Import Tint changes from Dawn
Changes:
- a187e9e281254475088161ca906a905282f5663e spirv-reader: Error for OpSpecConstantComposite expression by James Price <jrprice@google.com>
- b703afc061cb518b81664c2fdb7f23570edf8934 tint/utils: Support hetrogeneous hashmap key lookups by Ben Clayton <bclayton@google.com>
- 4204bb3ef11e2ea9d10a7a18f32a4ed69cf870a9 tint/writer/spirv: Fix build on MSVC / some clang builds by Ben Clayton <bclayton@google.com>
- 1dd578ad35a3be57ffe3ef59bf45c6664b5d1ada Revert "ir/spirv-writer: Emit entry point declarations" by Ben Clayton <bclayton@google.com>
- 146b67e0cdfae428a4787b0760b56649f49e9af6 tint/ir: Replace getter with raw fields for more classes by Ben Clayton <bclayton@google.com>
- 895d240fbf9ec44dfd8900fa13b0aa2dc6dea880 tint/ir: Replace Converter with FromProgram() free function by Ben Clayton <bclayton@google.com>
- 90789ea1f8f6aad42238dde3d75d39d8e07d0d60 ir/spirv-writer: Emit entry point declarations by James Price <jrprice@google.com>
- 436fffe2a13cb8c4074fdd09944bc8b72a873788 ir/spirv-writer: Emit function declarations by James Price <jrprice@google.com>
- c9734160bcf0509faf4f2a10296b8305fe1ba2a2 [ir] Add tests for compound operators. by dan sinclair <dsinclair@chromium.org>
- eae9902c815a31bc0bcd4c465111fdf622c54ebe [ir] Add store test by dan sinclair <dsinclair@chromium.org>
- 02b5b224e3d1591f9b9f7d53ec46779c90ecba7d ir/spirv-writer: Add support for scalar types by James Price <jrprice@google.com>
- b169165633d5023111db83c22acaf71588d73f19 [ir] Add tests for unary conversion. by dan sinclair <dsinclair@chromium.org>
- 63716c55cc4f6ea9872bf736a3d2b1e6d2a19d1f [ir] Spit builder_impl tests. by dan sinclair <dsinclair@chromium.org>
- 34f41c7bad4ab5fbe90d9f6ca6e987e8333d3b2c [ir] Change unary not to a binary equal by dan sinclair <dsinclair@chromium.org>
- e964f5163c9fe1cde50407c36aecde033079ce72 [ir] Update type display in disassembly, remove string me... by dan sinclair <dsinclair@chromium.org>
- b298b6a222e2dddea59e4b126734976395d1be44 ir/function: Add missing <array> include by James Price <jrprice@google.com>
- 29bff642fc0b1624350a78c673366934335a261b ir: Use std::optional::value_or to simplify code by Ben Clayton <bclayton@google.com>
- f789854a94287fafd0b08abb9b67fe6bca95287f tint: fix undetected overflow in const-eval refract by Antonio Maiorano <amaiorano@google.com>
- 8f9ea96c20734fb17d69576bfc4af7d7a224f466 tint/writer/spirv: Add path for generating from IR by James Price <jrprice@google.com>
- 057b7f326e6383944e5ade235f2ee70d7fb568cd tint/writer/spirv: Use Diagnostics() for errors by James Price <jrprice@google.com>
- cb8f3308a3e24388ee0e28ceb5a0b5bbeafdd24b spirv-reader: Error for OpUndef image argument by James Price <jrprice@google.com>
- f885a90a5feabbf75ead60f60200098ea80adb9f tint/writer/spirv: Create Module class by James Price <jrprice@google.com>
- 09b02ffc7bcb4b95f52315f1a11bfc833f69ec27 [ir] Split the Terminator into two nodes. by dan sinclair <dsinclair@chromium.org>
- 69bb5dd816781b7490c9a3cc6a5de1f186bc9f2f [ir] Add function return information. by dan sinclair <dsinclair@chromium.org>
- 9d9a38336e0571ce6fa6fccd2e7868fcc341c04a [ir] Add function attributes by dan sinclair <dsinclair@chromium.org>
- 4cadbc4daf9fea260feb80f570674a9f71d7d50a [ir] Handle IdentifierExpression by dan sinclair <dsinclair@chromium.org>
- 1545ca191bd5b4a9f31e10c9924e7cdbc395ea29 tint: Remove Program|ProgramBuilder::FriendlyName() by Ben Clayton <bclayton@google.com>
- 6ac51c1c572d0327e62c53f6eeac388279cf9aec [ir] Update binary and unary names. by dan sinclair <dsinclair@chromium.org>
- fa00fe9d417fbbbfcdae4390a85faedc9dc6dfb0 tint/hlsl+glsl: fix workgroupUniformLoad polyfills by Antonio Maiorano <amaiorano@google.com>
- e903396ff2c5d4c205bffc5c6b91cb48ebefd5f7 [ir] Emit short-circuit as an `If` node by dan sinclair <dsinclair@chromium.org>
GitOrigin-RevId: a187e9e281254475088161ca906a905282f5663e
Change-Id: Iab6728a5ca72ed77818aa6bb5095315ba47fa4a8
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/131680
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index c6affb1..8cf3daa 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -955,6 +955,8 @@
"writer/spirv/generator_impl.h",
"writer/spirv/instruction.cc",
"writer/spirv/instruction.h",
+ "writer/spirv/module.cc",
+ "writer/spirv/module.h",
"writer/spirv/operand.cc",
"writer/spirv/operand.h",
"writer/spirv/scalar_constant.h",
@@ -972,6 +974,17 @@
":libtint_utils_src",
":libtint_writer_src",
]
+
+ if (tint_build_ir) {
+ sources += [
+ "writer/spirv/generator_impl_ir.cc",
+ "writer/spirv/generator_impl_ir.h",
+ ]
+ deps += [
+ ":libtint_ir_builder_src",
+ ":libtint_ir_src",
+ ]
+ }
}
libtint_source_set("libtint_wgsl_reader_src") {
@@ -1109,8 +1122,8 @@
sources = [
"ir/builder_impl.cc",
"ir/builder_impl.h",
- "ir/converter.cc",
- "ir/converter.h",
+ "ir/from_program.cc",
+ "ir/from_program.h",
]
deps = [
":libtint_ast_src",
@@ -1118,6 +1131,7 @@
":libtint_ir_src",
":libtint_program_src",
":libtint_sem_src",
+ ":libtint_symbols_src",
":libtint_type_src",
":libtint_utils_src",
]
@@ -1153,6 +1167,8 @@
"ir/flow_node.h",
"ir/function.cc",
"ir/function.h",
+ "ir/function_terminator.cc",
+ "ir/function_terminator.h",
"ir/if.cc",
"ir/if.h",
"ir/instruction.cc",
@@ -1161,12 +1177,12 @@
"ir/loop.h",
"ir/module.cc",
"ir/module.h",
+ "ir/root_terminator.cc",
+ "ir/root_terminator.h",
"ir/store.cc",
"ir/store.h",
"ir/switch.cc",
"ir/switch.h",
- "ir/terminator.cc",
- "ir/terminator.h",
"ir/unary.cc",
"ir/unary.h",
"ir/user_call.cc",
@@ -1825,6 +1841,7 @@
"writer/spirv/builder_type_test.cc",
"writer/spirv/builder_unary_op_expression_test.cc",
"writer/spirv/instruction_test.cc",
+ "writer/spirv/module_test.cc",
"writer/spirv/operand_test.cc",
"writer/spirv/scalar_constant_test.cc",
"writer/spirv/spv_dump.cc",
@@ -1839,6 +1856,15 @@
":tint_unittests_ast_src",
"${tint_spirv_tools_dir}/:spvtools",
]
+
+ if (tint_build_ir) {
+ sources += [
+ "writer/spirv/generator_impl_function_test.cc",
+ "writer/spirv/generator_impl_ir_test.cc",
+ "writer/spirv/generator_impl_type_test.cc",
+ ]
+ deps += [ ":libtint_ir_src" ]
+ }
}
tint_unittests_source_set("tint_unittests_wgsl_reader_src") {
@@ -2120,7 +2146,14 @@
sources = [
"ir/binary_test.cc",
"ir/bitcast_test.cc",
+ "ir/builder_impl_binary_test.cc",
+ "ir/builder_impl_call_test.cc",
+ "ir/builder_impl_literal_test.cc",
+ "ir/builder_impl_materialize_test.cc",
+ "ir/builder_impl_store_test.cc",
"ir/builder_impl_test.cc",
+ "ir/builder_impl_unary_test.cc",
+ "ir/builder_impl_var_test.cc",
"ir/constant_test.cc",
"ir/discard_test.cc",
"ir/store_test.cc",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 2e1ded8..f47d2ce 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -644,10 +644,19 @@
writer/spirv/generator_impl.h
writer/spirv/instruction.cc
writer/spirv/instruction.h
+ writer/spirv/module.cc
+ writer/spirv/module.h
writer/spirv/operand.cc
writer/spirv/operand.h
writer/spirv/scalar_constant.h
)
+
+ if(${TINT_BUILD_IR})
+ list(APPEND TINT_LIB_SRCS
+ writer/spirv/generator_impl_ir.cc
+ writer/spirv/generator_impl_ir.h
+ )
+ endif()
endif()
if(${TINT_BUILD_WGSL_WRITER})
@@ -718,18 +727,20 @@
ir/construct.h
ir/convert.cc
ir/convert.h
- ir/converter.cc
- ir/converter.h
ir/debug.cc
ir/debug.h
ir/disassembler.cc
ir/disassembler.h
ir/discard.cc
ir/discard.h
+ ir/from_program.cc
+ ir/from_program.h
ir/flow_node.cc
ir/flow_node.h
ir/function.cc
ir/function.h
+ ir/function_terminator.cc
+ ir/function_terminator.h
ir/if.cc
ir/if.h
ir/instruction.cc
@@ -738,12 +749,12 @@
ir/loop.h
ir/module.cc
ir/module.h
+ ir/root_terminator.cc
+ ir/root_terminator.h
ir/store.cc
ir/store.h
ir/switch.cc
ir/switch.h
- ir/terminator.cc
- ir/terminator.h
ir/unary.cc
ir/unary.h
ir/user_call.cc
@@ -1206,12 +1217,22 @@
writer/spirv/builder_type_test.cc
writer/spirv/builder_unary_op_expression_test.cc
writer/spirv/instruction_test.cc
+ writer/spirv/module_test.cc
writer/spirv/operand_test.cc
writer/spirv/scalar_constant_test.cc
writer/spirv/spv_dump.cc
writer/spirv/spv_dump.h
writer/spirv/test_helper.h
)
+
+ if(${TINT_BUILD_IR})
+ list(APPEND TINT_TEST_SRCS
+ writer/spirv/generator_impl_function_test.cc
+ writer/spirv/generator_impl_ir_test.cc
+ writer/spirv/generator_impl_type_test.cc
+ writer/spirv/test_helper_ir.h
+ )
+ endif()
endif()
if(${TINT_BUILD_WGSL_WRITER})
@@ -1422,7 +1443,14 @@
list(APPEND TINT_TEST_SRCS
ir/binary_test.cc
ir/bitcast_test.cc
+ ir/builder_impl_binary_test.cc
+ ir/builder_impl_call_test.cc
+ ir/builder_impl_literal_test.cc
+ ir/builder_impl_materialize_test.cc
+ ir/builder_impl_store_test.cc
ir/builder_impl_test.cc
+ ir/builder_impl_unary_test.cc
+ ir/builder_impl_var_test.cc
ir/constant_test.cc
ir/discard_test.cc
ir/store_test.cc
diff --git a/src/tint/cmd/loopy.cc b/src/tint/cmd/loopy.cc
index 75102eb..34ded9d 100644
--- a/src/tint/cmd/loopy.cc
+++ b/src/tint/cmd/loopy.cc
@@ -19,7 +19,7 @@
#include "tint/tint.h"
#if TINT_BUILD_IR
-#include "src/tint/ir/converter.h"
+#include "src/tint/ir/from_program.h"
#include "src/tint/ir/module.h"
#endif // TINT_BUILD_IR
@@ -378,7 +378,7 @@
loop_count = options.loop_count;
}
for (uint32_t i = 0; i < loop_count; ++i) {
- auto result = tint::ir::Converter::FromProgram(program.get());
+ auto result = tint::ir::FromProgram(program.get());
if (!result) {
std::cerr << "Failed to build IR from program: " << result.Failure() << std::endl;
}
diff --git a/src/tint/cmd/main.cc b/src/tint/cmd/main.cc
index c8260f1..76a9256 100644
--- a/src/tint/cmd/main.cc
+++ b/src/tint/cmd/main.cc
@@ -49,9 +49,9 @@
#include "tint/tint.h"
#if TINT_BUILD_IR
-#include "src/tint/ir/converter.h" // nogncheck
#include "src/tint/ir/debug.h" // nogncheck
#include "src/tint/ir/disassembler.h" // nogncheck
+#include "src/tint/ir/from_program.h" // nogncheck
#include "src/tint/ir/module.h" // nogncheck
#endif // TINT_BUILD_IR
@@ -111,6 +111,7 @@
#if TINT_BUILD_IR
bool dump_ir = false;
bool dump_ir_graph = false;
+ bool use_ir = false;
#endif // TINT_BUILD_IR
#if TINT_BUILD_SYNTAX_TREE_WRITER
@@ -388,6 +389,8 @@
opts->dump_ir = true;
} else if (arg == "--dump-ir-graph") {
opts->dump_ir_graph = true;
+ } else if (arg == "--use-ir") {
+ opts->use_ir = true;
#endif // TINT_BUILD_IR
#if TINT_BUILD_SYNTAX_TREE_WRITER
} else if (arg == "--dump-ast") {
@@ -548,6 +551,9 @@
gen_options.disable_workgroup_init = options.disable_workgroup_init;
gen_options.external_texture_options.bindings_map =
tint::cmd::GenerateExternalTextureBindings(program);
+#if TINT_BUILD_IR
+ gen_options.use_tint_ir = options.use_ir;
+#endif
auto result = tint::writer::spirv::Generate(program, gen_options);
if (!result.success) {
tint::cmd::PrintWGSL(std::cerr, *program);
@@ -1023,7 +1029,8 @@
#if TINT_BUILD_IR
usage +=
" --dump-ir -- Writes the IR to stdout\n"
- " --dump-ir-graph -- Writes the IR graph to 'tint.dot' as a dot graph\n";
+ " --dump-ir-graph -- Writes the IR graph to 'tint.dot' as a dot graph\n"
+ " --use-ir -- Use the IR for writers and transforms when possible\n";
#endif // TINT_BUILD_IR
#if TINT_BUILD_SYNTAX_TREE_WRITER
usage += " --dump-ast -- Writes the AST to stdout\n";
@@ -1079,7 +1086,7 @@
#if TINT_BUILD_IR
if (options.dump_ir || options.dump_ir_graph) {
- auto result = tint::ir::Converter::FromProgram(program.get());
+ auto result = tint::ir::FromProgram(program.get());
if (!result) {
std::cerr << "Failed to build IR from program: " << result.Failure() << std::endl;
} else {
diff --git a/src/tint/ir/binary.cc b/src/tint/ir/binary.cc
index d3e3548..a6a6aa7 100644
--- a/src/tint/ir/binary.cc
+++ b/src/tint/ir/binary.cc
@@ -19,8 +19,8 @@
namespace tint::ir {
-Binary::Binary(uint32_t id, Kind kind, const type::Type* ty, Value* lhs, Value* rhs)
- : Base(id, ty), kind_(kind), lhs_(lhs), rhs_(rhs) {
+Binary::Binary(uint32_t identifier, Kind kind, const type::Type* ty, Value* lhs, Value* rhs)
+ : Base(identifier, ty), kind_(kind), lhs_(lhs), rhs_(rhs) {
TINT_ASSERT(IR, lhs_);
TINT_ASSERT(IR, rhs_);
lhs_->AddUsage(this);
@@ -29,69 +29,4 @@
Binary::~Binary() = default;
-utils::StringStream& Binary::ToInstruction(utils::StringStream& out) const {
- ToValue(out) << " = ";
-
- switch (GetKind()) {
- case Binary::Kind::kAdd:
- out << "add";
- break;
- case Binary::Kind::kSubtract:
- out << "sub";
- break;
- case Binary::Kind::kMultiply:
- out << "mul";
- break;
- case Binary::Kind::kDivide:
- out << "div";
- break;
- case Binary::Kind::kModulo:
- out << "mod";
- break;
- case Binary::Kind::kAnd:
- out << "bit_and";
- break;
- case Binary::Kind::kOr:
- out << "bit_or";
- break;
- case Binary::Kind::kXor:
- out << "bit_xor";
- break;
- case Binary::Kind::kLogicalAnd:
- out << "log_and";
- break;
- case Binary::Kind::kLogicalOr:
- out << "log_or";
- break;
- case Binary::Kind::kEqual:
- out << "eq";
- break;
- case Binary::Kind::kNotEqual:
- out << "neq";
- break;
- case Binary::Kind::kLessThan:
- out << "lt";
- break;
- case Binary::Kind::kGreaterThan:
- out << "gt";
- break;
- case Binary::Kind::kLessThanEqual:
- out << "lte";
- break;
- case Binary::Kind::kGreaterThanEqual:
- out << "gte";
- break;
- case Binary::Kind::kShiftLeft:
- out << "shiftl";
- break;
- case Binary::Kind::kShiftRight:
- out << "shiftr";
- break;
- }
- out << " ";
- lhs_->ToValue(out) << ", ";
- rhs_->ToValue(out);
- return out;
-}
-
} // namespace tint::ir
diff --git a/src/tint/ir/binary.h b/src/tint/ir/binary.h
index 92a1998..c686797 100644
--- a/src/tint/ir/binary.h
+++ b/src/tint/ir/binary.h
@@ -17,7 +17,6 @@
#include "src/tint/ir/instruction.h"
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
@@ -36,9 +35,6 @@
kOr,
kXor,
- kLogicalAnd,
- kLogicalOr,
-
kEqual,
kNotEqual,
kLessThan,
@@ -73,11 +69,6 @@
/// @returns the right-hand-side value for the instruction
const Value* RHS() const { return rhs_; }
- /// Write the instruction to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- utils::StringStream& ToInstruction(utils::StringStream& out) const override;
-
private:
Kind kind_;
Value* lhs_ = nullptr;
diff --git a/src/tint/ir/binary_test.cc b/src/tint/ir/binary_test.cc
index e03a61d..6a96633 100644
--- a/src/tint/ir/binary_test.cc
+++ b/src/tint/ir/binary_test.cc
@@ -14,7 +14,6 @@
#include "src/tint/ir/instruction.h"
#include "src/tint/ir/test_helper.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
namespace {
@@ -42,10 +41,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = bit_and 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateOr) {
@@ -66,10 +61,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = bit_or 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateXor) {
@@ -90,58 +81,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = bit_xor 4i, 2i");
-}
-
-TEST_F(IR_InstructionTest, CreateLogicalAnd) {
- auto& b = CreateEmptyBuilder();
-
- const auto* inst = b.builder.LogicalAnd(b.builder.ir.types.Get<type::Bool>(),
- b.builder.Constant(4_i), b.builder.Constant(2_i));
-
- ASSERT_TRUE(inst->Is<Binary>());
- EXPECT_EQ(inst->GetKind(), Binary::Kind::kLogicalAnd);
-
- ASSERT_TRUE(inst->LHS()->Is<Constant>());
- auto lhs = inst->LHS()->As<Constant>()->value;
- ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
- EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- ASSERT_TRUE(inst->RHS()->Is<Constant>());
- auto rhs = inst->RHS()->As<Constant>()->value;
- ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
- EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(bool) = log_and 4i, 2i");
-}
-
-TEST_F(IR_InstructionTest, CreateLogicalOr) {
- auto& b = CreateEmptyBuilder();
-
- const auto* inst = b.builder.LogicalOr(b.builder.ir.types.Get<type::Bool>(),
- b.builder.Constant(4_i), b.builder.Constant(2_i));
-
- ASSERT_TRUE(inst->Is<Binary>());
- EXPECT_EQ(inst->GetKind(), Binary::Kind::kLogicalOr);
-
- ASSERT_TRUE(inst->LHS()->Is<Constant>());
- auto lhs = inst->LHS()->As<Constant>()->value;
- ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
- EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- ASSERT_TRUE(inst->RHS()->Is<Constant>());
- auto rhs = inst->RHS()->As<Constant>()->value;
- ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
- EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(bool) = log_or 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateEqual) {
@@ -162,10 +101,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(bool) = eq 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateNotEqual) {
@@ -186,10 +121,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(bool) = neq 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateLessThan) {
@@ -210,10 +141,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(bool) = lt 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateGreaterThan) {
@@ -234,10 +161,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(bool) = gt 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateLessThanEqual) {
@@ -258,10 +181,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(bool) = lte 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
@@ -282,10 +201,25 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
+}
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(bool) = gte 4i, 2i");
+TEST_F(IR_InstructionTest, CreateNot) {
+ auto& b = CreateEmptyBuilder();
+ const auto* inst =
+ b.builder.Not(b.builder.ir.types.Get<type::Bool>(), b.builder.Constant(true));
+
+ ASSERT_TRUE(inst->Is<Binary>());
+ EXPECT_EQ(inst->GetKind(), Binary::Kind::kEqual);
+
+ ASSERT_TRUE(inst->LHS()->Is<Constant>());
+ auto lhs = inst->LHS()->As<Constant>()->value;
+ ASSERT_TRUE(lhs->Is<constant::Scalar<bool>>());
+ EXPECT_TRUE(lhs->As<constant::Scalar<bool>>()->ValueAs<bool>());
+
+ ASSERT_TRUE(inst->RHS()->Is<Constant>());
+ auto rhs = inst->RHS()->As<Constant>()->value;
+ ASSERT_TRUE(rhs->Is<constant::Scalar<bool>>());
+ EXPECT_FALSE(rhs->As<constant::Scalar<bool>>()->ValueAs<bool>());
}
TEST_F(IR_InstructionTest, CreateShiftLeft) {
@@ -306,10 +240,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = shiftl 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateShiftRight) {
@@ -330,10 +260,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = shiftr 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateAdd) {
@@ -354,10 +280,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = add 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateSubtract) {
@@ -378,10 +300,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = sub 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateMultiply) {
@@ -402,10 +320,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = mul 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateDivide) {
@@ -426,10 +340,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = div 4i, 2i");
}
TEST_F(IR_InstructionTest, CreateModulo) {
@@ -450,10 +360,6 @@
auto rhs = inst->RHS()->As<Constant>()->value;
ASSERT_TRUE(rhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(2_i, rhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = mod 4i, 2i");
}
TEST_F(IR_InstructionTest, Binary_Usage) {
diff --git a/src/tint/ir/bitcast.cc b/src/tint/ir/bitcast.cc
index 70f412c..89eedca 100644
--- a/src/tint/ir/bitcast.cc
+++ b/src/tint/ir/bitcast.cc
@@ -19,15 +19,9 @@
namespace tint::ir {
-Bitcast::Bitcast(uint32_t id, const type::Type* type, Value* val)
- : Base(id, type, utils::Vector{val}) {}
+Bitcast::Bitcast(uint32_t identifier, const type::Type* ty, Value* val)
+ : Base(identifier, ty, utils::Vector{val}) {}
Bitcast::~Bitcast() = default;
-utils::StringStream& Bitcast::ToInstruction(utils::StringStream& out) const {
- ToValue(out) << " = bitcast ";
- EmitArgs(out);
- return out;
-}
-
} // namespace tint::ir
diff --git a/src/tint/ir/bitcast.h b/src/tint/ir/bitcast.h
index 253ea0b..0443701 100644
--- a/src/tint/ir/bitcast.h
+++ b/src/tint/ir/bitcast.h
@@ -17,7 +17,6 @@
#include "src/tint/ir/call.h"
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
@@ -35,11 +34,6 @@
Bitcast& operator=(const Bitcast& inst) = delete;
Bitcast& operator=(Bitcast&& inst) = delete;
-
- /// Write the instruction to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- utils::StringStream& ToInstruction(utils::StringStream& out) const override;
};
} // namespace tint::ir
diff --git a/src/tint/ir/bitcast_test.cc b/src/tint/ir/bitcast_test.cc
index a70fb92..dfe7461 100644
--- a/src/tint/ir/bitcast_test.cc
+++ b/src/tint/ir/bitcast_test.cc
@@ -14,7 +14,6 @@
#include "src/tint/ir/instruction.h"
#include "src/tint/ir/test_helper.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
namespace {
@@ -31,15 +30,11 @@
ASSERT_TRUE(inst->Is<ir::Bitcast>());
ASSERT_NE(inst->Type(), nullptr);
- ASSERT_EQ(inst->Args().Length(), 1u);
- ASSERT_TRUE(inst->Args()[0]->Is<Constant>());
- auto val = inst->Args()[0]->As<Constant>()->value;
+ ASSERT_EQ(inst->args.Length(), 1u);
+ ASSERT_TRUE(inst->args[0]->Is<Constant>());
+ auto val = inst->args[0]->As<Constant>()->value;
ASSERT_TRUE(val->Is<constant::Scalar<i32>>());
EXPECT_EQ(4_i, val->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = bitcast 4i");
}
TEST_F(IR_InstructionTest, Bitcast_Usage) {
@@ -47,10 +42,10 @@
const auto* inst =
b.builder.Bitcast(b.builder.ir.types.Get<type::I32>(), b.builder.Constant(4_i));
- ASSERT_EQ(inst->Args().Length(), 1u);
- ASSERT_NE(inst->Args()[0], nullptr);
- ASSERT_EQ(inst->Args()[0]->Usage().Length(), 1u);
- EXPECT_EQ(inst->Args()[0]->Usage()[0], inst);
+ ASSERT_EQ(inst->args.Length(), 1u);
+ ASSERT_NE(inst->args[0], nullptr);
+ ASSERT_EQ(inst->args[0]->Usage().Length(), 1u);
+ EXPECT_EQ(inst->args[0]->Usage()[0], inst);
}
} // namespace
diff --git a/src/tint/ir/branch.h b/src/tint/ir/branch.h
index 4fc8d7c..667f131 100644
--- a/src/tint/ir/branch.h
+++ b/src/tint/ir/branch.h
@@ -26,7 +26,7 @@
FlowNode* target = nullptr;
/// The arguments provided for that branch. These arguments could be the
- /// return value in the case of a branch to the terminator, or they could
+ /// return value in the case of a branch to the function terminator, or they could
/// be the basic block arguments passed into the block.
utils::Vector<Value*, 2> args;
};
diff --git a/src/tint/ir/builder.cc b/src/tint/ir/builder.cc
index 2c97737..e826be4 100644
--- a/src/tint/ir/builder.cc
+++ b/src/tint/ir/builder.cc
@@ -16,6 +16,8 @@
#include <utility>
+#include "src/tint/constant/scalar.h"
+
namespace tint::ir {
Builder::Builder() {}
@@ -29,8 +31,8 @@
ir.root_block = CreateBlock();
// Everything in the module scope must have been const-eval's, so everything will go into a
- // single block. So, we can create the terminator for the root-block now.
- ir.root_block->branch.target = CreateTerminator();
+ // single block. So, we can create the root terminator for the root-block now.
+ ir.root_block->branch.target = CreateRootTerminator();
}
return ir.root_block;
}
@@ -39,14 +41,18 @@
return ir.flow_nodes.Create<Block>();
}
-Terminator* Builder::CreateTerminator() {
- return ir.flow_nodes.Create<Terminator>();
+RootTerminator* Builder::CreateRootTerminator() {
+ return ir.flow_nodes.Create<RootTerminator>();
+}
+
+FunctionTerminator* Builder::CreateFunctionTerminator() {
+ return ir.flow_nodes.Create<FunctionTerminator>();
}
Function* Builder::CreateFunction() {
auto* ir_func = ir.flow_nodes.Create<Function>();
ir_func->start_target = CreateBlock();
- ir_func->end_target = CreateTerminator();
+ ir_func->end_target = CreateFunctionTerminator();
// Function is always branching into the start target
ir_func->start_target->inbound_branches.Push(ir_func);
@@ -118,14 +124,6 @@
return CreateBinary(Binary::Kind::kXor, type, lhs, rhs);
}
-Binary* Builder::LogicalAnd(const type::Type* type, Value* lhs, Value* rhs) {
- return CreateBinary(Binary::Kind::kLogicalAnd, type, lhs, rhs);
-}
-
-Binary* Builder::LogicalOr(const type::Type* type, Value* lhs, Value* rhs) {
- return CreateBinary(Binary::Kind::kLogicalOr, type, lhs, rhs);
-}
-
Binary* Builder::Equal(const type::Type* type, Value* lhs, Value* rhs) {
return CreateBinary(Binary::Kind::kEqual, type, lhs, rhs);
}
@@ -198,8 +196,8 @@
return CreateUnary(Unary::Kind::kNegation, type, val);
}
-Unary* Builder::Not(const type::Type* type, Value* val) {
- return CreateUnary(Unary::Kind::kNot, type, val);
+Binary* Builder::Not(const type::Type* type, Value* val) {
+ return Equal(type, val, Constant(create<constant::Scalar<bool>>(type, false)));
}
ir::Bitcast* Builder::Bitcast(const type::Type* type, Value* val) {
diff --git a/src/tint/ir/builder.h b/src/tint/ir/builder.h
index d509c06..ff01e2d 100644
--- a/src/tint/ir/builder.h
+++ b/src/tint/ir/builder.h
@@ -26,12 +26,13 @@
#include "src/tint/ir/convert.h"
#include "src/tint/ir/discard.h"
#include "src/tint/ir/function.h"
+#include "src/tint/ir/function_terminator.h"
#include "src/tint/ir/if.h"
#include "src/tint/ir/loop.h"
#include "src/tint/ir/module.h"
+#include "src/tint/ir/root_terminator.h"
#include "src/tint/ir/store.h"
#include "src/tint/ir/switch.h"
-#include "src/tint/ir/terminator.h"
#include "src/tint/ir/unary.h"
#include "src/tint/ir/user_call.h"
#include "src/tint/ir/value.h"
@@ -59,8 +60,11 @@
/// @returns a new block flow node
Block* CreateBlock();
- /// @returns a new terminator flow node
- Terminator* CreateTerminator();
+ /// @returns a new root terminator flow node
+ RootTerminator* CreateRootTerminator();
+
+ /// @returns a new function terminator flow node
+ FunctionTerminator* CreateFunctionTerminator();
/// Creates a function flow node
/// @returns the flow node
@@ -170,20 +174,6 @@
/// @returns the operation
Binary* Xor(const type::Type* type, Value* lhs, Value* rhs);
- /// Creates an LogicalAnd operation
- /// @param type the result type of the expression
- /// @param lhs the lhs of the add
- /// @param rhs the rhs of the add
- /// @returns the operation
- Binary* LogicalAnd(const type::Type* type, Value* lhs, Value* rhs);
-
- /// Creates an LogicalOr operation
- /// @param type the result type of the expression
- /// @param lhs the lhs of the add
- /// @param rhs the rhs of the add
- /// @returns the operation
- Binary* LogicalOr(const type::Type* type, Value* lhs, Value* rhs);
-
/// Creates an Equal operation
/// @param type the result type of the expression
/// @param lhs the lhs of the add
@@ -310,7 +300,7 @@
/// @param type the result type of the expression
/// @param val the value
/// @returns the operation
- Unary* Not(const type::Type* type, Value* val);
+ Binary* Not(const type::Type* type, Value* val);
/// Creates a bitcast instruction
/// @param type the result type of the bitcast
diff --git a/src/tint/ir/builder_impl.cc b/src/tint/ir/builder_impl.cc
index 19caf6f..ef4a94e 100644
--- a/src/tint/ir/builder_impl.cc
+++ b/src/tint/ir/builder_impl.cc
@@ -39,6 +39,7 @@
#include "src/tint/ast/identifier_expression.h"
#include "src/tint/ast/if_statement.h"
#include "src/tint/ast/int_literal_expression.h"
+#include "src/tint/ast/invariant_attribute.h"
#include "src/tint/ast/let.h"
#include "src/tint/ast/literal_expression.h"
#include "src/tint/ast/loop_statement.h"
@@ -60,11 +61,11 @@
#include "src/tint/ir/module.h"
#include "src/tint/ir/store.h"
#include "src/tint/ir/switch.h"
-#include "src/tint/ir/terminator.h"
#include "src/tint/ir/value.h"
#include "src/tint/program.h"
#include "src/tint/sem/builtin.h"
#include "src/tint/sem/call.h"
+#include "src/tint/sem/function.h"
#include "src/tint/sem/materialize.h"
#include "src/tint/sem/module.h"
#include "src/tint/sem/switch_statement.h"
@@ -74,6 +75,7 @@
#include "src/tint/sem/variable.h"
#include "src/tint/switch.h"
#include "src/tint/type/void.h"
+#include "src/tint/utils/defer.h"
#include "src/tint/utils/scoped_assignment.h"
namespace tint::ir {
@@ -209,19 +211,85 @@
ast_to_flow_[ast_func] = ir_func;
+ const auto* sem = program_->Sem().Get(ast_func);
if (ast_func->IsEntryPoint()) {
builder.ir.entry_points.Push(ir_func);
+
+ switch (ast_func->PipelineStage()) {
+ case ast::PipelineStage::kVertex:
+ ir_func->pipeline_stage = Function::PipelineStage::kVertex;
+ break;
+ case ast::PipelineStage::kFragment:
+ ir_func->pipeline_stage = Function::PipelineStage::kFragment;
+ break;
+ case ast::PipelineStage::kCompute: {
+ ir_func->pipeline_stage = Function::PipelineStage::kCompute;
+
+ auto wg_size = sem->WorkgroupSize();
+ ir_func->workgroup_size = {
+ wg_size[0].value(),
+ wg_size[1].value_or(1),
+ wg_size[2].value_or(1),
+ };
+ break;
+ }
+ default: {
+ TINT_ICE(IR, diagnostics_) << "Invalid pipeline stage";
+ return;
+ }
+ }
+
+ for (auto* attr : ast_func->return_type_attributes) {
+ tint::Switch(
+ attr, //
+ [&](const ast::LocationAttribute*) {
+ ir_func->return_attributes.Push(Function::ReturnAttribute::kLocation);
+ },
+ [&](const ast::InvariantAttribute*) {
+ ir_func->return_attributes.Push(Function::ReturnAttribute::kInvariant);
+ },
+ [&](const ast::BuiltinAttribute* b) {
+ if (auto* ident_sem =
+ program_->Sem()
+ .Get(b)
+ ->As<sem::BuiltinEnumExpression<builtin::BuiltinValue>>()) {
+ switch (ident_sem->Value()) {
+ case builtin::BuiltinValue::kPosition:
+ ir_func->return_attributes.Push(
+ Function::ReturnAttribute::kPosition);
+ break;
+ case builtin::BuiltinValue::kFragDepth:
+ ir_func->return_attributes.Push(
+ Function::ReturnAttribute::kFragDepth);
+ break;
+ case builtin::BuiltinValue::kSampleMask:
+ ir_func->return_attributes.Push(
+ Function::ReturnAttribute::kSampleMask);
+ break;
+ default:
+ TINT_ICE(IR, diagnostics_)
+ << "Unknown builtin value in return attributes "
+ << ident_sem->Value();
+ return;
+ }
+ } else {
+ TINT_ICE(IR, diagnostics_) << "Builtin attribute sem invalid";
+ return;
+ }
+ });
+ }
}
+ ir_func->return_type = sem->ReturnType()->Clone(clone_ctx_.type_ctx);
+ ir_func->return_location = sem->ReturnLocation();
{
FlowStackScope scope(this, ir_func);
current_flow_block = ir_func->start_target;
- EmitStatements(ast_func->body->statements);
+ EmitBlock(ast_func->body);
// TODO(dsinclair): Store return type and attributes
// TODO(dsinclair): Store parameters
- // TODO(dsinclair): Store attributes
// If the branch target has already been set then a `return` was called. Only set in the
// case where `return` wasn't called.
@@ -309,30 +377,6 @@
case ast::BinaryOp::kXor:
inst = builder.Xor(ty, lhs.Get(), rhs.Get());
break;
- case ast::BinaryOp::kLogicalAnd:
- inst = builder.LogicalAnd(ty, lhs.Get(), rhs.Get());
- break;
- case ast::BinaryOp::kLogicalOr:
- inst = builder.LogicalOr(ty, lhs.Get(), rhs.Get());
- break;
- case ast::BinaryOp::kEqual:
- inst = builder.Equal(ty, lhs.Get(), rhs.Get());
- break;
- case ast::BinaryOp::kNotEqual:
- inst = builder.NotEqual(ty, lhs.Get(), rhs.Get());
- break;
- case ast::BinaryOp::kLessThan:
- inst = builder.LessThan(ty, lhs.Get(), rhs.Get());
- break;
- case ast::BinaryOp::kGreaterThan:
- inst = builder.GreaterThan(ty, lhs.Get(), rhs.Get());
- break;
- case ast::BinaryOp::kLessThanEqual:
- inst = builder.LessThanEqual(ty, lhs.Get(), rhs.Get());
- break;
- case ast::BinaryOp::kGreaterThanEqual:
- inst = builder.GreaterThanEqual(ty, lhs.Get(), rhs.Get());
- break;
case ast::BinaryOp::kShiftLeft:
inst = builder.ShiftLeft(ty, lhs.Get(), rhs.Get());
break;
@@ -354,6 +398,16 @@
case ast::BinaryOp::kModulo:
inst = builder.Modulo(ty, lhs.Get(), rhs.Get());
break;
+ case ast::BinaryOp::kLessThanEqual:
+ case ast::BinaryOp::kGreaterThanEqual:
+ case ast::BinaryOp::kGreaterThan:
+ case ast::BinaryOp::kLessThan:
+ case ast::BinaryOp::kNotEqual:
+ case ast::BinaryOp::kEqual:
+ case ast::BinaryOp::kLogicalAnd:
+ case ast::BinaryOp::kLogicalOr:
+ TINT_ICE(IR, diagnostics_) << "invalid compound assignment";
+ return;
case ast::BinaryOp::kNone:
TINT_ICE(IR, diagnostics_) << "missing binary operand type";
return;
@@ -365,9 +419,12 @@
}
void BuilderImpl::EmitBlock(const ast::BlockStatement* block) {
- // Note, this doesn't need to emit a Block as the current block flow node should be
- // sufficient as the blocks all get flattened. Each flow control node will inject the basic
- // blocks it requires.
+ scopes_.Push();
+ TINT_DEFER(scopes_.Pop());
+
+ // Note, this doesn't need to emit a Block as the current block flow node should be sufficient
+ // as the blocks all get flattened. Each flow control node will inject the basic blocks it
+ // requires.
EmitStatements(block->statements);
}
@@ -389,7 +446,7 @@
FlowStackScope scope(this, if_node);
current_flow_block = if_node->true_.target->As<Block>();
- EmitStatement(stmt->body);
+ EmitBlock(stmt->body);
// If the true branch did not execute control flow, then go to the merge target
BranchToIfNeeded(if_node->merge.target);
@@ -404,9 +461,8 @@
}
current_flow_block = nullptr;
- // If both branches went somewhere, then they both returned, continued or broke. So,
- // there is no need for the if merge-block and there is nothing to branch to the merge
- // block anyway.
+ // If both branches went somewhere, then they both returned, continued or broke. So, there is no
+ // need for the if merge-block and there is nothing to branch to the merge block anyway.
if (IsConnected(if_node->merge.target)) {
current_flow_block = if_node->merge.target->As<Block>();
}
@@ -423,22 +479,22 @@
FlowStackScope scope(this, loop_node);
current_flow_block = loop_node->start.target->As<Block>();
- EmitStatement(stmt->body);
+ EmitBlock(stmt->body);
// The current block didn't `break`, `return` or `continue`, go to the continuing block.
BranchToIfNeeded(loop_node->continuing.target);
current_flow_block = loop_node->continuing.target->As<Block>();
if (stmt->continuing) {
- EmitStatement(stmt->continuing);
+ EmitBlock(stmt->continuing);
}
// Branch back to the start node if the continue target didn't branch out already
BranchToIfNeeded(loop_node->start.target);
}
- // The loop merge can get disconnected if the loop returns directly, or the continuing
- // target branches, eventually, to the merge, but nothing branched to the continuing target.
+ // The loop merge can get disconnected if the loop returns directly, or the continuing target
+ // branches, eventually, to the merge, but nothing branched to the continuing target.
current_flow_block = loop_node->merge.target->As<Block>();
if (!IsConnected(loop_node->merge.target)) {
current_flow_block = nullptr;
@@ -479,7 +535,7 @@
BranchTo(if_node);
current_flow_block = if_node->merge.target->As<Block>();
- EmitStatement(stmt->body);
+ EmitBlock(stmt->body);
BranchToIfNeeded(loop_node->continuing.target);
}
@@ -494,6 +550,10 @@
builder.Branch(loop_node->continuing.target->As<Block>(), loop_node->start.target,
utils::Empty);
+ // Make sure the initializer ends up in a contained scope
+ scopes_.Push();
+ TINT_DEFER(scopes_.Pop());
+
if (stmt->initializer) {
// Emit the for initializer before branching to the loop
EmitStatement(stmt->initializer);
@@ -529,7 +589,7 @@
current_flow_block = if_node->merge.target->As<Block>();
}
- EmitStatement(stmt->body);
+ EmitBlock(stmt->body);
BranchToIfNeeded(loop_node->continuing.target);
if (stmt->continuing) {
@@ -537,6 +597,7 @@
EmitStatement(stmt->continuing);
}
}
+
// The while loop always has a path to the merge target as the break statement comes before
// anything inside the loop.
current_flow_block = loop_node->merge.target->As<Block>();
@@ -571,7 +632,8 @@
}
current_flow_block = builder.CreateCase(switch_node, selectors);
- EmitStatement(c->Body()->Declaration());
+ EmitBlock(c->Body()->Declaration());
+
BranchToIfNeeded(switch_node->merge.target);
}
}
@@ -620,9 +682,9 @@
}
// Discard is being treated as an instruction. The semantics in WGSL is demote_to_helper, so the
-// code has to continue as before it just predicates writes. If WGSL grows some kind of
-// terminating discard that would probably make sense as a FlowNode but would then require
-// figuring out the multi-level exit that is triggered.
+// code has to continue as before it just predicates writes. If WGSL grows some kind of terminating
+// discard that would probably make sense as a FlowNode but would then require figuring out the
+// multi-level exit that is triggered.
void BuilderImpl::EmitDiscard(const ast::DiscardStatement*) {
auto* inst = builder.Discard();
current_flow_block->instructions.Push(inst);
@@ -679,9 +741,10 @@
[&](const ast::BinaryExpression* b) { return EmitBinary(b); },
[&](const ast::BitcastExpression* b) { return EmitBitcast(b); },
[&](const ast::CallExpression* c) { return EmitCall(c); },
- // [&](const ast::IdentifierExpression* i) {
- // TODO(dsinclair): Implement
- // },
+ [&](const ast::IdentifierExpression* i) {
+ auto* v = scopes_.Get(i->identifier->symbol);
+ return utils::Result<Value*>{v};
+ },
[&](const ast::LiteralExpression* l) { return EmitLiteral(l); },
// [&](const ast::MemberAccessorExpression* m) {
// TODO(dsinclair): Implement
@@ -716,7 +779,8 @@
auto* store = builder.Store(val, init.Get());
current_flow_block->instructions.Push(store);
}
- // TODO(dsinclair): Store the mapping from the var name to the `Declare` value
+ // Store the declaration so we can get the instruction to store too
+ scopes_.Set(v->name->symbol, val);
},
[&](const ast::Let* l) {
// A `let` doesn't exist as a standalone item in the IR, it's just the result of the
@@ -725,7 +789,9 @@
if (!init) {
return;
}
- // TODO(dsinclair): Store the mapping from the let name to the `init` value
+
+ // Store the results of the initialization
+ scopes_.Set(l->name->symbol, init.Get());
},
[&](const ast::Override*) {
add_error(var->source,
@@ -738,8 +804,8 @@
// should never be used.
//
// TODO(dsinclair): Probably want to store the const variable somewhere and then in
- // identifier expression log an error if we ever see a const identifier. Add this
- // when identifiers and variables are supported.
+ // identifier expression log an error if we ever see a const identifier. Add this when
+ // identifiers and variables are supported.
},
[&](Default) {
add_error(var->source, "unknown variable: " + std::string(var->TypeInfo().name));
@@ -755,7 +821,7 @@
auto* sem = program_->Sem().Get(expr);
auto* ty = sem->Type()->Clone(clone_ctx_.type_ctx);
- Unary* inst = nullptr;
+ Instruction* inst = nullptr;
switch (expr->op) {
case ast::UnaryOp::kAddressOf:
inst = builder.AddressOf(ty, val.Get());
@@ -778,7 +844,68 @@
return inst;
}
+// A short-circut needs special treatment. The short-circuit is decomposed into the relevant if
+// statements and declarations.
+utils::Result<Value*> BuilderImpl::EmitShortCircuit(const ast::BinaryExpression* expr) {
+ switch (expr->op) {
+ case ast::BinaryOp::kLogicalAnd:
+ case ast::BinaryOp::kLogicalOr:
+ break;
+ default:
+ TINT_ICE(IR, diagnostics_) << "invalid operation type for short-circut decomposition";
+ return utils::Failure;
+ }
+
+ // Evaluate the LHS of the short-circuit
+ auto lhs = EmitExpression(expr->lhs);
+ if (!lhs) {
+ return utils::Failure;
+ }
+
+ // Generate a variable to store the short-circut into
+ auto* ty = builder.ir.types.Get<type::Bool>();
+ auto* result_var =
+ builder.Declare(ty, builtin::AddressSpace::kFunction, builtin::Access::kReadWrite);
+ current_flow_block->instructions.Push(result_var);
+
+ auto* lhs_store = builder.Store(result_var, lhs.Get());
+ current_flow_block->instructions.Push(lhs_store);
+
+ auto* if_node = builder.CreateIf();
+ if_node->condition = lhs.Get();
+ BranchTo(if_node);
+
+ utils::Result<Value*> rhs;
+ {
+ FlowStackScope scope(this, if_node);
+
+ // If this is an `&&` then we only evaluate the RHS expression in the true block.
+ // If this is an `||` then we only evaluate the RHS expression in the false block.
+ if (expr->op == ast::BinaryOp::kLogicalAnd) {
+ current_flow_block = if_node->true_.target->As<Block>();
+ } else {
+ current_flow_block = if_node->false_.target->As<Block>();
+ }
+
+ rhs = EmitExpression(expr->rhs);
+ if (!rhs) {
+ return utils::Failure;
+ }
+ auto* rhs_store = builder.Store(result_var, rhs.Get());
+ current_flow_block->instructions.Push(rhs_store);
+
+ BranchTo(if_node->merge.target);
+ }
+ current_flow_block = if_node->merge.target->As<Block>();
+
+ return result_var;
+}
+
utils::Result<Value*> BuilderImpl::EmitBinary(const ast::BinaryExpression* expr) {
+ if (expr->op == ast::BinaryOp::kLogicalAnd || expr->op == ast::BinaryOp::kLogicalOr) {
+ return EmitShortCircuit(expr);
+ }
+
auto lhs = EmitExpression(expr->lhs);
if (!lhs) {
return utils::Failure;
@@ -803,12 +930,6 @@
case ast::BinaryOp::kXor:
inst = builder.Xor(ty, lhs.Get(), rhs.Get());
break;
- case ast::BinaryOp::kLogicalAnd:
- inst = builder.LogicalAnd(ty, lhs.Get(), rhs.Get());
- break;
- case ast::BinaryOp::kLogicalOr:
- inst = builder.LogicalOr(ty, lhs.Get(), rhs.Get());
- break;
case ast::BinaryOp::kEqual:
inst = builder.Equal(ty, lhs.Get(), rhs.Get());
break;
@@ -848,6 +969,10 @@
case ast::BinaryOp::kModulo:
inst = builder.Modulo(ty, lhs.Get(), rhs.Get());
break;
+ case ast::BinaryOp::kLogicalAnd:
+ case ast::BinaryOp::kLogicalOr:
+ TINT_ICE(IR, diagnostics_) << "short circuit op should have already been handled";
+ return utils::Failure;
case ast::BinaryOp::kNone:
TINT_ICE(IR, diagnostics_) << "missing binary operand type";
return utils::Failure;
diff --git a/src/tint/ir/builder_impl.h b/src/tint/ir/builder_impl.h
index 7b18492..f6bed12 100644
--- a/src/tint/ir/builder_impl.h
+++ b/src/tint/ir/builder_impl.h
@@ -26,6 +26,7 @@
#include "src/tint/ir/flow_node.h"
#include "src/tint/ir/module.h"
#include "src/tint/ir/value.h"
+#include "src/tint/scope_stack.h"
#include "src/tint/utils/result.h"
// Forward Declarations
@@ -59,14 +60,6 @@
class WhileStatement;
class Variable;
} // namespace tint::ast
-namespace tint::ir {
-class Block;
-class If;
-class Function;
-class Loop;
-class Switch;
-class Terminator;
-} // namespace tint::ir
namespace tint::sem {
class Builtin;
} // namespace tint::sem
@@ -166,6 +159,11 @@
/// @returns the value storing the result if successful, utils::Failure otherwise
utils::Result<Value*> EmitUnary(const ast::UnaryOpExpression* expr);
+ /// Emits a short-circult binary expression
+ /// @param expr the binary expression
+ /// @returns the value storing the result if successful, utils::Failure otherwise
+ utils::Result<Value*> EmitShortCircuit(const ast::BinaryExpression* expr);
+
/// Emits a binary expression
/// @param expr the binary expression
/// @returns the value storing the result if successful, utils::Failure otherwise
@@ -227,19 +225,17 @@
void add_error(const Source& s, const std::string& err);
- const Program* program_ = nullptr;
-
Symbol CloneSymbol(Symbol sym) const;
- diag::List diagnostics_;
-
+ const Program* program_ = nullptr;
Function* current_function_ = nullptr;
+ ScopeStack<Symbol, Value*> scopes_;
+ constant::CloneContext clone_ctx_;
+ diag::List diagnostics_;
/// Map from ast nodes to flow nodes, used to retrieve the flow node for a given AST node.
/// Used for testing purposes.
std::unordered_map<const ast::Node*, const FlowNode*> ast_to_flow_;
-
- constant::CloneContext clone_ctx_;
};
} // namespace tint::ir
diff --git a/src/tint/ir/builder_impl_binary_test.cc b/src/tint/ir/builder_impl_binary_test.cc
new file mode 100644
index 0000000..a9a8978
--- /dev/null
+++ b/src/tint/ir/builder_impl_binary_test.cc
@@ -0,0 +1,696 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/ir/test_helper.h"
+
+#include "gmock/gmock.h"
+#include "src/tint/ast/case_selector.h"
+#include "src/tint/ast/int_literal_expression.h"
+#include "src/tint/constant/scalar.h"
+
+namespace tint::ir {
+namespace {
+
+using namespace tint::number_suffixes; // NOLINT
+
+using IR_BuilderImplTest = TestHelper;
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Add) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = Add(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:u32 = add %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundAdd) {
+ GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.u32());
+ auto* expr = CompoundAssign("v1", 1_u, ast::BinaryOp::kAdd);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, u32, read_write> = var private read_write
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:ref<private, u32, read_write> = add %1:ref<private, u32, read_write>, 1u
+ store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Subtract) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = Sub(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:u32 = sub %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundSubtract) {
+ GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.u32());
+ auto* expr = CompoundAssign("v1", 1_u, ast::BinaryOp::kSubtract);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, u32, read_write> = var private read_write
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:ref<private, u32, read_write> = sub %1:ref<private, u32, read_write>, 1u
+ store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Multiply) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = Mul(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:u32 = mul %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundMultiply) {
+ GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.u32());
+ auto* expr = CompoundAssign("v1", 1_u, ast::BinaryOp::kMultiply);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, u32, read_write> = var private read_write
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:ref<private, u32, read_write> = mul %1:ref<private, u32, read_write>, 1u
+ store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Div) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = Div(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:u32 = div %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundDiv) {
+ GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.u32());
+ auto* expr = CompoundAssign("v1", 1_u, ast::BinaryOp::kDivide);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, u32, read_write> = var private read_write
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:ref<private, u32, read_write> = div %1:ref<private, u32, read_write>, 1u
+ store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Modulo) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = Mod(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:u32 = mod %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundModulo) {
+ GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.u32());
+ auto* expr = CompoundAssign("v1", 1_u, ast::BinaryOp::kModulo);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, u32, read_write> = var private read_write
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:ref<private, u32, read_write> = mod %1:ref<private, u32, read_write>, 1u
+ store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_And) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = And(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:u32 = and %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundAnd) {
+ GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.bool_());
+ auto* expr = CompoundAssign("v1", false, ast::BinaryOp::kAnd);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, bool, read_write> = var private read_write
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:ref<private, bool, read_write> = and %1:ref<private, bool, read_write>, false
+ store %1:ref<private, bool, read_write>, %2:ref<private, bool, read_write>
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Or) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = Or(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:u32 = or %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundOr) {
+ GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.bool_());
+ auto* expr = CompoundAssign("v1", false, ast::BinaryOp::kOr);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, bool, read_write> = var private read_write
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:ref<private, bool, read_write> = or %1:ref<private, bool, read_write>, false
+ store %1:ref<private, bool, read_write>, %2:ref<private, bool, read_write>
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Xor) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = Xor(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:u32 = xor %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundXor) {
+ GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.u32());
+ auto* expr = CompoundAssign("v1", 1_u, ast::BinaryOp::kXor);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, u32, read_write> = var private read_write
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:ref<private, u32, read_write> = xor %1:ref<private, u32, read_write>, 1u
+ store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalAnd) {
+ Func("my_func", utils::Empty, ty.bool_(), utils::Vector{Return(true)});
+ auto* expr = LogicalAnd(Call("my_func"), false);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = func my_func():bool
+ %fn1 = block
+ ret true
+func_end
+
+%fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn3 = block
+ %1:bool = call my_func
+ %2:bool = var function read_write
+ store %2:bool, %1:bool
+ branch %fn4
+
+ %fn4 = if %1:bool [t: %fn5, f: %fn6, m: %fn7]
+ # true branch
+ %fn5 = block
+ store %2:bool, false
+ branch %fn7
+
+ # if merge
+ %fn7 = block
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalOr) {
+ Func("my_func", utils::Empty, ty.bool_(), utils::Vector{Return(true)});
+ auto* expr = LogicalOr(Call("my_func"), true);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = func my_func():bool
+ %fn1 = block
+ ret true
+func_end
+
+%fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn3 = block
+ %1:bool = call my_func
+ %2:bool = var function read_write
+ store %2:bool, %1:bool
+ branch %fn4
+
+ %fn4 = if %1:bool [t: %fn5, f: %fn6, m: %fn7]
+ # true branch
+ # false branch
+ %fn6 = block
+ store %2:bool, true
+ branch %fn7
+
+ # if merge
+ %fn7 = block
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Equal) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = Equal(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:bool = eq %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_NotEqual) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = NotEqual(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:bool = neq %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LessThan) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = LessThan(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:bool = lt %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_GreaterThan) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = GreaterThan(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:bool = gt %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LessThanEqual) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = LessThanEqual(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:bool = lte %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_GreaterThanEqual) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = GreaterThanEqual(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:bool = gte %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_ShiftLeft) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = Shl(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:u32 = shiftl %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundShiftLeft) {
+ GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.u32());
+ auto* expr = CompoundAssign("v1", 1_u, ast::BinaryOp::kShiftLeft);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, u32, read_write> = var private read_write
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:ref<private, u32, read_write> = shiftl %1:ref<private, u32, read_write>, 1u
+ store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_ShiftRight) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
+ auto* expr = Shr(Call("my_func"), 4_u);
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:u32 = shiftr %1:u32, 4u
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundShiftRight) {
+ GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.u32());
+ auto* expr = CompoundAssign("v1", 1_u, ast::BinaryOp::kShiftRight);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, u32, read_write> = var private read_write
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:ref<private, u32, read_write> = shiftr %1:ref<private, u32, read_write>, 1u
+ store %1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Compound) {
+ Func("my_func", utils::Empty, ty.f32(), utils::Vector{Return(0_f)});
+
+ auto* expr = LogicalAnd(LessThan(Call("my_func"), 2_f),
+ GreaterThan(2.5_f, Div(Call("my_func"), Mul(2.3_f, Call("my_func")))));
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = func my_func():f32
+ %fn1 = block
+ ret 0.0f
+func_end
+
+%fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn3 = block
+ %1:f32 = call my_func
+ %2:bool = lt %1:f32, 2.0f
+ %3:bool = var function read_write
+ store %3:bool, %2:bool
+ branch %fn4
+
+ %fn4 = if %2:bool [t: %fn5, f: %fn6, m: %fn7]
+ # true branch
+ %fn5 = block
+ %4:f32 = call my_func
+ %5:f32 = call my_func
+ %6:f32 = mul 2.29999995231628417969f, %5:f32
+ %7:f32 = div %4:f32, %6:f32
+ %8:bool = gt 2.5f, %7:f32
+ store %3:bool, %8:bool
+ branch %fn7
+
+ # if merge
+ %fn7 = block
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Compound_WithConstEval) {
+ Func("my_func", utils::Vector{Param("p", ty.bool_())}, ty.bool_(), utils::Vector{Return(true)});
+ auto* expr = Call("my_func", LogicalAnd(LessThan(2.4_f, 2_f),
+ GreaterThan(2.5_f, Div(10_f, Mul(2.3_f, 9.4_f)))));
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = func my_func():bool
+ %fn1 = block
+ ret true
+func_end
+
+%fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn3 = block
+ %1:bool = call my_func, false
+ ret
+func_end
+
+)");
+}
+
+} // namespace
+} // namespace tint::ir
diff --git a/src/tint/ir/builder_impl_call_test.cc b/src/tint/ir/builder_impl_call_test.cc
new file mode 100644
index 0000000..4564880
--- /dev/null
+++ b/src/tint/ir/builder_impl_call_test.cc
@@ -0,0 +1,153 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/ir/test_helper.h"
+
+#include "gmock/gmock.h"
+#include "src/tint/ast/case_selector.h"
+#include "src/tint/ast/int_literal_expression.h"
+#include "src/tint/constant/scalar.h"
+
+namespace tint::ir {
+namespace {
+
+using namespace tint::number_suffixes; // NOLINT
+
+using IR_BuilderImplTest = TestHelper;
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Bitcast) {
+ Func("my_func", utils::Empty, ty.f32(), utils::Vector{Return(0_f)});
+
+ auto* expr = Bitcast<f32>(Call("my_func"));
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:f32 = call my_func
+%2:f32 = bitcast %1:f32
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitStatement_Discard) {
+ auto* expr = Discard();
+ Func("test_function", {}, ty.void_(), expr,
+ utils::Vector{
+ create<ast::StageAttribute>(ast::PipelineStage::kFragment),
+ });
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ b.EmitStatement(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(discard
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitStatement_UserFunction) {
+ Func("my_func", utils::Vector{Param("p", ty.f32())}, ty.void_(), utils::Empty);
+
+ auto* stmt = CallStmt(Call("my_func", Mul(2_a, 3_a)));
+ WrapInFunction(stmt);
+
+ auto& b = CreateBuilder();
+
+ InjectFlowBlock();
+ b.EmitStatement(stmt);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:void = call my_func, 6.0f
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Convert) {
+ auto i = GlobalVar("i", builtin::AddressSpace::kPrivate, Expr(1_i));
+ auto* expr = Call(ty.f32(), i);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+ ASSERT_TRUE(r);
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, i32, read_write> = var private read_write
+store %1:ref<private, i32, read_write>, 1i
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:f32 = convert i32, %1:ref<private, i32, read_write>
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_ConstructEmpty) {
+ auto* expr = vec3(ty.f32());
+ GlobalVar("i", builtin::AddressSpace::kPrivate, expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+ ASSERT_TRUE(r);
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, vec3<f32>, read_write> = var private read_write
+store %1:ref<private, vec3<f32>, read_write>, vec3<f32> 0.0f
+
+
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Construct) {
+ auto i = GlobalVar("i", builtin::AddressSpace::kPrivate, Expr(1_f));
+ auto* expr = vec3(ty.f32(), 2_f, 3_f, i);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+ ASSERT_TRUE(r);
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, f32, read_write> = var private read_write
+store %1:ref<private, f32, read_write>, 1.0f
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:vec3<f32> = construct 2.0f, 3.0f, %1:ref<private, f32, read_write>
+ ret
+func_end
+
+)");
+}
+
+} // namespace
+} // namespace tint::ir
diff --git a/src/tint/ir/builder_impl_literal_test.cc b/src/tint/ir/builder_impl_literal_test.cc
new file mode 100644
index 0000000..090f3f8
--- /dev/null
+++ b/src/tint/ir/builder_impl_literal_test.cc
@@ -0,0 +1,115 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/ir/test_helper.h"
+
+#include "gmock/gmock.h"
+#include "src/tint/ast/case_selector.h"
+#include "src/tint/ast/int_literal_expression.h"
+#include "src/tint/constant/scalar.h"
+
+namespace tint::ir {
+namespace {
+
+using namespace tint::number_suffixes; // NOLINT
+
+using IR_BuilderImplTest = TestHelper;
+
+TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_True) {
+ auto* expr = Expr(true);
+ GlobalVar("a", ty.bool_(), builtin::AddressSpace::kPrivate, expr);
+
+ auto& b = CreateBuilder();
+ auto r = b.EmitLiteral(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+
+ ASSERT_TRUE(r.Get()->Is<Constant>());
+ auto* val = r.Get()->As<Constant>()->value;
+ EXPECT_TRUE(val->Is<constant::Scalar<bool>>());
+ EXPECT_TRUE(val->As<constant::Scalar<bool>>()->ValueAs<bool>());
+}
+
+TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_False) {
+ auto* expr = Expr(false);
+ GlobalVar("a", ty.bool_(), builtin::AddressSpace::kPrivate, expr);
+
+ auto& b = CreateBuilder();
+ auto r = b.EmitLiteral(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+
+ ASSERT_TRUE(r.Get()->Is<Constant>());
+ auto* val = r.Get()->As<Constant>()->value;
+ EXPECT_TRUE(val->Is<constant::Scalar<bool>>());
+ EXPECT_FALSE(val->As<constant::Scalar<bool>>()->ValueAs<bool>());
+}
+
+TEST_F(IR_BuilderImplTest, EmitLiteral_F32) {
+ auto* expr = Expr(1.2_f);
+ GlobalVar("a", ty.f32(), builtin::AddressSpace::kPrivate, expr);
+
+ auto& b = CreateBuilder();
+ auto r = b.EmitLiteral(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+
+ ASSERT_TRUE(r.Get()->Is<Constant>());
+ auto* val = r.Get()->As<Constant>()->value;
+ EXPECT_TRUE(val->Is<constant::Scalar<f32>>());
+ EXPECT_EQ(1.2_f, val->As<constant::Scalar<f32>>()->ValueAs<f32>());
+}
+
+TEST_F(IR_BuilderImplTest, EmitLiteral_F16) {
+ Enable(builtin::Extension::kF16);
+ auto* expr = Expr(1.2_h);
+ GlobalVar("a", ty.f16(), builtin::AddressSpace::kPrivate, expr);
+
+ auto& b = CreateBuilder();
+ auto r = b.EmitLiteral(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+
+ ASSERT_TRUE(r.Get()->Is<Constant>());
+ auto* val = r.Get()->As<Constant>()->value;
+ EXPECT_TRUE(val->Is<constant::Scalar<f16>>());
+ EXPECT_EQ(1.2_h, val->As<constant::Scalar<f16>>()->ValueAs<f32>());
+}
+
+TEST_F(IR_BuilderImplTest, EmitLiteral_I32) {
+ auto* expr = Expr(-2_i);
+ GlobalVar("a", ty.i32(), builtin::AddressSpace::kPrivate, expr);
+
+ auto& b = CreateBuilder();
+ auto r = b.EmitLiteral(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+
+ ASSERT_TRUE(r.Get()->Is<Constant>());
+ auto* val = r.Get()->As<Constant>()->value;
+ EXPECT_TRUE(val->Is<constant::Scalar<i32>>());
+ EXPECT_EQ(-2_i, val->As<constant::Scalar<i32>>()->ValueAs<f32>());
+}
+
+TEST_F(IR_BuilderImplTest, EmitLiteral_U32) {
+ auto* expr = Expr(2_u);
+ GlobalVar("a", ty.u32(), builtin::AddressSpace::kPrivate, expr);
+
+ auto& b = CreateBuilder();
+ auto r = b.EmitLiteral(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+
+ ASSERT_TRUE(r.Get()->Is<Constant>());
+ auto* val = r.Get()->As<Constant>()->value;
+ EXPECT_TRUE(val->Is<constant::Scalar<u32>>());
+ EXPECT_EQ(2_u, val->As<constant::Scalar<u32>>()->ValueAs<f32>());
+}
+
+} // namespace
+} // namespace tint::ir
diff --git a/src/tint/ir/builder_impl_materialize_test.cc b/src/tint/ir/builder_impl_materialize_test.cc
new file mode 100644
index 0000000..4f917f7
--- /dev/null
+++ b/src/tint/ir/builder_impl_materialize_test.cc
@@ -0,0 +1,47 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/ir/test_helper.h"
+
+#include "gmock/gmock.h"
+#include "src/tint/ast/case_selector.h"
+#include "src/tint/ast/int_literal_expression.h"
+#include "src/tint/constant/scalar.h"
+
+namespace tint::ir {
+namespace {
+
+using namespace tint::number_suffixes; // NOLINT
+
+using IR_BuilderImplTest = TestHelper;
+
+TEST_F(IR_BuilderImplTest, EmitExpression_MaterializedCall) {
+ auto* expr = Return(Call("trunc", 2.5_f));
+
+ Func("test_function", {}, ty.f32(), expr, utils::Empty);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function():f32
+ %fn1 = block
+ ret 2.0f
+func_end
+
+)");
+}
+
+} // namespace
+} // namespace tint::ir
diff --git a/src/tint/ir/builder_impl_store_test.cc b/src/tint/ir/builder_impl_store_test.cc
new file mode 100644
index 0000000..f7cc6ab
--- /dev/null
+++ b/src/tint/ir/builder_impl_store_test.cc
@@ -0,0 +1,54 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/ir/test_helper.h"
+
+#include "gmock/gmock.h"
+#include "src/tint/ast/case_selector.h"
+#include "src/tint/ast/int_literal_expression.h"
+#include "src/tint/constant/scalar.h"
+
+namespace tint::ir {
+namespace {
+
+using namespace tint::number_suffixes; // NOLINT
+
+using IR_BuilderImplTest = TestHelper;
+
+TEST_F(IR_BuilderImplTest, EmitStatement_Assign) {
+ GlobalVar("a", ty.u32(), builtin::AddressSpace::kPrivate);
+
+ auto* expr = Assign("a", 4_u);
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, u32, read_write> = var private read_write
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ store %1:ref<private, u32, read_write>, 4u
+ ret
+func_end
+
+)");
+}
+
+} // namespace
+} // namespace tint::ir
diff --git a/src/tint/ir/builder_impl_test.cc b/src/tint/ir/builder_impl_test.cc
index 1e6a26d..4a6e713 100644
--- a/src/tint/ir/builder_impl_test.cc
+++ b/src/tint/ir/builder_impl_test.cc
@@ -42,7 +42,7 @@
EXPECT_EQ(1u, f->start_target->inbound_branches.Length());
EXPECT_EQ(1u, f->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func f
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = func f():void
%fn1 = block
ret
func_end
@@ -88,7 +88,8 @@
EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -136,7 +137,8 @@
EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
EXPECT_EQ(2u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -183,7 +185,8 @@
EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
EXPECT_EQ(2u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -230,7 +233,8 @@
EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
EXPECT_EQ(2u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -273,7 +277,8 @@
ASSERT_NE(loop_flow->continuing.target, nullptr);
ASSERT_NE(loop_flow->merge.target, nullptr);
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -330,7 +335,8 @@
EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -388,7 +394,8 @@
EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -463,7 +470,8 @@
EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -538,7 +546,8 @@
EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -595,7 +604,8 @@
EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -657,7 +667,8 @@
// This is 1 because only the loop branch happens. The subsequent if return is dead code.
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -711,7 +722,8 @@
EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -857,7 +869,8 @@
EXPECT_EQ(1u, func->start_target->inbound_branches.Length());
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -1001,7 +1014,8 @@
EXPECT_EQ(1u, if_flow->false_.target->inbound_branches.Length());
EXPECT_EQ(1u, if_flow->merge.target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -1071,7 +1085,8 @@
EXPECT_EQ(1u, if_flow->false_.target->inbound_branches.Length());
EXPECT_EQ(1u, if_flow->merge.target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -1178,7 +1193,8 @@
EXPECT_EQ(1u, flow->merge.target->inbound_branches.Length());
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -1237,7 +1253,8 @@
EXPECT_EQ(3u, flow->merge.target->inbound_branches.Length());
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -1301,7 +1318,8 @@
EXPECT_EQ(1u, flow->merge.target->inbound_branches.Length());
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -1345,7 +1363,8 @@
EXPECT_EQ(1u, flow->merge.target->inbound_branches.Length());
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -1398,7 +1417,8 @@
// This is 1 because the if is dead-code eliminated and the return doesn't happen.
EXPECT_EQ(1u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -1457,7 +1477,8 @@
EXPECT_EQ(0u, flow->merge.target->inbound_branches.Length());
EXPECT_EQ(2u, func->end_target->inbound_branches.Length());
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
%fn1 = block
branch %fn2
@@ -1473,669 +1494,5 @@
)");
}
-TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_True) {
- auto* expr = Expr(true);
- GlobalVar("a", ty.bool_(), builtin::AddressSpace::kPrivate, expr);
-
- auto& b = CreateBuilder();
- auto r = b.EmitLiteral(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
-
- ASSERT_TRUE(r.Get()->Is<Constant>());
- auto* val = r.Get()->As<Constant>()->value;
- EXPECT_TRUE(val->Is<constant::Scalar<bool>>());
- EXPECT_TRUE(val->As<constant::Scalar<bool>>()->ValueAs<bool>());
-}
-
-TEST_F(IR_BuilderImplTest, EmitLiteral_Bool_False) {
- auto* expr = Expr(false);
- GlobalVar("a", ty.bool_(), builtin::AddressSpace::kPrivate, expr);
-
- auto& b = CreateBuilder();
- auto r = b.EmitLiteral(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
-
- ASSERT_TRUE(r.Get()->Is<Constant>());
- auto* val = r.Get()->As<Constant>()->value;
- EXPECT_TRUE(val->Is<constant::Scalar<bool>>());
- EXPECT_FALSE(val->As<constant::Scalar<bool>>()->ValueAs<bool>());
-}
-
-TEST_F(IR_BuilderImplTest, EmitLiteral_F32) {
- auto* expr = Expr(1.2_f);
- GlobalVar("a", ty.f32(), builtin::AddressSpace::kPrivate, expr);
-
- auto& b = CreateBuilder();
- auto r = b.EmitLiteral(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
-
- ASSERT_TRUE(r.Get()->Is<Constant>());
- auto* val = r.Get()->As<Constant>()->value;
- EXPECT_TRUE(val->Is<constant::Scalar<f32>>());
- EXPECT_EQ(1.2_f, val->As<constant::Scalar<f32>>()->ValueAs<f32>());
-}
-
-TEST_F(IR_BuilderImplTest, EmitLiteral_F16) {
- Enable(builtin::Extension::kF16);
- auto* expr = Expr(1.2_h);
- GlobalVar("a", ty.f16(), builtin::AddressSpace::kPrivate, expr);
-
- auto& b = CreateBuilder();
- auto r = b.EmitLiteral(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
-
- ASSERT_TRUE(r.Get()->Is<Constant>());
- auto* val = r.Get()->As<Constant>()->value;
- EXPECT_TRUE(val->Is<constant::Scalar<f16>>());
- EXPECT_EQ(1.2_h, val->As<constant::Scalar<f16>>()->ValueAs<f32>());
-}
-
-TEST_F(IR_BuilderImplTest, EmitLiteral_I32) {
- auto* expr = Expr(-2_i);
- GlobalVar("a", ty.i32(), builtin::AddressSpace::kPrivate, expr);
-
- auto& b = CreateBuilder();
- auto r = b.EmitLiteral(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
-
- ASSERT_TRUE(r.Get()->Is<Constant>());
- auto* val = r.Get()->As<Constant>()->value;
- EXPECT_TRUE(val->Is<constant::Scalar<i32>>());
- EXPECT_EQ(-2_i, val->As<constant::Scalar<i32>>()->ValueAs<f32>());
-}
-
-TEST_F(IR_BuilderImplTest, EmitLiteral_U32) {
- auto* expr = Expr(2_u);
- GlobalVar("a", ty.u32(), builtin::AddressSpace::kPrivate, expr);
-
- auto& b = CreateBuilder();
- auto r = b.EmitLiteral(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
-
- ASSERT_TRUE(r.Get()->Is<Constant>());
- auto* val = r.Get()->As<Constant>()->value;
- EXPECT_TRUE(val->Is<constant::Scalar<u32>>());
- EXPECT_EQ(2_u, val->As<constant::Scalar<u32>>()->ValueAs<f32>());
-}
-
-TEST_F(IR_BuilderImplTest, Emit_GlobalVar_NoInit) {
- GlobalVar("a", ty.u32(), builtin::AddressSpace::kPrivate);
-
- auto r = Build();
- ASSERT_TRUE(r) << Error();
- auto m = r.Move();
-
- EXPECT_EQ(Disassemble(m), R"(%fn0 = block
-%1(ref<private, u32, read_write>) = var private read_write
-ret
-
-)");
-}
-
-TEST_F(IR_BuilderImplTest, Emit_GlobalVar_Init) {
- auto* expr = Expr(2_u);
- GlobalVar("a", ty.u32(), builtin::AddressSpace::kPrivate, expr);
-
- auto r = Build();
- ASSERT_TRUE(r) << Error();
- auto m = r.Move();
-
- EXPECT_EQ(Disassemble(m), R"(%fn0 = block
-%1(ref<private, u32, read_write>) = var private read_write
-store %1(ref<private, u32, read_write>), 2u
-ret
-
-)");
-}
-
-TEST_F(IR_BuilderImplTest, Emit_Var_NoInit) {
- auto* a = Var("a", ty.u32(), builtin::AddressSpace::kFunction);
- WrapInFunction(a);
-
- auto r = Build();
- ASSERT_TRUE(r) << Error();
- auto m = r.Move();
-
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
- %fn1 = block
- %1(ref<function, u32, read_write>) = var function read_write
- ret
-func_end
-
-)");
-}
-
-TEST_F(IR_BuilderImplTest, Emit_Var_Init) {
- auto* expr = Expr(2_u);
- auto* a = Var("a", ty.u32(), builtin::AddressSpace::kFunction, expr);
- WrapInFunction(a);
-
- auto r = Build();
- ASSERT_TRUE(r) << Error();
- auto m = r.Move();
-
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
- %fn1 = block
- %1(ref<function, u32, read_write>) = var function read_write
- store %1(ref<function, u32, read_write>), 2u
- ret
-func_end
-
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Add) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = Add(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(u32) = add %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Subtract) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = Sub(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(u32) = sub %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Multiply) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = Mul(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(u32) = mul %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Div) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = Div(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(u32) = div %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Modulo) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = Mod(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(u32) = mod %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_And) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = And(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(u32) = bit_and %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Or) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = Or(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(u32) = bit_or %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Xor) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = Xor(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(u32) = bit_xor %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalAnd) {
- Func("my_func", utils::Empty, ty.bool_(), utils::Vector{Return(true)});
- auto* expr = LogicalAnd(Call("my_func"), false);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(bool) = call my_func
-%2(bool) = log_and %1(bool), false
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LogicalOr) {
- Func("my_func", utils::Empty, ty.bool_(), utils::Vector{Return(true)});
- auto* expr = LogicalOr(Call("my_func"), true);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(bool) = call my_func
-%2(bool) = log_or %1(bool), true
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Equal) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = Equal(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(bool) = eq %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_NotEqual) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = NotEqual(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(bool) = neq %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LessThan) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = LessThan(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(bool) = lt %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_GreaterThan) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = GreaterThan(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(bool) = gt %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_LessThanEqual) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = LessThanEqual(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(bool) = lte %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_GreaterThanEqual) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = GreaterThanEqual(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(bool) = gte %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_ShiftLeft) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = Shl(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(u32) = shiftl %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_ShiftRight) {
- Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(0_u)});
- auto* expr = Shr(Call("my_func"), 4_u);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(u32) = call my_func
-%2(u32) = shiftr %1(u32), 4u
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Compound) {
- Func("my_func", utils::Empty, ty.f32(), utils::Vector{Return(0_f)});
-
- auto* expr = LogicalAnd(LessThan(Call("my_func"), 2_f),
- GreaterThan(2.5_f, Div(Call("my_func"), Mul(2.3_f, Call("my_func")))));
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(f32) = call my_func
-%2(bool) = lt %1(f32), 2.0f
-%3(f32) = call my_func
-%4(f32) = call my_func
-%5(f32) = mul 2.29999995231628417969f, %4(f32)
-%6(f32) = div %3(f32), %5(f32)
-%7(bool) = gt 2.5f, %6(f32)
-%8(bool) = log_and %2(bool), %7(bool)
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Compound_WithConstEval) {
- Func("my_func", utils::Vector{Param("p", ty.bool_())}, ty.bool_(), utils::Vector{Return(true)});
- auto* expr = Call("my_func", LogicalAnd(LessThan(2.4_f, 2_f),
- GreaterThan(2.5_f, Div(10_f, Mul(2.3_f, 9.4_f)))));
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(bool) = call my_func, false
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_Bitcast) {
- Func("my_func", utils::Empty, ty.f32(), utils::Vector{Return(0_f)});
-
- auto* expr = Bitcast<f32>(Call("my_func"));
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(f32) = call my_func
-%2(f32) = bitcast %1(f32)
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitStatement_Discard) {
- auto* expr = Discard();
- Func("test_function", {}, ty.void_(), expr,
- utils::Vector{
- create<ast::StageAttribute>(ast::PipelineStage::kFragment),
- });
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- b.EmitStatement(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(discard
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitStatement_UserFunction) {
- Func("my_func", utils::Vector{Param("p", ty.f32())}, ty.void_(), utils::Empty);
-
- auto* stmt = CallStmt(Call("my_func", Mul(2_a, 3_a)));
- WrapInFunction(stmt);
-
- auto& b = CreateBuilder();
-
- InjectFlowBlock();
- b.EmitStatement(stmt);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(void) = call my_func, 6.0f
-)");
-}
-
-// TODO(dsinclair): This needs assignment in order to output correctly. The empty constructor ends
-// up materializing, so there is no expression to emit until there is a usage. When assigment is
-// implemented this can be enabled (and the output updated).
-TEST_F(IR_BuilderImplTest, DISABLED_EmitExpression_ConstructEmpty) {
- auto* expr = vec3(ty.f32());
- GlobalVar("i", builtin::AddressSpace::kPrivate, expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%1(vec3<f32>) = construct
-)");
-}
-
-// Requires identifier expressions
-TEST_F(IR_BuilderImplTest, DISABLED_EmitExpression_Construct) {
- auto i = GlobalVar("i", builtin::AddressSpace::kPrivate, Expr(1_f));
- auto* expr = vec3(ty.f32(), 2_f, 3_f, i);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%2(vec3<f32>) = construct 2.0f, 3.0f, %1(void)
-)");
-}
-
-// Requires identifier expressions
-TEST_F(IR_BuilderImplTest, DISABLED_EmitExpression_Convert) {
- auto i = GlobalVar("i", builtin::AddressSpace::kPrivate, Expr(1_i));
- auto* expr = Call(ty.f32(), i);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%2(f32) = convert i32, %1(void)
-)");
-}
-
-TEST_F(IR_BuilderImplTest, EmitExpression_MaterializedCall) {
- auto* expr = Return(Call("trunc", 2.5_f));
-
- Func("test_function", {}, ty.f32(), expr, utils::Empty);
-
- auto r = Build();
- ASSERT_TRUE(r) << Error();
- auto m = r.Move();
-
- EXPECT_EQ(Disassemble(m), R"(%fn0 = func test_function
- %fn1 = block
- ret 2.0f
-func_end
-
-)");
-}
-
-// Requires identifier expressions
-TEST_F(IR_BuilderImplTest, DISABLED_EmitExpression_Builtin) {
- auto i = GlobalVar("i", builtin::AddressSpace::kPrivate, Expr(1_f));
- auto* expr = Call("asin", i);
- WrapInFunction(expr);
-
- auto& b = CreateBuilder();
- InjectFlowBlock();
- auto r = b.EmitExpression(expr);
- ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
- ASSERT_TRUE(r);
-
- Disassembler d(b.builder.ir);
- d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
- EXPECT_EQ(d.AsString(), R"(%2(f32) = asin %1(void)
-)");
-}
-
} // namespace
} // namespace tint::ir
diff --git a/src/tint/ir/builder_impl_unary_test.cc b/src/tint/ir/builder_impl_unary_test.cc
new file mode 100644
index 0000000..9d35c02
--- /dev/null
+++ b/src/tint/ir/builder_impl_unary_test.cc
@@ -0,0 +1,135 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/ir/test_helper.h"
+
+#include "gmock/gmock.h"
+#include "src/tint/ast/case_selector.h"
+#include "src/tint/ast/int_literal_expression.h"
+#include "src/tint/constant/scalar.h"
+
+namespace tint::ir {
+namespace {
+
+using namespace tint::number_suffixes; // NOLINT
+
+using IR_BuilderImplTest = TestHelper;
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Unary_Not) {
+ Func("my_func", utils::Empty, ty.bool_(), utils::Vector{Return(false)});
+ auto* expr = Not(Call("my_func"));
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:bool = call my_func
+%2:bool = eq %1:bool, false
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Unary_Complement) {
+ Func("my_func", utils::Empty, ty.u32(), utils::Vector{Return(1_u)});
+ auto* expr = Complement(Call("my_func"));
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:u32 = call my_func
+%2:u32 = complement %1:u32
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Unary_Negation) {
+ Func("my_func", utils::Empty, ty.i32(), utils::Vector{Return(1_i)});
+ auto* expr = Negation(Call("my_func"));
+ WrapInFunction(expr);
+
+ auto& b = CreateBuilder();
+ InjectFlowBlock();
+ auto r = b.EmitExpression(expr);
+ ASSERT_THAT(b.Diagnostics(), testing::IsEmpty());
+ ASSERT_TRUE(r);
+
+ Disassembler d(b.builder.ir);
+ d.EmitBlockInstructions(b.current_flow_block->As<ir::Block>());
+ EXPECT_EQ(d.AsString(), R"(%1:i32 = call my_func
+%2:i32 = negation %1:i32
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Unary_AddressOf) {
+ GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.i32());
+
+ auto* expr = Decl(Let("v2", AddressOf("v1")));
+ WrapInFunction(expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, i32, read_write> = var private read_write
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:ptr<private, i32, read_write> = addr_of %1:ref<private, i32, read_write>
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, EmitExpression_Unary_Indirection) {
+ GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.i32());
+ utils::Vector stmts = {
+ Decl(Let("v3", AddressOf("v1"))),
+ Decl(Let("v2", Deref("v3"))),
+ };
+ WrapInFunction(stmts);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, i32, read_write> = var private read_write
+
+
+
+%fn1 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn2 = block
+ %2:ptr<private, i32, read_write> = addr_of %1:ref<private, i32, read_write>
+ %3:i32 = indirection %2:ptr<private, i32, read_write>
+ ret
+func_end
+
+)");
+}
+
+} // namespace
+} // namespace tint::ir
diff --git a/src/tint/ir/builder_impl_var_test.cc b/src/tint/ir/builder_impl_var_test.cc
new file mode 100644
index 0000000..485684a
--- /dev/null
+++ b/src/tint/ir/builder_impl_var_test.cc
@@ -0,0 +1,99 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/ir/test_helper.h"
+
+#include "gmock/gmock.h"
+#include "src/tint/ast/case_selector.h"
+#include "src/tint/ast/int_literal_expression.h"
+#include "src/tint/constant/scalar.h"
+
+namespace tint::ir {
+namespace {
+
+using namespace tint::number_suffixes; // NOLINT
+
+using IR_BuilderImplTest = TestHelper;
+
+TEST_F(IR_BuilderImplTest, Emit_GlobalVar_NoInit) {
+ GlobalVar("a", ty.u32(), builtin::AddressSpace::kPrivate);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, u32, read_write> = var private read_write
+
+
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, Emit_GlobalVar_Init) {
+ auto* expr = Expr(2_u);
+ GlobalVar("a", ty.u32(), builtin::AddressSpace::kPrivate, expr);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m), R"(%fn0 = block
+%1:ref<private, u32, read_write> = var private read_write
+store %1:ref<private, u32, read_write>, 2u
+
+
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, Emit_Var_NoInit) {
+ auto* a = Var("a", ty.u32(), builtin::AddressSpace::kFunction);
+ WrapInFunction(a);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn1 = block
+ %1:ref<function, u32, read_write> = var function read_write
+ ret
+func_end
+
+)");
+}
+
+TEST_F(IR_BuilderImplTest, Emit_Var_Init) {
+ auto* expr = Expr(2_u);
+ auto* a = Var("a", ty.u32(), builtin::AddressSpace::kFunction, expr);
+ WrapInFunction(a);
+
+ auto r = Build();
+ ASSERT_TRUE(r) << Error();
+ auto m = r.Move();
+
+ EXPECT_EQ(Disassemble(m),
+ R"(%fn0 = func test_function():void [@compute @workgroup_size(1, 1, 1)]
+ %fn1 = block
+ %1:ref<function, u32, read_write> = var function read_write
+ store %1:ref<function, u32, read_write>, 2u
+ ret
+func_end
+
+)");
+}
+} // namespace
+} // namespace tint::ir
diff --git a/src/tint/ir/builtin.cc b/src/tint/ir/builtin.cc
index 54cf882..5e53eec 100644
--- a/src/tint/ir/builtin.cc
+++ b/src/tint/ir/builtin.cc
@@ -13,6 +13,9 @@
// limitations under the License.
#include "src/tint/ir/builtin.h"
+
+#include <utility>
+
#include "src/tint/debug.h"
TINT_INSTANTIATE_TYPEINFO(tint::ir::Builtin);
@@ -20,19 +23,13 @@
// \cond DO_NOT_DOCUMENT
namespace tint::ir {
-Builtin::Builtin(uint32_t id,
- const type::Type* type,
+Builtin::Builtin(uint32_t identifier,
+ const type::Type* ty,
builtin::Function func,
- utils::VectorRef<Value*> args)
- : Base(id, type, args), func_(func) {}
+ utils::VectorRef<Value*> arguments)
+ : Base(identifier, ty, std::move(arguments)), func_(func) {}
Builtin::~Builtin() = default;
-utils::StringStream& Builtin::ToInstruction(utils::StringStream& out) const {
- ToValue(out) << " = " << builtin::str(func_) << " ";
- EmitArgs(out);
- return out;
-}
-
} // namespace tint::ir
// \endcond
diff --git a/src/tint/ir/builtin.h b/src/tint/ir/builtin.h
index 9f6f666..2106a68 100644
--- a/src/tint/ir/builtin.h
+++ b/src/tint/ir/builtin.h
@@ -18,7 +18,6 @@
#include "src/tint/builtin/function.h"
#include "src/tint/ir/call.h"
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
@@ -44,11 +43,6 @@
/// @returns the builtin function
builtin::Function Func() const { return func_; }
- /// Write the instruction to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- utils::StringStream& ToInstruction(utils::StringStream& out) const override;
-
private:
const builtin::Function func_;
};
diff --git a/src/tint/ir/call.cc b/src/tint/ir/call.cc
index 322f83d..9f5a8a5 100644
--- a/src/tint/ir/call.cc
+++ b/src/tint/ir/call.cc
@@ -14,14 +14,14 @@
#include "src/tint/ir/call.h"
+#include <utility>
+
TINT_INSTANTIATE_TYPEINFO(tint::ir::Call);
namespace tint::ir {
-Call::Call() : Base() {}
-
-Call::Call(uint32_t id, const type::Type* type, utils::VectorRef<Value*> args)
- : Base(id, type), args_(args) {
+Call::Call(uint32_t identifier, const type::Type* ty, utils::VectorRef<Value*> arguments)
+ : Base(identifier, ty), args(std::move(arguments)) {
for (auto* arg : args) {
arg->AddUsage(this);
}
@@ -29,15 +29,4 @@
Call::~Call() = default;
-void Call::EmitArgs(utils::StringStream& out) const {
- bool first = true;
- for (const auto* arg : args_) {
- if (!first) {
- out << ", ";
- }
- first = false;
- arg->ToValue(out);
- }
-}
-
} // namespace tint::ir
diff --git a/src/tint/ir/call.h b/src/tint/ir/call.h
index a49e9fa..b0f2e7c 100644
--- a/src/tint/ir/call.h
+++ b/src/tint/ir/call.h
@@ -17,7 +17,6 @@
#include "src/tint/ir/instruction.h"
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
@@ -31,24 +30,17 @@
Call& operator=(const Call& inst) = delete;
Call& operator=(Call&& inst) = delete;
- /// @returns the constructor arguments
- utils::VectorRef<Value*> Args() const { return args_; }
-
- /// Writes the call arguments to the given stream.
- /// @param out the output stream
- void EmitArgs(utils::StringStream& out) const;
+ /// The constructor arguments
+ utils::Vector<Value*, 1> args;
protected:
/// Constructor
- Call();
+ Call() = delete;
/// Constructor
/// @param id the instruction id
/// @param type the result type
/// @param args the constructor arguments
Call(uint32_t id, const type::Type* type, utils::VectorRef<Value*> args);
-
- private:
- utils::Vector<Value*, 1> args_;
};
} // namespace tint::ir
diff --git a/src/tint/ir/constant.cc b/src/tint/ir/constant.cc
index 0666e91..8b5260c 100644
--- a/src/tint/ir/constant.cc
+++ b/src/tint/ir/constant.cc
@@ -14,13 +14,6 @@
#include "src/tint/ir/constant.h"
-#include <string>
-
-#include "src/tint/constant/composite.h"
-#include "src/tint/constant/scalar.h"
-#include "src/tint/constant/splat.h"
-#include "src/tint/switch.h"
-
TINT_INSTANTIATE_TYPEINFO(tint::ir::Constant);
namespace tint::ir {
@@ -29,43 +22,4 @@
Constant::~Constant() = default;
-utils::StringStream& Constant::ToValue(utils::StringStream& out) const {
- std::function<void(const constant::Value*)> emit = [&](const constant::Value* c) {
- Switch(
- c,
- [&](const constant::Scalar<AFloat>* scalar) { out << scalar->ValueAs<AFloat>().value; },
- [&](const constant::Scalar<AInt>* scalar) { out << scalar->ValueAs<AInt>().value; },
- [&](const constant::Scalar<i32>* scalar) {
- out << scalar->ValueAs<i32>().value << "i";
- },
- [&](const constant::Scalar<u32>* scalar) {
- out << scalar->ValueAs<u32>().value << "u";
- },
- [&](const constant::Scalar<f32>* scalar) {
- out << scalar->ValueAs<f32>().value << "f";
- },
- [&](const constant::Scalar<f16>* scalar) {
- out << scalar->ValueAs<f16>().value << "h";
- },
- [&](const constant::Scalar<bool>* scalar) {
- out << (scalar->ValueAs<bool>() ? "true" : "false");
- },
- [&](const constant::Splat* splat) {
- out << splat->Type()->FriendlyName() << " ";
- emit(splat->Index(0));
- },
- [&](const constant::Composite* composite) {
- out << composite->Type()->FriendlyName() << " ";
- for (const auto* elem : composite->elements) {
- if (elem != composite->elements[0]) {
- out << ", ";
- }
- emit(elem);
- }
- });
- };
- emit(value);
- return out;
-}
-
} // namespace tint::ir
diff --git a/src/tint/ir/constant.h b/src/tint/ir/constant.h
index 2413721..68e0dc7 100644
--- a/src/tint/ir/constant.h
+++ b/src/tint/ir/constant.h
@@ -17,7 +17,6 @@
#include "src/tint/constant/value.h"
#include "src/tint/ir/value.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
@@ -32,11 +31,6 @@
/// @returns the type of the constant
const type::Type* Type() const override { return value->Type(); }
- /// Write the constant to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- utils::StringStream& ToValue(utils::StringStream& out) const override;
-
/// The constants value
const constant::Value* const value;
};
diff --git a/src/tint/ir/constant_test.cc b/src/tint/ir/constant_test.cc
index 43d92b4..c550763 100644
--- a/src/tint/ir/constant_test.cc
+++ b/src/tint/ir/constant_test.cc
@@ -14,7 +14,6 @@
#include "src/tint/ir/test_helper.h"
#include "src/tint/ir/value.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
namespace {
@@ -31,9 +30,6 @@
auto* c = b.builder.Constant(1.2_f);
EXPECT_EQ(1.2_f, c->value->As<constant::Scalar<f32>>()->ValueAs<f32>());
- c->ToValue(str);
- EXPECT_EQ("1.20000004768371582031f", str.str());
-
EXPECT_TRUE(c->value->Is<constant::Scalar<f32>>());
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
EXPECT_FALSE(c->value->Is<constant::Scalar<i32>>());
@@ -49,9 +45,6 @@
auto* c = b.builder.Constant(1.1_h);
EXPECT_EQ(1.1_h, c->value->As<constant::Scalar<f16>>()->ValueAs<f16>());
- c->ToValue(str);
- EXPECT_EQ("1.099609375h", str.str());
-
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
EXPECT_TRUE(c->value->Is<constant::Scalar<f16>>());
EXPECT_FALSE(c->value->Is<constant::Scalar<i32>>());
@@ -67,9 +60,6 @@
auto* c = b.builder.Constant(1_i);
EXPECT_EQ(1_i, c->value->As<constant::Scalar<i32>>()->ValueAs<i32>());
- c->ToValue(str);
- EXPECT_EQ("1i", str.str());
-
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
EXPECT_TRUE(c->value->Is<constant::Scalar<i32>>());
@@ -85,9 +75,6 @@
auto* c = b.builder.Constant(2_u);
EXPECT_EQ(2_u, c->value->As<constant::Scalar<u32>>()->ValueAs<u32>());
- c->ToValue(str);
- EXPECT_EQ("2u", str.str());
-
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
EXPECT_FALSE(c->value->Is<constant::Scalar<i32>>());
@@ -103,9 +90,6 @@
auto* c = b.builder.Constant(false);
EXPECT_FALSE(c->value->As<constant::Scalar<bool>>()->ValueAs<bool>());
-
- c->ToValue(str);
- EXPECT_EQ("false", str.str());
}
{
@@ -113,9 +97,6 @@
auto c = b.builder.Constant(true);
EXPECT_TRUE(c->value->As<constant::Scalar<bool>>()->ValueAs<bool>());
- c->ToValue(str);
- EXPECT_EQ("true", str.str());
-
EXPECT_FALSE(c->value->Is<constant::Scalar<f32>>());
EXPECT_FALSE(c->value->Is<constant::Scalar<f16>>());
EXPECT_FALSE(c->value->Is<constant::Scalar<i32>>());
diff --git a/src/tint/ir/construct.cc b/src/tint/ir/construct.cc
index 1507e8f..44c8862 100644
--- a/src/tint/ir/construct.cc
+++ b/src/tint/ir/construct.cc
@@ -13,21 +13,18 @@
// limitations under the License.
#include "src/tint/ir/construct.h"
+
+#include <utility>
+
#include "src/tint/debug.h"
TINT_INSTANTIATE_TYPEINFO(tint::ir::Construct);
namespace tint::ir {
-Construct::Construct(uint32_t id, const type::Type* type, utils::VectorRef<Value*> args)
- : Base(id, type, args) {}
+Construct::Construct(uint32_t identifier, const type::Type* ty, utils::VectorRef<Value*> arguments)
+ : Base(identifier, ty, std::move(arguments)) {}
Construct::~Construct() = default;
-utils::StringStream& Construct::ToInstruction(utils::StringStream& out) const {
- ToValue(out) << " = construct ";
- EmitArgs(out);
- return out;
-}
-
} // namespace tint::ir
diff --git a/src/tint/ir/construct.h b/src/tint/ir/construct.h
index 1cc0102..b1711fb 100644
--- a/src/tint/ir/construct.h
+++ b/src/tint/ir/construct.h
@@ -17,7 +17,6 @@
#include "src/tint/ir/call.h"
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
@@ -35,11 +34,6 @@
Construct& operator=(const Construct& inst) = delete;
Construct& operator=(Construct&& inst) = delete;
-
- /// Write the instruction to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- utils::StringStream& ToInstruction(utils::StringStream& out) const override;
};
} // namespace tint::ir
diff --git a/src/tint/ir/convert.cc b/src/tint/ir/convert.cc
index 7ffd6f5..969390c 100644
--- a/src/tint/ir/convert.cc
+++ b/src/tint/ir/convert.cc
@@ -19,18 +19,12 @@
namespace tint::ir {
-Convert::Convert(uint32_t id,
+Convert::Convert(uint32_t identifier,
const type::Type* to_type,
const type::Type* from_type,
- utils::VectorRef<Value*> args)
- : Base(id, to_type, args), from_type_(from_type) {}
+ utils::VectorRef<Value*> arguments)
+ : Base(identifier, to_type, arguments), from_type_(from_type) {}
Convert::~Convert() = default;
-utils::StringStream& Convert::ToInstruction(utils::StringStream& out) const {
- ToValue(out) << " = convert " << from_type_->FriendlyName() << ", ";
- EmitArgs(out);
- return out;
-}
-
} // namespace tint::ir
diff --git a/src/tint/ir/convert.h b/src/tint/ir/convert.h
index c164a45..953a5fa 100644
--- a/src/tint/ir/convert.h
+++ b/src/tint/ir/convert.h
@@ -18,7 +18,6 @@
#include "src/tint/ir/call.h"
#include "src/tint/type/type.h"
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
@@ -46,11 +45,6 @@
/// @returns the to type
const type::Type* ToType() const { return Type(); }
- /// Write the instruction to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- utils::StringStream& ToInstruction(utils::StringStream& out) const override;
-
private:
const type::Type* from_type_ = nullptr;
};
diff --git a/src/tint/ir/converter.h b/src/tint/ir/converter.h
deleted file mode 100644
index 8defd83..0000000
--- a/src/tint/ir/converter.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2023 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef SRC_TINT_IR_CONVERTER_H_
-#define SRC_TINT_IR_CONVERTER_H_
-
-#include <string>
-
-#include "src/tint/ir/module.h"
-#include "src/tint/utils/result.h"
-
-// Forward Declarations
-namespace tint {
-class Program;
-} // namespace tint
-
-namespace tint::ir {
-
-/// Class for converting into and out of IR.
-class Converter {
- public:
- /// The result type for the FromProgram method.
- using Result = utils::Result<Module, std::string>;
-
- /// Builds an ir::Module from the given Program
- /// @param program the Program to use.
- /// @returns the `utiils::Result` of generating the IR. The result will contain the `ir::Module`
- /// on success, otherwise the `std::string` error.
- ///
- /// @note this assumes the program |IsValid|, and has had const-eval done so
- /// any abstract values have been calculated and converted into the relevant
- /// concrete types.
- static Result FromProgram(const Program* program);
-
- /// Converts the module back to a Program
- /// @returns the resulting program, or nullptr on error
- /// (Note, this will probably turn into a utils::Result, just stubbing for now)
- static const Program* ToProgram();
-};
-
-} // namespace tint::ir
-
-#endif // SRC_TINT_IR_CONVERTER_H_
diff --git a/src/tint/ir/debug.cc b/src/tint/ir/debug.cc
index f69805e..655c455 100644
--- a/src/tint/ir/debug.cc
+++ b/src/tint/ir/debug.cc
@@ -18,10 +18,10 @@
#include <unordered_set>
#include "src/tint/ir/block.h"
+#include "src/tint/ir/function_terminator.h"
#include "src/tint/ir/if.h"
#include "src/tint/ir/loop.h"
#include "src/tint/ir/switch.h"
-#include "src/tint/ir/terminator.h"
#include "src/tint/switch.h"
#include "src/tint/utils/string_stream.h"
@@ -136,7 +136,7 @@
Graph(l->continuing.target);
Graph(l->merge.target);
},
- [&](const ir::Terminator*) {
+ [&](const ir::FunctionTerminator*) {
// Already done
});
};
diff --git a/src/tint/ir/disassembler.cc b/src/tint/ir/disassembler.cc
index 2b8de0b..58fb1a0 100644
--- a/src/tint/ir/disassembler.cc
+++ b/src/tint/ir/disassembler.cc
@@ -14,12 +14,27 @@
#include "src/tint/ir/disassembler.h"
+#include "src//tint/ir/unary.h"
+#include "src/tint/constant/composite.h"
+#include "src/tint/constant/scalar.h"
+#include "src/tint/constant/splat.h"
+#include "src/tint/ir/binary.h"
+#include "src/tint/ir/bitcast.h"
#include "src/tint/ir/block.h"
+#include "src/tint/ir/builtin.h"
+#include "src/tint/ir/construct.h"
+#include "src/tint/ir/convert.h"
+#include "src/tint/ir/discard.h"
+#include "src/tint/ir/function_terminator.h"
#include "src/tint/ir/if.h"
#include "src/tint/ir/loop.h"
+#include "src/tint/ir/root_terminator.h"
+#include "src/tint/ir/store.h"
#include "src/tint/ir/switch.h"
-#include "src/tint/ir/terminator.h"
+#include "src/tint/ir/user_call.h"
+#include "src/tint/ir/var.h"
#include "src/tint/switch.h"
+#include "src/tint/type/type.h"
#include "src/tint/utils/scoped_assignment.h"
namespace tint::ir {
@@ -65,7 +80,8 @@
void Disassembler::EmitBlockInstructions(const Block* b) {
for (const auto* inst : b->instructions) {
Indent();
- inst->ToInstruction(out_) << std::endl;
+ EmitInstruction(inst);
+ out_ << std::endl;
}
}
@@ -92,7 +108,32 @@
[&](const ir::Function* f) {
TINT_SCOPED_ASSIGNMENT(in_function_, true);
- Indent() << "%fn" << GetIdForNode(f) << " = func " << f->name.Name() << std::endl;
+ Indent() << "%fn" << GetIdForNode(f) << " = func " << f->name.Name()
+ << "():" << f->return_type->FriendlyName();
+
+ if (f->pipeline_stage != Function::PipelineStage::kUndefined) {
+ out_ << " [@" << f->pipeline_stage;
+
+ if (f->workgroup_size) {
+ auto arr = f->workgroup_size.value();
+ out_ << " @workgroup_size(" << arr[0] << ", " << arr[1] << ", " << arr[2]
+ << ")";
+ }
+
+ if (!f->return_attributes.IsEmpty()) {
+ out_ << " ra:";
+
+ for (auto attr : f->return_attributes) {
+ out_ << " @" << attr;
+ if (attr == Function::ReturnAttribute::kLocation) {
+ out_ << "(" << f->return_location.value() << ")";
+ }
+ }
+ }
+
+ out_ << "]";
+ }
+ out_ << std::endl;
{
ScopedIndent func_indent(&indent_size_);
@@ -110,8 +151,10 @@
Indent() << "%fn" << GetIdForNode(b) << " = block" << std::endl;
EmitBlockInstructions(b);
- if (b->branch.target->Is<Terminator>()) {
+ if (b->branch.target->Is<FunctionTerminator>()) {
Indent() << "ret";
+ } else if (b->branch.target->Is<RootTerminator>()) {
+ // Nothing to do
} else {
Indent() << "branch "
<< "%fn" << GetIdForNode(b->branch.target);
@@ -122,12 +165,12 @@
if (v != b->branch.args.Front()) {
out_ << ", ";
}
- v->ToValue(out_);
+ EmitValue(v);
}
}
out_ << std::endl;
- if (!b->branch.target->Is<Terminator>()) {
+ if (!b->branch.target->Is<FunctionTerminator>()) {
out_ << std::endl;
}
@@ -135,7 +178,7 @@
},
[&](const ir::Switch* s) {
Indent() << "%fn" << GetIdForNode(s) << " = switch ";
- s->condition->ToValue(out_);
+ EmitValue(s->condition);
out_ << " [";
for (const auto& c : s->cases) {
if (&c != &s->cases.Front()) {
@@ -150,7 +193,7 @@
if (selector.IsDefault()) {
out_ << "default";
} else {
- selector.val->ToValue(out_);
+ EmitValue(selector.val);
}
}
out_ << ", %fn" << GetIdForNode(c.start.target) << ")";
@@ -173,7 +216,7 @@
if (selector.IsDefault()) {
out_ << "default";
} else {
- selector.val->ToValue(out_);
+ EmitValue(selector.val);
}
}
out_ << std::endl;
@@ -188,7 +231,7 @@
},
[&](const ir::If* i) {
Indent() << "%fn" << GetIdForNode(i) << " = if ";
- i->condition->ToValue(out_);
+ EmitValue(i->condition);
out_ << " [t: %fn" << GetIdForNode(i->true_.target) << ", f: %fn"
<< GetIdForNode(i->false_.target);
if (i->merge.target->IsConnected()) {
@@ -203,8 +246,10 @@
Indent() << "# true branch" << std::endl;
Walk(i->true_.target);
- Indent() << "# false branch" << std::endl;
- Walk(i->false_.target);
+ if (!i->false_.target->IsDead()) {
+ Indent() << "# false branch" << std::endl;
+ Walk(i->false_.target);
+ }
}
if (i->merge.target->IsConnected()) {
@@ -244,10 +289,12 @@
Walk(l->merge.target);
}
},
- [&](const ir::Terminator*) {
- if (in_function_) {
- Indent() << "func_end" << std::endl;
- }
+ [&](const ir::FunctionTerminator*) {
+ TINT_ASSERT(IR, in_function_);
+ Indent() << "func_end" << std::endl << std::endl;
+ },
+ [&](const ir::RootTerminator*) {
+ TINT_ASSERT(IR, !in_function_);
out_ << std::endl;
});
}
@@ -263,4 +310,196 @@
return out_.str();
}
+void Disassembler::EmitValue(const Value* val) {
+ tint::Switch(
+ val,
+ [&](const ir::Constant* constant) {
+ std::function<void(const constant::Value*)> emit = [&](const constant::Value* c) {
+ tint::Switch(
+ c,
+ [&](const constant::Scalar<AFloat>* scalar) {
+ out_ << scalar->ValueAs<AFloat>().value;
+ },
+ [&](const constant::Scalar<AInt>* scalar) {
+ out_ << scalar->ValueAs<AInt>().value;
+ },
+ [&](const constant::Scalar<i32>* scalar) {
+ out_ << scalar->ValueAs<i32>().value << "i";
+ },
+ [&](const constant::Scalar<u32>* scalar) {
+ out_ << scalar->ValueAs<u32>().value << "u";
+ },
+ [&](const constant::Scalar<f32>* scalar) {
+ out_ << scalar->ValueAs<f32>().value << "f";
+ },
+ [&](const constant::Scalar<f16>* scalar) {
+ out_ << scalar->ValueAs<f16>().value << "h";
+ },
+ [&](const constant::Scalar<bool>* scalar) {
+ out_ << (scalar->ValueAs<bool>() ? "true" : "false");
+ },
+ [&](const constant::Splat* splat) {
+ out_ << splat->Type()->FriendlyName() << " ";
+ emit(splat->Index(0));
+ },
+ [&](const constant::Composite* composite) {
+ out_ << composite->Type()->FriendlyName() << " ";
+ for (const auto* elem : composite->elements) {
+ if (elem != composite->elements[0]) {
+ out_ << ", ";
+ }
+ emit(elem);
+ }
+ });
+ };
+ emit(constant->value);
+ },
+ [&](const ir::Instruction* i) {
+ if (i->id == ir::Instruction::kNoID) {
+ out_ << "<no-id>";
+ } else {
+ out_ << "%" << i->id;
+ }
+ if (i->Type() != nullptr) {
+ out_ << ":" << i->Type()->FriendlyName();
+ }
+ });
+}
+
+void Disassembler::EmitInstruction(const Instruction* inst) {
+ tint::Switch(
+ inst, //
+ [&](const ir::Binary* b) { EmitBinary(b); }, [&](const ir::Unary* u) { EmitUnary(u); },
+ [&](const ir::Bitcast* b) {
+ EmitValue(b);
+ out_ << " = bitcast ";
+ EmitArgs(b);
+ },
+ [&](const ir::Discard*) { out_ << "discard"; },
+ [&](const ir::Builtin* b) {
+ EmitValue(b);
+ out_ << " = " << builtin::str(b->Func()) << " ";
+ EmitArgs(b);
+ },
+ [&](const ir::Construct* c) {
+ EmitValue(c);
+ out_ << " = construct ";
+ EmitArgs(c);
+ },
+ [&](const ir::Convert* c) {
+ EmitValue(c);
+ out_ << " = convert " << c->FromType()->FriendlyName() << ", ";
+ EmitArgs(c);
+ },
+ [&](const ir::Store* s) {
+ out_ << "store ";
+ EmitValue(s->to);
+ out_ << ", ";
+ EmitValue(s->from);
+ },
+ [&](const ir::UserCall* uc) {
+ EmitValue(uc);
+ out_ << " = call " << uc->name.Name();
+ if (uc->args.Length() > 0) {
+ out_ << ", ";
+ }
+ EmitArgs(uc);
+ },
+ [&](const ir::Var* v) {
+ EmitValue(v);
+ out_ << " = var " << v->address_space << " " << v->access;
+ });
+}
+
+void Disassembler::EmitArgs(const Call* call) {
+ bool first = true;
+ for (const auto* arg : call->args) {
+ if (!first) {
+ out_ << ", ";
+ }
+ first = false;
+ EmitValue(arg);
+ }
+}
+
+void Disassembler::EmitBinary(const Binary* b) {
+ EmitValue(b);
+ out_ << " = ";
+ switch (b->GetKind()) {
+ case Binary::Kind::kAdd:
+ out_ << "add";
+ break;
+ case Binary::Kind::kSubtract:
+ out_ << "sub";
+ break;
+ case Binary::Kind::kMultiply:
+ out_ << "mul";
+ break;
+ case Binary::Kind::kDivide:
+ out_ << "div";
+ break;
+ case Binary::Kind::kModulo:
+ out_ << "mod";
+ break;
+ case Binary::Kind::kAnd:
+ out_ << "and";
+ break;
+ case Binary::Kind::kOr:
+ out_ << "or";
+ break;
+ case Binary::Kind::kXor:
+ out_ << "xor";
+ break;
+ case Binary::Kind::kEqual:
+ out_ << "eq";
+ break;
+ case Binary::Kind::kNotEqual:
+ out_ << "neq";
+ break;
+ case Binary::Kind::kLessThan:
+ out_ << "lt";
+ break;
+ case Binary::Kind::kGreaterThan:
+ out_ << "gt";
+ break;
+ case Binary::Kind::kLessThanEqual:
+ out_ << "lte";
+ break;
+ case Binary::Kind::kGreaterThanEqual:
+ out_ << "gte";
+ break;
+ case Binary::Kind::kShiftLeft:
+ out_ << "shiftl";
+ break;
+ case Binary::Kind::kShiftRight:
+ out_ << "shiftr";
+ break;
+ }
+ out_ << " ";
+ EmitValue(b->LHS());
+ out_ << ", ";
+ EmitValue(b->RHS());
+}
+
+void Disassembler::EmitUnary(const Unary* u) {
+ EmitValue(u);
+ out_ << " = ";
+ switch (u->GetKind()) {
+ case Unary::Kind::kAddressOf:
+ out_ << "addr_of";
+ break;
+ case Unary::Kind::kComplement:
+ out_ << "complement";
+ break;
+ case Unary::Kind::kIndirection:
+ out_ << "indirection";
+ break;
+ case Unary::Kind::kNegation:
+ out_ << "negation";
+ break;
+ }
+ out_ << " ";
+ EmitValue(u->Val());
+}
+
} // namespace tint::ir
diff --git a/src/tint/ir/disassembler.h b/src/tint/ir/disassembler.h
index 04b3997..d9182d3 100644
--- a/src/tint/ir/disassembler.h
+++ b/src/tint/ir/disassembler.h
@@ -19,8 +19,11 @@
#include <unordered_map>
#include <unordered_set>
+#include "src/tint/ir/binary.h"
+#include "src/tint/ir/call.h"
#include "src/tint/ir/flow_node.h"
#include "src/tint/ir/module.h"
+#include "src/tint/ir/unary.h"
#include "src/tint/utils/string_stream.h"
namespace tint::ir {
@@ -46,9 +49,15 @@
private:
utils::StringStream& Indent();
- void Walk(const FlowNode* node);
size_t GetIdForNode(const FlowNode* node);
+ void Walk(const FlowNode* node);
+ void EmitInstruction(const Instruction* inst);
+ void EmitValue(const Value* val);
+ void EmitArgs(const Call* call);
+ void EmitBinary(const Binary* b);
+ void EmitUnary(const Unary* b);
+
const Module& mod_;
utils::StringStream out_;
std::unordered_set<const FlowNode*> visited_;
diff --git a/src/tint/ir/discard.cc b/src/tint/ir/discard.cc
index bc7bdc3..6c7ded7 100644
--- a/src/tint/ir/discard.cc
+++ b/src/tint/ir/discard.cc
@@ -19,13 +19,8 @@
namespace tint::ir {
-Discard::Discard() : Base() {}
+Discard::Discard() : Base(kNoID, nullptr, utils::Empty) {}
Discard::~Discard() = default;
-utils::StringStream& Discard::ToInstruction(utils::StringStream& out) const {
- out << "discard";
- return out;
-}
-
} // namespace tint::ir
diff --git a/src/tint/ir/discard.h b/src/tint/ir/discard.h
index 456c8d5..2789e57 100644
--- a/src/tint/ir/discard.h
+++ b/src/tint/ir/discard.h
@@ -18,7 +18,6 @@
#include "src/tint/debug.h"
#include "src/tint/ir/call.h"
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
@@ -33,11 +32,6 @@
Discard& operator=(const Discard& inst) = delete;
Discard& operator=(Discard&& inst) = delete;
-
- /// Write the instruction to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- utils::StringStream& ToInstruction(utils::StringStream& out) const override;
};
} // namespace tint::ir
diff --git a/src/tint/ir/discard_test.cc b/src/tint/ir/discard_test.cc
index 32b5c1e..b1bf8c2 100644
--- a/src/tint/ir/discard_test.cc
+++ b/src/tint/ir/discard_test.cc
@@ -14,7 +14,6 @@
#include "src/tint/ir/instruction.h"
#include "src/tint/ir/test_helper.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
namespace {
@@ -26,10 +25,6 @@
const auto* inst = b.builder.Discard();
ASSERT_TRUE(inst->Is<ir::Discard>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "discard");
}
} // namespace
diff --git a/src/tint/ir/converter.cc b/src/tint/ir/from_program.cc
similarity index 75%
rename from src/tint/ir/converter.cc
rename to src/tint/ir/from_program.cc
index e89be3a..d093103 100644
--- a/src/tint/ir/converter.cc
+++ b/src/tint/ir/from_program.cc
@@ -12,17 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "src/tint/ir/converter.h"
+#include "src/tint/ir/from_program.h"
#include "src/tint/ir/builder_impl.h"
#include "src/tint/program.h"
namespace tint::ir {
-// static
-Converter::Result Converter::FromProgram(const Program* program) {
+utils::Result<Module, std::string> FromProgram(const Program* program) {
if (!program->IsValid()) {
- return Result{std::string("input program is not valid")};
+ return std::string("input program is not valid");
}
BuilderImpl b(program);
@@ -31,12 +30,7 @@
return b.Diagnostics().str();
}
- return Result{r.Move()};
-}
-
-// static
-const Program* Converter::ToProgram() {
- return nullptr;
+ return r.Move();
}
} // namespace tint::ir
diff --git a/src/tint/ir/from_program.h b/src/tint/ir/from_program.h
new file mode 100644
index 0000000..1853a9e
--- /dev/null
+++ b/src/tint/ir/from_program.h
@@ -0,0 +1,42 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_IR_FROM_PROGRAM_H_
+#define SRC_TINT_IR_FROM_PROGRAM_H_
+
+#include <string>
+
+#include "src/tint/ir/module.h"
+#include "src/tint/utils/result.h"
+
+// Forward Declarations
+namespace tint {
+class Program;
+} // namespace tint
+
+namespace tint::ir {
+
+/// Builds an ir::Module from the given Program
+/// @param program the Program to use.
+/// @returns the `utiils::Result` of generating the IR. The result will contain the `ir::Module` on
+/// success, otherwise the `std::string` error.
+///
+/// @note this assumes the `program.IsValid()`, and has had const-eval done so
+/// any abstract values have been calculated and converted into the relevant
+/// concrete types.
+utils::Result<Module, std::string> FromProgram(const Program* program);
+
+} // namespace tint::ir
+
+#endif // SRC_TINT_IR_FROM_PROGRAM_H_
diff --git a/src/tint/ir/function.cc b/src/tint/ir/function.cc
index 167664a..a03812e 100644
--- a/src/tint/ir/function.cc
+++ b/src/tint/ir/function.cc
@@ -22,4 +22,36 @@
Function::~Function() = default;
+utils::StringStream& operator<<(utils::StringStream& out, Function::PipelineStage value) {
+ switch (value) {
+ case Function::PipelineStage::kVertex:
+ return out << "vertex";
+ case Function::PipelineStage::kFragment:
+ return out << "fragment";
+ case Function::PipelineStage::kCompute:
+ return out << "compute";
+ default:
+ break;
+ }
+ return out << "<unknown>";
+}
+
+utils::StringStream& operator<<(utils::StringStream& out, Function::ReturnAttribute value) {
+ switch (value) {
+ case Function::ReturnAttribute::kLocation:
+ return out << "location";
+ case Function::ReturnAttribute::kFragDepth:
+ return out << "frag_depth";
+ case Function::ReturnAttribute::kSampleMask:
+ return out << "sample_mask";
+ case Function::ReturnAttribute::kPosition:
+ return out << "position";
+ case Function::ReturnAttribute::kInvariant:
+ return out << "invariant";
+ default:
+ break;
+ }
+ return out << "<unknown>";
+}
+
} // namespace tint::ir
diff --git a/src/tint/ir/function.h b/src/tint/ir/function.h
index ab3c6eb..e3d5529 100644
--- a/src/tint/ir/function.h
+++ b/src/tint/ir/function.h
@@ -15,13 +15,17 @@
#ifndef SRC_TINT_IR_FUNCTION_H_
#define SRC_TINT_IR_FUNCTION_H_
+#include <array>
+#include <optional>
+
#include "src/tint/ir/flow_node.h"
#include "src/tint/symbol.h"
+#include "src/tint/type/type.h"
// Forward declarations
namespace tint::ir {
class Block;
-class Terminator;
+class FunctionTerminator;
} // namespace tint::ir
namespace tint::ir {
@@ -29,6 +33,34 @@
/// An IR representation of a function
class Function : public utils::Castable<Function, FlowNode> {
public:
+ /// The pipeline stage for an entry point
+ enum class PipelineStage {
+ /// Not a pipeline entry point
+ kUndefined,
+ /// Vertex
+ kCompute,
+ /// Fragment
+ kFragment,
+ /// Vertex
+ kVertex,
+ };
+
+ /// Attributes attached to return types
+ enum class ReturnAttribute {
+ /// No return attribute
+ kNone,
+ /// Location attribute
+ kLocation,
+ /// Builtin Position attribute
+ kPosition,
+ /// Builtin FragDepth attribute
+ kFragDepth,
+ /// Builtin SampleMask
+ kSampleMask,
+ /// Invariant attribute
+ kInvariant,
+ };
+
/// Constructor
Function();
~Function() override;
@@ -36,13 +68,29 @@
/// The function name
Symbol name;
+ /// The pipeline stage for the function, `kUndefined` if the function is not an entry point
+ PipelineStage pipeline_stage = PipelineStage::kUndefined;
+
+ /// If this is a `compute` entry point, holds the workgroup size information
+ std::optional<std::array<uint32_t, 3>> workgroup_size;
+
+ /// The function return type
+ const type::Type* return_type = nullptr;
+ /// The function return attributes if any
+ utils::Vector<ReturnAttribute, 1> return_attributes;
+ /// If the return attribute is `kLocation` this stores the location value.
+ std::optional<uint32_t> return_location;
+
/// The start target is the first block in a function.
Block* start_target = nullptr;
/// The end target is the end of the function. It is used as the branch target if a return is
/// encountered in the function.
- Terminator* end_target = nullptr;
+ FunctionTerminator* end_target = nullptr;
};
+utils::StringStream& operator<<(utils::StringStream& out, Function::PipelineStage value);
+utils::StringStream& operator<<(utils::StringStream& out, Function::ReturnAttribute value);
+
} // namespace tint::ir
#endif // SRC_TINT_IR_FUNCTION_H_
diff --git a/src/tint/ir/terminator.cc b/src/tint/ir/function_terminator.cc
similarity index 75%
copy from src/tint/ir/terminator.cc
copy to src/tint/ir/function_terminator.cc
index 6d7678d..5989311 100644
--- a/src/tint/ir/terminator.cc
+++ b/src/tint/ir/function_terminator.cc
@@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "src/tint/ir/terminator.h"
+#include "src/tint/ir/function_terminator.h"
-TINT_INSTANTIATE_TYPEINFO(tint::ir::Terminator);
+TINT_INSTANTIATE_TYPEINFO(tint::ir::FunctionTerminator);
namespace tint::ir {
-Terminator::Terminator() : Base() {}
+FunctionTerminator::FunctionTerminator() : Base() {}
-Terminator::~Terminator() = default;
+FunctionTerminator::~FunctionTerminator() = default;
} // namespace tint::ir
diff --git a/src/tint/ir/terminator.h b/src/tint/ir/function_terminator.h
similarity index 76%
copy from src/tint/ir/terminator.h
copy to src/tint/ir/function_terminator.h
index 35fbcee..668eab6 100644
--- a/src/tint/ir/terminator.h
+++ b/src/tint/ir/function_terminator.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef SRC_TINT_IR_TERMINATOR_H_
-#define SRC_TINT_IR_TERMINATOR_H_
+#ifndef SRC_TINT_IR_FUNCTION_TERMINATOR_H_
+#define SRC_TINT_IR_FUNCTION_TERMINATOR_H_
#include "src/tint/ir/flow_node.h"
@@ -21,13 +21,13 @@
/// Flow node used as the end of a function. Must only be used as the `end_target` in a function
/// flow node. There are no instructions and no branches from this node.
-class Terminator : public utils::Castable<Terminator, FlowNode> {
+class FunctionTerminator : public utils::Castable<FunctionTerminator, FlowNode> {
public:
/// Constructor
- Terminator();
- ~Terminator() override;
+ FunctionTerminator();
+ ~FunctionTerminator() override;
};
} // namespace tint::ir
-#endif // SRC_TINT_IR_TERMINATOR_H_
+#endif // SRC_TINT_IR_FUNCTION_TERMINATOR_H_
diff --git a/src/tint/ir/instruction.cc b/src/tint/ir/instruction.cc
index 3e3192f..0cf4966 100644
--- a/src/tint/ir/instruction.cc
+++ b/src/tint/ir/instruction.cc
@@ -20,7 +20,7 @@
Instruction::Instruction() = default;
-Instruction::Instruction(uint32_t id, const type::Type* ty) : id_(id), type_(ty) {}
+Instruction::Instruction(uint32_t identifier, const type::Type* ty) : id(identifier), type(ty) {}
Instruction::~Instruction() = default;
diff --git a/src/tint/ir/instruction.h b/src/tint/ir/instruction.h
index f2dac09..1d4cafb 100644
--- a/src/tint/ir/instruction.h
+++ b/src/tint/ir/instruction.h
@@ -17,13 +17,15 @@
#include "src/tint/ir/value.h"
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
/// An instruction in the IR.
class Instruction : public utils::Castable<Instruction, Value> {
public:
+ /// The identifier used by instructions that have no value.
+ static constexpr uint32_t kNoID = 0;
+
Instruction(const Instruction& inst) = delete;
Instruction(Instruction&& inst) = delete;
/// Destructor
@@ -33,23 +35,13 @@
Instruction& operator=(Instruction&& inst) = delete;
/// @returns the type of the value
- const type::Type* Type() const override { return type_; }
+ const type::Type* Type() const override { return type; }
- /// Write the value to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- utils::StringStream& ToValue(utils::StringStream& out) const override {
- out << "%" << std::to_string(id_);
- if (type_ != nullptr) {
- out << "(" << Type()->FriendlyName() << ")";
- }
- return out;
- }
+ /// The instruction identifier
+ const uint32_t id = kNoID;
- /// Write the instruction to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- virtual utils::StringStream& ToInstruction(utils::StringStream& out) const = 0;
+ /// The instruction type
+ const type::Type* type = nullptr;
protected:
/// Constructor
@@ -58,10 +50,6 @@
/// @param id the instruction id
/// @param type the result type
Instruction(uint32_t id, const type::Type* type);
-
- private:
- uint32_t id_ = 0;
- const type::Type* type_ = nullptr;
};
} // namespace tint::ir
diff --git a/src/tint/ir/terminator.cc b/src/tint/ir/root_terminator.cc
similarity index 77%
rename from src/tint/ir/terminator.cc
rename to src/tint/ir/root_terminator.cc
index 6d7678d..bfccf46 100644
--- a/src/tint/ir/terminator.cc
+++ b/src/tint/ir/root_terminator.cc
@@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "src/tint/ir/terminator.h"
+#include "src/tint/ir/root_terminator.h"
-TINT_INSTANTIATE_TYPEINFO(tint::ir::Terminator);
+TINT_INSTANTIATE_TYPEINFO(tint::ir::RootTerminator);
namespace tint::ir {
-Terminator::Terminator() : Base() {}
+RootTerminator::RootTerminator() : Base() {}
-Terminator::~Terminator() = default;
+RootTerminator::~RootTerminator() = default;
} // namespace tint::ir
diff --git a/src/tint/ir/terminator.h b/src/tint/ir/root_terminator.h
similarity index 78%
rename from src/tint/ir/terminator.h
rename to src/tint/ir/root_terminator.h
index 35fbcee..361aa6d 100644
--- a/src/tint/ir/terminator.h
+++ b/src/tint/ir/root_terminator.h
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef SRC_TINT_IR_TERMINATOR_H_
-#define SRC_TINT_IR_TERMINATOR_H_
+#ifndef SRC_TINT_IR_ROOT_TERMINATOR_H_
+#define SRC_TINT_IR_ROOT_TERMINATOR_H_
#include "src/tint/ir/flow_node.h"
@@ -21,13 +21,13 @@
/// Flow node used as the end of a function. Must only be used as the `end_target` in a function
/// flow node. There are no instructions and no branches from this node.
-class Terminator : public utils::Castable<Terminator, FlowNode> {
+class RootTerminator : public utils::Castable<RootTerminator, FlowNode> {
public:
/// Constructor
- Terminator();
- ~Terminator() override;
+ RootTerminator();
+ ~RootTerminator() override;
};
} // namespace tint::ir
-#endif // SRC_TINT_IR_TERMINATOR_H_
+#endif // SRC_TINT_IR_ROOT_TERMINATOR_H_
diff --git a/src/tint/ir/store.cc b/src/tint/ir/store.cc
index 8d35214..87f3620 100644
--- a/src/tint/ir/store.cc
+++ b/src/tint/ir/store.cc
@@ -19,20 +19,13 @@
namespace tint::ir {
-Store::Store(Value* to, Value* from) : Base(), to_(to), from_(from) {
- TINT_ASSERT(IR, to_);
- TINT_ASSERT(IR, from_);
- to_->AddUsage(this);
- from_->AddUsage(this);
+Store::Store(Value* t, Value* f) : Base(), to(t), from(f) {
+ TINT_ASSERT(IR, to);
+ TINT_ASSERT(IR, from);
+ to->AddUsage(this);
+ from->AddUsage(this);
}
Store::~Store() = default;
-utils::StringStream& Store::ToInstruction(utils::StringStream& out) const {
- out << "store ";
- to_->ToValue(out) << ", ";
- from_->ToValue(out);
- return out;
-}
-
} // namespace tint::ir
diff --git a/src/tint/ir/store.h b/src/tint/ir/store.h
index ea5550d..9095c41 100644
--- a/src/tint/ir/store.h
+++ b/src/tint/ir/store.h
@@ -17,7 +17,6 @@
#include "src/tint/ir/instruction.h"
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
@@ -35,19 +34,10 @@
Store& operator=(const Store& inst) = delete;
Store& operator=(Store&& inst) = delete;
- /// @returns the value being stored too
- const Value* to() const { return to_; }
- /// @returns the value being stored
- const Value* from() const { return from_; }
-
- /// Write the instruction to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- utils::StringStream& ToInstruction(utils::StringStream& out) const override;
-
- private:
- Value* to_ = nullptr;
- Value* from_ = nullptr;
+ /// the value being stored to
+ Value* to = nullptr;
+ /// the value being stored
+ Value* from = nullptr;
};
} // namespace tint::ir
diff --git a/src/tint/ir/store_test.cc b/src/tint/ir/store_test.cc
index 82347dc..0005c80 100644
--- a/src/tint/ir/store_test.cc
+++ b/src/tint/ir/store_test.cc
@@ -14,7 +14,6 @@
#include "src/tint/ir/instruction.h"
#include "src/tint/ir/test_helper.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
namespace {
@@ -32,16 +31,12 @@
const auto* inst = b.builder.Store(to, b.builder.Constant(4_i));
ASSERT_TRUE(inst->Is<Store>());
- ASSERT_EQ(inst->to(), to);
+ ASSERT_EQ(inst->to, to);
- ASSERT_TRUE(inst->from()->Is<Constant>());
- auto lhs = inst->from()->As<Constant>()->value;
+ ASSERT_TRUE(inst->from->Is<Constant>());
+ auto lhs = inst->from->As<Constant>()->value;
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "store %0, 4i");
}
TEST_F(IR_InstructionTest, Store_Usage) {
@@ -50,13 +45,13 @@
auto* to = b.builder.Discard();
const auto* inst = b.builder.Store(to, b.builder.Constant(4_i));
- ASSERT_NE(inst->to(), nullptr);
- ASSERT_EQ(inst->to()->Usage().Length(), 1u);
- EXPECT_EQ(inst->to()->Usage()[0], inst);
+ ASSERT_NE(inst->to, nullptr);
+ ASSERT_EQ(inst->to->Usage().Length(), 1u);
+ EXPECT_EQ(inst->to->Usage()[0], inst);
- ASSERT_NE(inst->from(), nullptr);
- ASSERT_EQ(inst->from()->Usage().Length(), 1u);
- EXPECT_EQ(inst->from()->Usage()[0], inst);
+ ASSERT_NE(inst->from, nullptr);
+ ASSERT_EQ(inst->from->Usage().Length(), 1u);
+ EXPECT_EQ(inst->from->Usage()[0], inst);
}
} // namespace
diff --git a/src/tint/ir/test_helper.h b/src/tint/ir/test_helper.h
index 47f8821..d8568c2 100644
--- a/src/tint/ir/test_helper.h
+++ b/src/tint/ir/test_helper.h
@@ -24,6 +24,7 @@
#include "src/tint/ir/disassembler.h"
#include "src/tint/number.h"
#include "src/tint/program_builder.h"
+#include "src/tint/utils/string_stream.h"
namespace tint::ir {
diff --git a/src/tint/ir/unary.cc b/src/tint/ir/unary.cc
index f3c4f24..e3f20eb 100644
--- a/src/tint/ir/unary.cc
+++ b/src/tint/ir/unary.cc
@@ -19,36 +19,12 @@
namespace tint::ir {
-Unary::Unary(uint32_t id, Kind kind, const type::Type* type, Value* val)
- : Base(id, type), kind_(kind), val_(val) {
+Unary::Unary(uint32_t identifier, Kind kind, const type::Type* ty, Value* val)
+ : Base(identifier, ty), kind_(kind), val_(val) {
TINT_ASSERT(IR, val_);
val_->AddUsage(this);
}
Unary::~Unary() = default;
-utils::StringStream& Unary::ToInstruction(utils::StringStream& out) const {
- ToValue(out) << " = ";
- switch (GetKind()) {
- case Unary::Kind::kAddressOf:
- out << "addr_of";
- break;
- case Unary::Kind::kComplement:
- out << "bit_complement";
- break;
- case Unary::Kind::kIndirection:
- out << "indirection";
- break;
- case Unary::Kind::kNegation:
- out << "negation";
- break;
- case Unary::Kind::kNot:
- out << "log_not";
- break;
- }
- out << " ";
- val_->ToValue(out);
- return out;
-}
-
} // namespace tint::ir
diff --git a/src/tint/ir/unary.h b/src/tint/ir/unary.h
index ce3e5d7..64301d4 100644
--- a/src/tint/ir/unary.h
+++ b/src/tint/ir/unary.h
@@ -17,7 +17,6 @@
#include "src/tint/ir/instruction.h"
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
@@ -30,7 +29,6 @@
kComplement,
kIndirection,
kNegation,
- kNot,
};
/// Constructor
@@ -52,11 +50,6 @@
/// @returns the value for the instruction
const Value* Val() const { return val_; }
- /// Write the instruction to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- utils::StringStream& ToInstruction(utils::StringStream& out) const override;
-
private:
Kind kind_;
Value* val_ = nullptr;
diff --git a/src/tint/ir/unary_test.cc b/src/tint/ir/unary_test.cc
index ff247a2..e205d8f 100644
--- a/src/tint/ir/unary_test.cc
+++ b/src/tint/ir/unary_test.cc
@@ -14,7 +14,6 @@
#include "src/tint/ir/instruction.h"
#include "src/tint/ir/test_helper.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
namespace {
@@ -42,10 +41,6 @@
auto lhs = inst->Val()->As<Constant>()->value;
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(ptr<private, i32, read_write>) = addr_of 4i");
}
TEST_F(IR_InstructionTest, CreateComplement) {
@@ -60,10 +55,6 @@
auto lhs = inst->Val()->As<Constant>()->value;
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = bit_complement 4i");
}
TEST_F(IR_InstructionTest, CreateIndirection) {
@@ -80,10 +71,6 @@
auto lhs = inst->Val()->As<Constant>()->value;
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = indirection 4i");
}
TEST_F(IR_InstructionTest, CreateNegation) {
@@ -98,28 +85,6 @@
auto lhs = inst->Val()->As<Constant>()->value;
ASSERT_TRUE(lhs->Is<constant::Scalar<i32>>());
EXPECT_EQ(4_i, lhs->As<constant::Scalar<i32>>()->ValueAs<i32>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(i32) = negation 4i");
-}
-
-TEST_F(IR_InstructionTest, CreateNot) {
- auto& b = CreateEmptyBuilder();
- const auto* inst =
- b.builder.Not(b.builder.ir.types.Get<type::Bool>(), b.builder.Constant(true));
-
- ASSERT_TRUE(inst->Is<Unary>());
- EXPECT_EQ(inst->GetKind(), Unary::Kind::kNot);
-
- ASSERT_TRUE(inst->Val()->Is<Constant>());
- auto lhs = inst->Val()->As<Constant>()->value;
- ASSERT_TRUE(lhs->Is<constant::Scalar<bool>>());
- EXPECT_TRUE(lhs->As<constant::Scalar<bool>>()->ValueAs<bool>());
-
- utils::StringStream str;
- inst->ToInstruction(str);
- EXPECT_EQ(str.str(), "%1(bool) = log_not true");
}
TEST_F(IR_InstructionTest, Unary_Usage) {
diff --git a/src/tint/ir/user_call.cc b/src/tint/ir/user_call.cc
index f23a2ca..e7e2e26 100644
--- a/src/tint/ir/user_call.cc
+++ b/src/tint/ir/user_call.cc
@@ -13,24 +13,21 @@
// limitations under the License.
#include "src/tint/ir/user_call.h"
+
+#include <utility>
+
#include "src/tint/debug.h"
TINT_INSTANTIATE_TYPEINFO(tint::ir::UserCall);
namespace tint::ir {
-UserCall::UserCall(uint32_t id, const type::Type* type, Symbol name, utils::VectorRef<Value*> args)
- : Base(id, type, args), name_(name) {}
+UserCall::UserCall(uint32_t identifier,
+ const type::Type* ty,
+ Symbol n,
+ utils::VectorRef<Value*> arguments)
+ : Base(identifier, ty, std::move(arguments)), name(n) {}
UserCall::~UserCall() = default;
-utils::StringStream& UserCall::ToInstruction(utils::StringStream& out) const {
- ToValue(out) << " = call " << name_.Name();
- if (Args().Length() > 0) {
- out << ", ";
- }
- EmitArgs(out);
- return out;
-}
-
} // namespace tint::ir
diff --git a/src/tint/ir/user_call.h b/src/tint/ir/user_call.h
index 1e2b070..1edfa8b 100644
--- a/src/tint/ir/user_call.h
+++ b/src/tint/ir/user_call.h
@@ -18,7 +18,6 @@
#include "src/tint/ir/call.h"
#include "src/tint/symbol.h"
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
@@ -38,16 +37,8 @@
UserCall& operator=(const UserCall& inst) = delete;
UserCall& operator=(UserCall&& inst) = delete;
- /// @returns the function name
- Symbol Name() const { return name_; }
-
- /// Write the instruction to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- utils::StringStream& ToInstruction(utils::StringStream& out) const override;
-
- private:
- Symbol name_{};
+ /// The function name
+ Symbol name;
};
} // namespace tint::ir
diff --git a/src/tint/ir/value.h b/src/tint/ir/value.h
index 7f3f4b7..e91e4c4 100644
--- a/src/tint/ir/value.h
+++ b/src/tint/ir/value.h
@@ -17,7 +17,6 @@
#include "src/tint/type/type.h"
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/string_stream.h"
#include "src/tint/utils/unique_vector.h"
// Forward declarations
@@ -50,11 +49,6 @@
/// @returns the type of the value
virtual const type::Type* Type() const = 0;
- /// Write the value to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- virtual utils::StringStream& ToValue(utils::StringStream& out) const = 0;
-
protected:
/// Constructor
Value();
diff --git a/src/tint/ir/var.cc b/src/tint/ir/var.cc
index 740a35e..b7ede1d 100644
--- a/src/tint/ir/var.cc
+++ b/src/tint/ir/var.cc
@@ -19,17 +19,12 @@
namespace tint::ir {
-Var::Var(uint32_t id,
+Var::Var(uint32_t identifier,
const type::Type* ty,
- builtin::AddressSpace address_space,
- builtin::Access access)
- : Base(id, ty), address_space_(address_space), access_(access) {}
+ builtin::AddressSpace addr_space,
+ builtin::Access acc)
+ : Base(identifier, ty), address_space(addr_space), access(acc) {}
Var::~Var() = default;
-utils::StringStream& Var::ToInstruction(utils::StringStream& out) const {
- ToValue(out) << " = var " << address_space_ << " " << access_;
- return out;
-}
-
} // namespace tint::ir
diff --git a/src/tint/ir/var.h b/src/tint/ir/var.h
index 456e7d3..dd46f54 100644
--- a/src/tint/ir/var.h
+++ b/src/tint/ir/var.h
@@ -19,7 +19,6 @@
#include "src/tint/builtin/address_space.h"
#include "src/tint/ir/instruction.h"
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/string_stream.h"
namespace tint::ir {
@@ -42,20 +41,11 @@
Var& operator=(const Var& inst) = delete;
Var& operator=(Var&& inst) = delete;
- /// @returns the address space
- builtin::AddressSpace AddressSpace() const { return address_space_; }
+ /// The variable address space
+ builtin::AddressSpace address_space = builtin::AddressSpace::kUndefined;
- /// @returns the access mode
- builtin::Access Access() const { return access_; }
-
- /// Write the instruction to the given stream
- /// @param out the stream to write to
- /// @returns the stream
- utils::StringStream& ToInstruction(utils::StringStream& out) const override;
-
- private:
- builtin::AddressSpace address_space_;
- builtin::Access access_;
+ /// The variable access mode
+ builtin::Access access = builtin::Access::kUndefined;
};
} // namespace tint::ir
diff --git a/src/tint/program.cc b/src/tint/program.cc
index c8466f5..a1cf5c8 100644
--- a/src/tint/program.cc
+++ b/src/tint/program.cc
@@ -134,19 +134,6 @@
return Sem().Get(type_decl);
}
-std::string Program::FriendlyName(ast::Type type) const {
- TINT_ASSERT_PROGRAM_IDS_EQUAL(Program, type, ID());
- return type ? type->identifier->symbol.Name() : "<null>";
-}
-
-std::string Program::FriendlyName(const type::Type* type) const {
- return type ? type->FriendlyName() : "<null>";
-}
-
-std::string Program::FriendlyName(std::nullptr_t) const {
- return "<null>";
-}
-
void Program::AssertNotMoved() const {
TINT_ASSERT(Program, !moved_);
}
diff --git a/src/tint/program.h b/src/tint/program.h
index 1c57fe0..ae46acd 100644
--- a/src/tint/program.h
+++ b/src/tint/program.h
@@ -151,19 +151,6 @@
/// the type declaration has no resolved type.
const type::Type* TypeOf(const ast::TypeDecl* type_decl) const;
- /// @param type a type
- /// @returns the name for `type` that closely resembles how it would be declared in WGSL.
- std::string FriendlyName(ast::Type type) const;
-
- /// @param type a type
- /// @returns the name for `type` that closely resembles how it would be declared in WGSL.
- std::string FriendlyName(const type::Type* type) const;
-
- /// Overload of FriendlyName, which removes an ambiguity when passing nullptr.
- /// Simplifies test code.
- /// @returns "<null>"
- std::string FriendlyName(std::nullptr_t) const;
-
/// A function that can be used to print a program
using Printer = std::string (*)(const Program*);
diff --git a/src/tint/program_builder.cc b/src/tint/program_builder.cc
index 4181f96..fc2e795 100644
--- a/src/tint/program_builder.cc
+++ b/src/tint/program_builder.cc
@@ -113,19 +113,6 @@
return Sem().Get(type_decl);
}
-std::string ProgramBuilder::FriendlyName(ast::Type type) const {
- TINT_ASSERT_PROGRAM_IDS_EQUAL(ProgramBuilder, type, ID());
- return type.expr ? type->identifier->symbol.Name() : "<null>";
-}
-
-std::string ProgramBuilder::FriendlyName(const type::Type* type) const {
- return type ? type->FriendlyName() : "<null>";
-}
-
-std::string ProgramBuilder::FriendlyName(std::nullptr_t) const {
- return "<null>";
-}
-
ProgramBuilder::TypesBuilder::TypesBuilder(ProgramBuilder* pb) : builder(pb) {}
const ast::Statement* ProgramBuilder::WrapInStatement(const ast::Expression* expr) {
diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h
index 49b14fc..b944e21 100644
--- a/src/tint/program_builder.h
+++ b/src/tint/program_builder.h
@@ -3919,19 +3919,6 @@
/// the type declaration has no resolved type.
const type::Type* TypeOf(const ast::TypeDecl* type_decl) const;
- /// @param type a type
- /// @returns the name for `type` that closely resembles how it would be declared in WGSL.
- std::string FriendlyName(ast::Type type) const;
-
- /// @param type a type
- /// @returns the name for `type` that closely resembles how it would be declared in WGSL.
- std::string FriendlyName(const type::Type* type) const;
-
- /// Overload of FriendlyName, which removes an ambiguity when passing nullptr.
- /// Simplifies test code.
- /// @returns "<null>"
- std::string FriendlyName(std::nullptr_t) const;
-
/// Wraps the ast::Expression in a statement. This is used by tests that
/// construct a partial AST and require the Resolver to reach these
/// nodes.
diff --git a/src/tint/reader/spirv/function.cc b/src/tint/reader/spirv/function.cc
index 8061f74..c3c12f2 100644
--- a/src/tint/reader/spirv/function.cc
+++ b/src/tint/reader/spirv/function.cc
@@ -4075,6 +4075,12 @@
// All parameters to GLSL.std.450 extended instructions are IDs.
for (uint32_t iarg = 2; iarg < inst.NumInOperands(); ++iarg) {
TypedExpression operand = MakeOperand(inst, iarg);
+ if (!operand.expr) {
+ if (!failed()) {
+ Fail() << "unexpected failure to make an operand";
+ }
+ return {};
+ }
if (first_operand_type == nullptr) {
first_operand_type = operand.type;
}
@@ -5183,6 +5189,9 @@
const auto usage = parser_impl_.GetHandleUsage(arg_id);
const auto* mem_obj_decl =
parser_impl_.GetMemoryObjectDeclarationForHandle(arg_id, usage.IsTexture());
+ if (!mem_obj_decl) {
+ return Fail() << "invalid handle object passed as function parameter";
+ }
expr = MakeExpression(mem_obj_decl->result_id());
// Pass the handle through instead of a pointer to the handle.
expr.type = parser_impl_.GetHandleTypeForSpirvHandle(*mem_obj_decl);
diff --git a/src/tint/reader/spirv/parser_impl.cc b/src/tint/reader/spirv/parser_impl.cc
index 6f6bf1e..220ccb9 100644
--- a/src/tint/reader/spirv/parser_impl.cc
+++ b/src/tint/reader/spirv/parser_impl.cc
@@ -1891,8 +1891,6 @@
}
auto source = GetSourceForInst(inst);
- // TODO(dneto): Handle spec constants too?
-
auto* original_ast_type = ConvertType(inst->type_id());
if (original_ast_type == nullptr) {
return {};
@@ -1952,6 +1950,12 @@
declared_constant_composites_.insert({id, decl->name->symbol});
return {original_ast_type, builder_.Expr(name)};
}
+ case spv::Op::OpSpecConstantComposite:
+ case spv::Op::OpSpecConstantOp: {
+ // TODO(crbug.com/tint/111): Handle OpSpecConstantOp and OpSpecConstantComposite here.
+ Fail() << "unimplemented: OpSpecConstantOp and OpSpecConstantComposite";
+ return {};
+ }
default:
break;
}
diff --git a/src/tint/reader/spirv/parser_impl_handle_test.cc b/src/tint/reader/spirv/parser_impl_handle_test.cc
index dd572b6..15a62a6 100644
--- a/src/tint/reader/spirv/parser_impl_handle_test.cc
+++ b/src/tint/reader/spirv/parser_impl_handle_test.cc
@@ -4236,5 +4236,30 @@
ASSERT_EQ(expect, got);
}
+TEST_F(SpvParserHandleTest, OpUndef_FunctionParam) {
+ // We can't generate reasonable WGSL when an OpUndef is passed as an argument to a function
+ // parameter that is expecting an image object, so just make sure that we do not crash.
+ const auto assembly = Preamble() + FragMain() + " " + CommonTypes() + R"(
+ %f_ty = OpTypeFunction %void %f_storage_1d
+ %20 = OpUndef %f_storage_1d
+
+ %func = OpFunction %void None %f_ty
+ %im = OpFunctionParameter %f_storage_1d
+ %func_entry = OpLabel
+ OpImageWrite %im %uint_1 %v4float_null
+ OpReturn
+ OpFunctionEnd
+
+ %main = OpFunction %void None %voidfn
+ %entry = OpLabel
+ %foo = OpFunctionCall %void %func %20
+ OpReturn
+ OpFunctionEnd
+ )";
+ auto p = parser(test::Assemble(assembly));
+ EXPECT_FALSE(p->BuildAndParseInternalModule());
+ EXPECT_EQ(p->error(), "invalid handle object passed as function parameter");
+}
+
} // namespace
} // namespace tint::reader::spirv
diff --git a/src/tint/resolver/builtin_structs.cc b/src/tint/resolver/builtin_structs.cc
index 4e45c16..2b8c117 100644
--- a/src/tint/resolver/builtin_structs.cc
+++ b/src/tint/resolver/builtin_structs.cc
@@ -128,12 +128,12 @@
},
[&](Default) {
TINT_ICE(Resolver, b.Diagnostics())
- << "unhandled modf type: " << b.FriendlyName(ty);
+ << "unhandled modf type: " << ty->FriendlyName();
return nullptr;
});
},
[&](Default) {
- TINT_ICE(Resolver, b.Diagnostics()) << "unhandled modf type: " << b.FriendlyName(ty);
+ TINT_ICE(Resolver, b.Diagnostics()) << "unhandled modf type: " << ty->FriendlyName();
return nullptr;
});
}
@@ -208,12 +208,12 @@
},
[&](Default) {
TINT_ICE(Resolver, b.Diagnostics())
- << "unhandled frexp type: " << b.FriendlyName(ty);
+ << "unhandled frexp type: " << ty->FriendlyName();
return nullptr;
});
},
[&](Default) {
- TINT_ICE(Resolver, b.Diagnostics()) << "unhandled frexp type: " << b.FriendlyName(ty);
+ TINT_ICE(Resolver, b.Diagnostics()) << "unhandled frexp type: " << ty->FriendlyName();
return nullptr;
});
}
@@ -231,7 +231,7 @@
},
[&](Default) {
TINT_ICE(Resolver, b.Diagnostics())
- << "unhandled atomic_compare_exchange type: " << b.FriendlyName(ty);
+ << "unhandled atomic_compare_exchange type: " << ty->FriendlyName();
return nullptr;
});
}
diff --git a/src/tint/resolver/const_eval.cc b/src/tint/resolver/const_eval.cc
index 2aa755a..35ea8bb 100644
--- a/src/tint/resolver/const_eval.cc
+++ b/src/tint/resolver/const_eval.cc
@@ -271,7 +271,7 @@
// --- Below this point are the failure cases ---
} else if constexpr (IsAbstract<FROM>) {
// [abstract-numeric -> x] - materialization failure
- auto msg = OverflowErrorMessage(scalar->value, builder.FriendlyName(target_ty));
+ auto msg = OverflowErrorMessage(scalar->value, target_ty->FriendlyName());
if (use_runtime_semantics) {
builder.Diagnostics().add_warning(tint::diag::System::Resolver, msg, source);
switch (conv.Failure()) {
@@ -287,7 +287,7 @@
} else if constexpr (IsFloatingPoint<TO>) {
// [x -> floating-point] - number not exactly representable
// https://www.w3.org/TR/WGSL/#floating-point-conversion
- auto msg = OverflowErrorMessage(scalar->value, builder.FriendlyName(target_ty));
+ auto msg = OverflowErrorMessage(scalar->value, target_ty->FriendlyName());
if (use_runtime_semantics) {
builder.Diagnostics().add_warning(tint::diag::System::Resolver, msg, source);
switch (conv.Failure()) {
@@ -534,7 +534,7 @@
if constexpr (IsFloatingPoint<T>) {
if (!std::isfinite(v.value)) {
- AddError(OverflowErrorMessage(v, builder.FriendlyName(t)), source);
+ AddError(OverflowErrorMessage(v, t->FriendlyName()), source);
if (use_runtime_semantics_) {
return ZeroValue(t);
} else {
@@ -2689,7 +2689,7 @@
[&](Default) {
TINT_ICE(Resolver, builder.Diagnostics())
<< "unhandled element type for frexp() const-eval: "
- << builder.FriendlyName(s->Type());
+ << s->Type()->FriendlyName();
return FractExp{utils::Failure, utils::Failure};
});
};
@@ -3318,7 +3318,7 @@
return utils::Failure;
}
auto e2_scaled = Mul(source, ty, e2_scale.Get(), e2);
- if (!e1_scaled) {
+ if (!e2_scaled) {
return utils::Failure;
}
return Sub(source, ty, e1_scaled.Get(), e2_scaled.Get());
diff --git a/src/tint/resolver/const_eval_builtin_test.cc b/src/tint/resolver/const_eval_builtin_test.cc
index 7aecfac..a172ca3 100644
--- a/src/tint/resolver/const_eval_builtin_test.cc
+++ b/src/tint/resolver/const_eval_builtin_test.cc
@@ -2288,6 +2288,14 @@
// Overflow the k^2 operation
E({down_right, pos_y, Val(T::Highest())}, error_msg(T::Highest(), "*", T::Highest())),
});
+ ConcatIntoIf<std::is_same_v<T, f32>>( //
+ r, std::vector<Case>{
+ // Overflow the final multiply by e2 operation
+ // From https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58526
+ E({Vec(T(-2.22218755e-15), T(0)), Vec(T(-198225753253481323832809619456.0), T(0)),
+ Val(T(40.0313720703125))},
+ error_msg(T(35267222007971840.0), "*", T(-198225753253481323832809619456.0))),
+ });
return r;
}
diff --git a/src/tint/resolver/materialize_test.cc b/src/tint/resolver/materialize_test.cc
index 94d916c..696f279 100644
--- a/src/tint/resolver/materialize_test.cc
+++ b/src/tint/resolver/materialize_test.cc
@@ -75,8 +75,6 @@
template <typename CASE>
class MaterializeTest : public resolver::ResolverTestWithParam<CASE> {
protected:
- using ProgramBuilder::FriendlyName;
-
void CheckTypesAndValues(const sem::ValueExpression* expr,
const tint::type::Type* expected_sem_ty,
const std::variant<AInt, AFloat>& expected_value) {
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index de29692..a65d825 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -921,9 +921,8 @@
}
auto* cond = expr->ConstantValue();
if (auto* ty = cond->Type(); !ty->Is<type::Bool>()) {
- AddError(
- "const assertion condition must be a bool, got '" + builder_->FriendlyName(ty) + "'",
- assertion->condition->source);
+ AddError("const assertion condition must be a bool, got '" + ty->FriendlyName() + "'",
+ assertion->condition->source);
return nullptr;
}
if (!cond->ValueAs<bool>()) {
@@ -1833,8 +1832,8 @@
materialized_val = val.Get();
if (TINT_UNLIKELY(!materialized_val)) {
TINT_ICE(Resolver, diagnostics_)
- << decl->source << "ConvertValue(" << builder_->FriendlyName(expr_val->Type())
- << " -> " << builder_->FriendlyName(concrete_ty) << ") returned invalid value";
+ << decl->source << "ConvertValue(" << expr_val->Type()->FriendlyName() << " -> "
+ << concrete_ty->FriendlyName() << ") returned invalid value";
return nullptr;
}
}
@@ -2590,7 +2589,7 @@
}
if (!ApplyAddressSpaceUsageToType(address_space, store_ty,
store_ty_expr->Declaration()->source)) {
- AddNote("while instantiating " + builder_->FriendlyName(out), ident->source);
+ AddNote("while instantiating " + out->FriendlyName(), ident->source);
return nullptr;
}
return out;
@@ -3837,7 +3836,7 @@
if (auto* ty = count_val->Type(); !ty->is_integer_scalar()) {
AddError("array count must evaluate to a constant integer expression, but is type '" +
- builder_->FriendlyName(ty) + "'",
+ ty->FriendlyName() + "'",
count_expr->source);
return nullptr;
}
diff --git a/src/tint/transform/builtin_polyfill.cc b/src/tint/transform/builtin_polyfill.cc
index 9cbb65f..4014b21 100644
--- a/src/tint/transform/builtin_polyfill.cc
+++ b/src/tint/transform/builtin_polyfill.cc
@@ -593,7 +593,7 @@
if (TINT_UNLIKELY(((!type::Type::DeepestElementOf(ty)->IsAnyOf<type::I32, type::U32>())))) {
TINT_ICE(Transform, b.Diagnostics())
<< "insertBits polyfill only support i32, u32, and vector of i32 or u32, got "
- << b.FriendlyName(ty);
+ << ty->FriendlyName();
return {};
}
diff --git a/src/tint/transform/builtin_polyfill_test.cc b/src/tint/transform/builtin_polyfill_test.cc
index 65c1f29..ad47af6 100644
--- a/src/tint/transform/builtin_polyfill_test.cc
+++ b/src/tint/transform/builtin_polyfill_test.cc
@@ -16,6 +16,7 @@
#include <utility>
+#include "src/tint/transform/direct_variable_access.h"
#include "src/tint/transform/test_helper.h"
namespace tint::transform {
@@ -3673,8 +3674,23 @@
DataMap polyfillWorkgroupUniformLoad() {
BuiltinPolyfill::Builtins builtins;
builtins.workgroup_uniform_load = true;
+
DataMap data;
data.Add<BuiltinPolyfill::Config>(builtins);
+
+ return data;
+}
+
+DataMap polyfillWorkgroupUniformLoadWithDirectVariableAccess() {
+ DataMap data;
+
+ BuiltinPolyfill::Builtins builtins;
+ builtins.workgroup_uniform_load = true;
+ data.Add<BuiltinPolyfill::Config>(builtins);
+
+ DirectVariableAccess::Options options;
+ data.Add<DirectVariableAccess::Config>(options);
+
return data;
}
@@ -3830,6 +3846,50 @@
EXPECT_EQ(expect, str(got));
}
+TEST_F(BuiltinPolyfillTest, WorkgroupUniformLoad_DirectVariableAccess) {
+ auto* src = R"(
+var<workgroup> v : i32;
+var<workgroup> v2 : i32;
+
+fn f() {
+ let r = workgroupUniformLoad(&v);
+ let s = workgroupUniformLoad(&v2);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+fn tint_workgroupUniformLoad_v() -> i32 {
+ workgroupBarrier();
+ let result = v;
+ workgroupBarrier();
+ return result;
+}
+
+fn tint_workgroupUniformLoad_v2() -> i32 {
+ workgroupBarrier();
+ let result = v2;
+ workgroupBarrier();
+ return result;
+}
+
+var<workgroup> v : i32;
+
+var<workgroup> v2 : i32;
+
+fn f() {
+ let r = tint_workgroupUniformLoad_v();
+ let s = tint_workgroupUniformLoad_v2();
+}
+)";
+
+ auto got = Run<BuiltinPolyfill, DirectVariableAccess>(
+ src, polyfillWorkgroupUniformLoadWithDirectVariableAccess());
+
+ EXPECT_EQ(expect, str(got));
+}
+
////////////////////////////////////////////////////////////////////////////////
// quantizeToF16
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/tint/transform/robustness.cc b/src/tint/transform/robustness.cc
index c25bcac..3860de4 100644
--- a/src/tint/transform/robustness.cc
+++ b/src/tint/transform/robustness.cc
@@ -251,7 +251,7 @@
[&](Default) -> const ast::Expression* {
TINT_ICE(Transform, b.Diagnostics())
<< "unhandled object type in robustness of array index: "
- << src->FriendlyName(obj_type->UnwrapRef());
+ << obj_type->UnwrapRef()->FriendlyName();
return nullptr;
});
}
diff --git a/src/tint/transform/std140.cc b/src/tint/transform/std140.cc
index fa4fade..fed3943 100644
--- a/src/tint/transform/std140.cc
+++ b/src/tint/transform/std140.cc
@@ -414,7 +414,7 @@
auto std140_mat = std140_mats.GetOrCreate(mat, [&] {
auto name = b.Symbols().New("mat" + std::to_string(mat->columns()) + "x" +
std::to_string(mat->rows()) + "_" +
- src->FriendlyName(mat->type()));
+ mat->type()->FriendlyName());
auto members =
DecomposedMatrixStructMembers(mat, "col", mat->Align(), mat->Size());
b.Structure(name, members);
@@ -652,7 +652,7 @@
[&](const type::F16*) { return "f16"; },
[&](Default) {
TINT_ICE(Transform, b.Diagnostics())
- << "unhandled type for conversion name: " << src->FriendlyName(ty);
+ << "unhandled type for conversion name: " << ty->FriendlyName();
return "";
});
}
@@ -728,7 +728,7 @@
stmts.Push(b.Return(b.Call(mat_ty, std::move(mat_args))));
} else {
TINT_ICE(Transform, b.Diagnostics())
- << "failed to find std140 matrix info for: " << src->FriendlyName(ty);
+ << "failed to find std140 matrix info for: " << ty->FriendlyName();
}
}, //
[&](const type::Array* arr) {
@@ -758,7 +758,7 @@
},
[&](Default) {
TINT_ICE(Transform, b.Diagnostics())
- << "unhandled type for conversion: " << src->FriendlyName(ty);
+ << "unhandled type for conversion: " << ty->FriendlyName();
});
// Generate the function
@@ -1104,7 +1104,7 @@
}, //
[&](Default) -> ExprTypeName {
TINT_ICE(Transform, b.Diagnostics())
- << "unhandled type for access chain: " << src->FriendlyName(ty);
+ << "unhandled type for access chain: " << ty->FriendlyName();
return {};
});
}
@@ -1125,7 +1125,7 @@
}, //
[&](Default) -> ExprTypeName {
TINT_ICE(Transform, b.Diagnostics())
- << "unhandled type for access chain: " << src->FriendlyName(ty);
+ << "unhandled type for access chain: " << ty->FriendlyName();
return {};
});
}
@@ -1154,7 +1154,7 @@
}, //
[&](Default) -> ExprTypeName {
TINT_ICE(Transform, b.Diagnostics())
- << "unhandled type for access chain: " << src->FriendlyName(ty);
+ << "unhandled type for access chain: " << ty->FriendlyName();
return {};
});
}
diff --git a/src/tint/transform/vectorize_matrix_conversions.cc b/src/tint/transform/vectorize_matrix_conversions.cc
index 748346e..97e4d3c 100644
--- a/src/tint/transform/vectorize_matrix_conversions.cc
+++ b/src/tint/transform/vectorize_matrix_conversions.cc
@@ -124,8 +124,8 @@
utils::GetOrCreate(matrix_convs, HelperFunctionKey{{src_type, dst_type}}, [&] {
auto name = b.Symbols().New(
"convert_mat" + std::to_string(src_type->columns()) + "x" +
- std::to_string(src_type->rows()) + "_" + b.FriendlyName(src_type->type()) +
- "_" + b.FriendlyName(dst_type->type()));
+ std::to_string(src_type->rows()) + "_" + src_type->type()->FriendlyName() +
+ "_" + dst_type->type()->FriendlyName());
b.Func(name,
utils::Vector{
b.Param("value", CreateASTTypeFor(ctx, src_type)),
diff --git a/src/tint/type/test_helper.h b/src/tint/type/test_helper.h
index 45ff61a..95827b0 100644
--- a/src/tint/type/test_helper.h
+++ b/src/tint/type/test_helper.h
@@ -45,15 +45,15 @@
} // namespace tint::type
/// Helper macro for testing that a type was as expected
-#define EXPECT_TYPE(GOT, EXPECT) \
- do { \
- const type::Type* got = GOT; \
- const type::Type* expect = EXPECT; \
- if (got != expect) { \
- ADD_FAILURE() << #GOT " != " #EXPECT "\n" \
- << " " #GOT ": " << FriendlyName(got) << "\n" \
- << " " #EXPECT ": " << FriendlyName(expect); \
- } \
+#define EXPECT_TYPE(GOT, EXPECT) \
+ do { \
+ const type::Type* got = GOT; \
+ const type::Type* expect = EXPECT; \
+ if (got != expect) { \
+ ADD_FAILURE() << #GOT " != " #EXPECT "\n" \
+ << " " #GOT ": " << (got ? got->FriendlyName() : "<null>") << "\n" \
+ << " " #EXPECT ": " << (expect ? expect->FriendlyName() : "<null>"); \
+ } \
} while (false)
#endif // SRC_TINT_TYPE_TEST_HELPER_H_
diff --git a/src/tint/utils/castable.h b/src/tint/utils/castable.h
index abe7610..1df31e7 100644
--- a/src/tint/utils/castable.h
+++ b/src/tint/utils/castable.h
@@ -423,9 +423,9 @@
using TrueBase = BASE;
/// Constructor
- /// @param args the arguments to forward to the base class.
+ /// @param arguments the arguments to forward to the base class.
template <typename... ARGS>
- inline explicit Castable(ARGS&&... args) : TrueBase(std::forward<ARGS>(args)...) {
+ inline explicit Castable(ARGS&&... arguments) : TrueBase(std::forward<ARGS>(arguments)...) {
this->type_info_ = &TypeInfo::Of<CLASS>();
}
diff --git a/src/tint/utils/hash.h b/src/tint/utils/hash.h
index a63a303..af590f4 100644
--- a/src/tint/utils/hash.h
+++ b/src/tint/utils/hash.h
@@ -18,6 +18,7 @@
#include <stdint.h>
#include <cstdio>
#include <functional>
+#include <string>
#include <tuple>
#include <utility>
#include <variant>
@@ -152,6 +153,29 @@
}
};
+/// Hasher specialization for std::string, which also supports hashing of const char* and
+/// std::string_view without first constructing a std::string.
+template <>
+struct Hasher<std::string> {
+ /// @param str the string to hash
+ /// @returns a hash of the string
+ size_t operator()(const std::string& str) const {
+ return std::hash<std::string_view>()(std::string_view(str));
+ }
+
+ /// @param str the string to hash
+ /// @returns a hash of the string
+ size_t operator()(const char* str) const {
+ return std::hash<std::string_view>()(std::string_view(str));
+ }
+
+ /// @param str the string to hash
+ /// @returns a hash of the string
+ size_t operator()(const std::string_view& str) const {
+ return std::hash<std::string_view>()(str);
+ }
+};
+
/// @returns a hash of the variadic list of arguments.
/// The returned hash is dependent on the order of the arguments.
template <typename... ARGS>
@@ -176,6 +200,47 @@
return hash;
}
+/// A STL-compatible equal_to implementation that specializes for types.
+template <typename T>
+struct EqualTo {
+ /// @param lhs the left hand side value
+ /// @param rhs the right hand side value
+ /// @returns true if the two values are equal
+ constexpr bool operator()(const T& lhs, const T& rhs) const {
+ return std::equal_to<T>()(lhs, rhs);
+ }
+};
+
+/// A specialization for EqualTo for std::string, which supports additional comparision with
+/// std::string_view and const char*.
+template <>
+struct EqualTo<std::string> {
+ /// @param lhs the left hand side value
+ /// @param rhs the right hand side value
+ /// @returns true if the two values are equal
+ bool operator()(const std::string& lhs, const std::string& rhs) const { return lhs == rhs; }
+
+ /// @param lhs the left hand side value
+ /// @param rhs the right hand side value
+ /// @returns true if the two values are equal
+ bool operator()(const std::string& lhs, const char* rhs) const { return lhs == rhs; }
+
+ /// @param lhs the left hand side value
+ /// @param rhs the right hand side value
+ /// @returns true if the two values are equal
+ bool operator()(const std::string& lhs, std::string_view rhs) const { return lhs == rhs; }
+
+ /// @param lhs the left hand side value
+ /// @param rhs the right hand side value
+ /// @returns true if the two values are equal
+ bool operator()(const char* lhs, const std::string& rhs) const { return lhs == rhs; }
+
+ /// @param lhs the left hand side value
+ /// @param rhs the right hand side value
+ /// @returns true if the two values are equal
+ bool operator()(std::string_view lhs, const std::string& rhs) const { return lhs == rhs; }
+};
+
/// Wrapper for a hashable type enabling the wrapped value to be used as a key
/// for an unordered_map or unordered_set.
template <typename T>
diff --git a/src/tint/utils/hash_test.cc b/src/tint/utils/hash_test.cc
index cdceab4..2261eb8 100644
--- a/src/tint/utils/hash_test.cc
+++ b/src/tint/utils/hash_test.cc
@@ -73,5 +73,41 @@
EXPECT_EQ(m[W({2, 1})], 0);
}
+TEST(EqualTo, String) {
+ std::string str_a = "hello";
+ std::string str_b = "world";
+ const char* cstr_a = "hello";
+ const char* cstr_b = "world";
+ std::string_view sv_a = "hello";
+ std::string_view sv_b = "world";
+ EXPECT_TRUE(EqualTo<std::string>()(str_a, str_a));
+ EXPECT_TRUE(EqualTo<std::string>()(str_a, cstr_a));
+ EXPECT_TRUE(EqualTo<std::string>()(str_a, sv_a));
+ EXPECT_TRUE(EqualTo<std::string>()(str_a, str_a));
+ EXPECT_TRUE(EqualTo<std::string>()(cstr_a, str_a));
+ EXPECT_TRUE(EqualTo<std::string>()(sv_a, str_a));
+
+ EXPECT_FALSE(EqualTo<std::string>()(str_a, str_b));
+ EXPECT_FALSE(EqualTo<std::string>()(str_a, cstr_b));
+ EXPECT_FALSE(EqualTo<std::string>()(str_a, sv_b));
+ EXPECT_FALSE(EqualTo<std::string>()(str_a, str_b));
+ EXPECT_FALSE(EqualTo<std::string>()(cstr_a, str_b));
+ EXPECT_FALSE(EqualTo<std::string>()(sv_a, str_b));
+
+ EXPECT_FALSE(EqualTo<std::string>()(str_b, str_a));
+ EXPECT_FALSE(EqualTo<std::string>()(str_b, cstr_a));
+ EXPECT_FALSE(EqualTo<std::string>()(str_b, sv_a));
+ EXPECT_FALSE(EqualTo<std::string>()(str_b, str_a));
+ EXPECT_FALSE(EqualTo<std::string>()(cstr_b, str_a));
+ EXPECT_FALSE(EqualTo<std::string>()(sv_b, str_a));
+
+ EXPECT_TRUE(EqualTo<std::string>()(str_b, str_b));
+ EXPECT_TRUE(EqualTo<std::string>()(str_b, cstr_b));
+ EXPECT_TRUE(EqualTo<std::string>()(str_b, sv_b));
+ EXPECT_TRUE(EqualTo<std::string>()(str_b, str_b));
+ EXPECT_TRUE(EqualTo<std::string>()(cstr_b, str_b));
+ EXPECT_TRUE(EqualTo<std::string>()(sv_b, str_b));
+}
+
} // namespace
} // namespace tint::utils
diff --git a/src/tint/utils/hashmap.h b/src/tint/utils/hashmap.h
index 6a5f3c5..98317c9 100644
--- a/src/tint/utils/hashmap.h
+++ b/src/tint/utils/hashmap.h
@@ -31,11 +31,14 @@
typename VALUE,
size_t N,
typename HASH = Hasher<KEY>,
- typename EQUAL = std::equal_to<KEY>>
+ typename EQUAL = EqualTo<KEY>>
class Hashmap : public HashmapBase<KEY, VALUE, N, HASH, EQUAL> {
using Base = HashmapBase<KEY, VALUE, N, HASH, EQUAL>;
using PutMode = typename Base::PutMode;
+ template <typename T>
+ using ReferenceKeyType = traits::CharArrayToCharPtr<std::remove_reference_t<T>>;
+
public:
/// The key type
using Key = KEY;
@@ -51,7 +54,7 @@
/// The value returned by the Reference reflects the current state of the Hashmap, and so the
/// referenced value may change, or transition between valid or invalid based on the current
/// state of the Hashmap.
- template <bool IS_CONST>
+ template <bool IS_CONST, typename K>
class ReferenceT {
/// `const Value` if IS_CONST, or `Value` if !IS_CONST
using T = std::conditional_t<IS_CONST, const Value, Value>;
@@ -89,24 +92,34 @@
friend Hashmap;
/// Constructor
- ReferenceT(Map& map, const Key& key)
- : map_(map), key_(key), cached_(nullptr), generation_(map.Generation() - 1) {}
+ template <typename K_ARG>
+ ReferenceT(Map& map, K_ARG&& key)
+ : map_(map),
+ key_(std::forward<K_ARG>(key)),
+ cached_(nullptr),
+ generation_(map.Generation() - 1) {}
/// Constructor
- ReferenceT(Map& map, const Key& key, T* value)
- : map_(map), key_(key), cached_(value), generation_(map.Generation()) {}
+ template <typename K_ARG>
+ ReferenceT(Map& map, K_ARG&& key, T* value)
+ : map_(map),
+ key_(std::forward<K_ARG>(key)),
+ cached_(value),
+ generation_(map.Generation()) {}
Map& map_;
- const Key key_;
+ const K key_;
mutable T* cached_ = nullptr;
mutable size_t generation_ = 0;
};
/// A mutable reference returned by Find()
- using Reference = ReferenceT</*IS_CONST*/ false>;
+ template <typename K>
+ using Reference = ReferenceT</*IS_CONST*/ false, K>;
/// An immutable reference returned by Find()
- using ConstReference = ReferenceT</*IS_CONST*/ true>;
+ template <typename K>
+ using ConstReference = ReferenceT</*IS_CONST*/ true, K>;
/// Adds a value to the map, if the map does not already contain an entry with the key @p key.
/// @param key the entry key.
@@ -129,7 +142,8 @@
/// @param key the key to search for.
/// @returns the value of the entry that is equal to `value`, or no value if the entry was not
/// found.
- std::optional<Value> Get(const Key& key) const {
+ template <typename K>
+ std::optional<Value> Get(K&& key) const {
if (auto [found, index] = this->IndexOf(key); found) {
return this->slots_[index].entry->value;
}
@@ -169,18 +183,24 @@
/// @param key the entry's key value to search for.
/// @returns the value of the entry.
template <typename K>
- Reference GetOrZero(K&& key) {
+ auto GetOrZero(K&& key) {
auto res = Add(std::forward<K>(key), Value{});
- return Reference(*this, key, res.value);
+ return Reference<ReferenceKeyType<K>>(*this, key, res.value);
}
/// @param key the key to search for.
/// @returns a reference to the entry that is equal to the given value.
- Reference Find(const Key& key) { return Reference(*this, key); }
+ template <typename K>
+ auto Find(K&& key) {
+ return Reference<ReferenceKeyType<K>>(*this, std::forward<K>(key));
+ }
/// @param key the key to search for.
/// @returns a reference to the entry that is equal to the given value.
- ConstReference Find(const Key& key) const { return ConstReference(*this, key); }
+ template <typename K>
+ auto Find(K&& key) const {
+ return ConstReference<ReferenceKeyType<K>>(*this, std::forward<K>(key));
+ }
/// @returns the keys of the map as a vector.
/// @note the order of the returned vector is non-deterministic between compilers.
@@ -232,14 +252,16 @@
}
private:
- Value* Lookup(const Key& key) {
+ template <typename K>
+ Value* Lookup(K&& key) {
if (auto [found, index] = this->IndexOf(key); found) {
return &this->slots_[index].entry->value;
}
return nullptr;
}
- const Value* Lookup(const Key& key) const {
+ template <typename K>
+ const Value* Lookup(K&& key) const {
if (auto [found, index] = this->IndexOf(key); found) {
return &this->slots_[index].entry->value;
}
diff --git a/src/tint/utils/hashmap_base.h b/src/tint/utils/hashmap_base.h
index 12c1ed2..f31dcf2 100644
--- a/src/tint/utils/hashmap_base.h
+++ b/src/tint/utils/hashmap_base.h
@@ -106,7 +106,7 @@
typename VALUE,
size_t N,
typename HASH = Hasher<KEY>,
- typename EQUAL = std::equal_to<KEY>>
+ typename EQUAL = EqualTo<KEY>>
class HashmapBase {
static constexpr bool ValueIsVoid = std::is_same_v<VALUE, void>;
@@ -157,8 +157,9 @@
/// A slot can either be empty or filled with a value. If the slot is empty, #hash and #distance
/// will be zero.
struct Slot {
- bool Equals(size_t key_hash, const Key& key) const {
- return key_hash == hash && EQUAL()(key, KeyOf(*entry));
+ template <typename K>
+ bool Equals(size_t key_hash, K&& key) const {
+ return key_hash == hash && EQUAL()(std::forward<K>(key), KeyOf(*entry));
}
/// The slot value. If this does not contain a value, then the slot is vacant.
@@ -502,8 +503,9 @@
/// @param key the key to hash
/// @returns a tuple holding the target slot index for the given value, and the hash of the
/// value, respectively.
- HashResult Hash(const Key& key) const {
- size_t hash = HASH()(key);
+ template <typename K>
+ HashResult Hash(K&& key) const {
+ size_t hash = HASH()(std::forward<K>(key));
size_t index = Wrap(hash);
return {index, hash};
}
@@ -512,7 +514,8 @@
/// @param key the key to search for.
/// @returns a tuple holding a boolean representing whether the key was found in the map, and
/// if found, the index of the slot that holds the key.
- std::tuple<bool, size_t> IndexOf(const Key& key) const {
+ template <typename K>
+ std::tuple<bool, size_t> IndexOf(K&& key) const {
const auto hash = Hash(key);
const auto count = slots_.Length();
for (size_t distance = 0, index = hash.scan_start; distance < count; distance++) {
diff --git a/src/tint/utils/hashmap_test.cc b/src/tint/utils/hashmap_test.cc
index 6d993e2..f27875c 100644
--- a/src/tint/utils/hashmap_test.cc
+++ b/src/tint/utils/hashmap_test.cc
@@ -155,6 +155,134 @@
EXPECT_FALSE(one);
}
+TEST(Hashmap, StringKeys) {
+ Hashmap<std::string, int, 4> map;
+ EXPECT_FALSE(map.Find("zero"));
+ EXPECT_FALSE(map.Find(std::string("zero")));
+ EXPECT_FALSE(map.Find(std::string_view("zero")));
+
+ map.Add("three", 3);
+ auto three_cstr = map.Find("three");
+ auto three_str = map.Find(std::string("three"));
+ auto three_sv = map.Find(std::string_view("three"));
+ map.Add(std::string("two"), 2);
+ auto two_cstr = map.Find("two");
+ auto two_str = map.Find(std::string("two"));
+ auto two_sv = map.Find(std::string_view("two"));
+ map.Add("four", 4);
+ auto four_cstr = map.Find("four");
+ auto four_str = map.Find(std::string("four"));
+ auto four_sv = map.Find(std::string_view("four"));
+ map.Add(std::string("eight"), 8);
+ auto eight_cstr = map.Find("eight");
+ auto eight_str = map.Find(std::string("eight"));
+ auto eight_sv = map.Find(std::string_view("eight"));
+
+ ASSERT_TRUE(three_cstr);
+ ASSERT_TRUE(three_str);
+ ASSERT_TRUE(three_sv);
+ ASSERT_TRUE(two_cstr);
+ ASSERT_TRUE(two_str);
+ ASSERT_TRUE(two_sv);
+ ASSERT_TRUE(four_cstr);
+ ASSERT_TRUE(four_str);
+ ASSERT_TRUE(four_sv);
+ ASSERT_TRUE(eight_cstr);
+ ASSERT_TRUE(eight_str);
+ ASSERT_TRUE(eight_sv);
+
+ EXPECT_EQ(*three_cstr, 3);
+ EXPECT_EQ(*three_str, 3);
+ EXPECT_EQ(*three_sv, 3);
+ EXPECT_EQ(*two_cstr, 2);
+ EXPECT_EQ(*two_str, 2);
+ EXPECT_EQ(*two_sv, 2);
+ EXPECT_EQ(*four_cstr, 4);
+ EXPECT_EQ(*four_str, 4);
+ EXPECT_EQ(*four_sv, 4);
+ EXPECT_EQ(*eight_cstr, 8);
+ EXPECT_EQ(*eight_str, 8);
+ EXPECT_EQ(*eight_sv, 8);
+
+ map.Add("zero", 0); // Note: Find called before Add() is okay!
+ auto zero_cstr = map.Find("zero");
+ auto zero_str = map.Find(std::string("zero"));
+ auto zero_sv = map.Find(std::string_view("zero"));
+
+ map.Add(std::string("five"), 5);
+ auto five_cstr = map.Find("five");
+ auto five_str = map.Find(std::string("five"));
+ auto five_sv = map.Find(std::string_view("five"));
+ map.Add("six", 6);
+ auto six_cstr = map.Find("six");
+ auto six_str = map.Find(std::string("six"));
+ auto six_sv = map.Find(std::string_view("six"));
+ map.Add("one", 1);
+ auto one_cstr = map.Find("one");
+ auto one_str = map.Find(std::string("one"));
+ auto one_sv = map.Find(std::string_view("one"));
+ map.Add(std::string("seven"), 7);
+ auto seven_cstr = map.Find("seven");
+ auto seven_str = map.Find(std::string("seven"));
+ auto seven_sv = map.Find(std::string_view("seven"));
+
+ ASSERT_TRUE(zero_cstr);
+ ASSERT_TRUE(zero_str);
+ ASSERT_TRUE(zero_sv);
+ ASSERT_TRUE(three_cstr);
+ ASSERT_TRUE(three_str);
+ ASSERT_TRUE(three_sv);
+ ASSERT_TRUE(two_cstr);
+ ASSERT_TRUE(two_str);
+ ASSERT_TRUE(two_sv);
+ ASSERT_TRUE(four_cstr);
+ ASSERT_TRUE(four_str);
+ ASSERT_TRUE(four_sv);
+ ASSERT_TRUE(eight_cstr);
+ ASSERT_TRUE(eight_str);
+ ASSERT_TRUE(eight_sv);
+ ASSERT_TRUE(five_cstr);
+ ASSERT_TRUE(five_str);
+ ASSERT_TRUE(five_sv);
+ ASSERT_TRUE(six_cstr);
+ ASSERT_TRUE(six_str);
+ ASSERT_TRUE(six_sv);
+ ASSERT_TRUE(one_cstr);
+ ASSERT_TRUE(one_str);
+ ASSERT_TRUE(one_sv);
+ ASSERT_TRUE(seven_cstr);
+ ASSERT_TRUE(seven_str);
+ ASSERT_TRUE(seven_sv);
+
+ EXPECT_EQ(*zero_cstr, 0);
+ EXPECT_EQ(*zero_str, 0);
+ EXPECT_EQ(*zero_sv, 0);
+ EXPECT_EQ(*three_cstr, 3);
+ EXPECT_EQ(*three_str, 3);
+ EXPECT_EQ(*three_sv, 3);
+ EXPECT_EQ(*two_cstr, 2);
+ EXPECT_EQ(*two_str, 2);
+ EXPECT_EQ(*two_sv, 2);
+ EXPECT_EQ(*four_cstr, 4);
+ EXPECT_EQ(*four_str, 4);
+ EXPECT_EQ(*four_sv, 4);
+ EXPECT_EQ(*eight_cstr, 8);
+ EXPECT_EQ(*eight_str, 8);
+ EXPECT_EQ(*eight_sv, 8);
+ EXPECT_EQ(*five_cstr, 5);
+ EXPECT_EQ(*five_str, 5);
+ EXPECT_EQ(*five_sv, 5);
+ EXPECT_EQ(*six_cstr, 6);
+ EXPECT_EQ(*six_str, 6);
+ EXPECT_EQ(*six_sv, 6);
+ EXPECT_EQ(*one_cstr, 1);
+ EXPECT_EQ(*one_str, 1);
+ EXPECT_EQ(*one_sv, 1);
+ EXPECT_EQ(*seven_cstr, 7);
+ EXPECT_EQ(*seven_str, 7);
+ EXPECT_EQ(*seven_sv, 7);
+}
+
TEST(Hashmap, Iterator) {
using Map = Hashmap<int, std::string, 8>;
using Entry = typename Map::Entry;
diff --git a/src/tint/utils/traits.h b/src/tint/utils/traits.h
index 525ed9b..711ea36 100644
--- a/src/tint/utils/traits.h
+++ b/src/tint/utils/traits.h
@@ -159,16 +159,16 @@
namespace detail {
/// Base template for IsTypeIn
-template <class T, class TypeList>
+template <typename T, typename TypeList>
struct IsTypeIn;
/// Specialization for IsTypeIn
-template <class T, template <class...> class TypeContainer, class... Ts>
+template <typename T, template <typename...> typename TypeContainer, typename... Ts>
struct IsTypeIn<T, TypeContainer<Ts...>> : std::disjunction<std::is_same<T, Ts>...> {};
} // namespace detail
/// Evaluates to true if T is one of the types in the TypeContainer's template arguments.
-/// Works for std::variant, std::tuple, std::pair, or any class template where all parameters are
+/// Works for std::variant, std::tuple, std::pair, or any typename template where all parameters are
/// types.
template <typename T, typename TypeContainer>
static constexpr bool IsTypeIn = detail::IsTypeIn<T, TypeContainer>::value;
@@ -183,6 +183,32 @@
std::is_same_v<Decay<T>, std::string> || std::is_same_v<Decay<T>, std::string_view> ||
std::is_same_v<Decay<T>, const char*>;
+namespace detail {
+/// Helper for CharArrayToCharPtr
+template <typename T>
+struct CharArrayToCharPtrImpl {
+ /// Evaluates to T
+ using type = T;
+};
+/// Specialization of CharArrayToCharPtrImpl for `char[N]`
+template <size_t N>
+struct CharArrayToCharPtrImpl<char[N]> {
+ /// Evaluates to `char*`
+ using type = char*;
+};
+/// Specialization of CharArrayToCharPtrImpl for `const char[N]`
+template <size_t N>
+struct CharArrayToCharPtrImpl<const char[N]> {
+ /// Evaluates to `const char*`
+ using type = const char*;
+};
+} // namespace detail
+
+/// Evaluates to `char*` or `const char*` if `T` is `char[N]` or `const char[N]`, respectively,
+/// otherwise T.
+template <typename T>
+using CharArrayToCharPtr = typename detail::CharArrayToCharPtrImpl<T>::type;
+
} // namespace tint::utils::traits
#endif // SRC_TINT_UTILS_TRAITS_H_
diff --git a/src/tint/utils/traits_test.cc b/src/tint/utils/traits_test.cc
index 578ed44..83a80f9 100644
--- a/src/tint/utils/traits_test.cc
+++ b/src/tint/utils/traits_test.cc
@@ -241,4 +241,9 @@
static_assert(std::is_same_v<std::tuple_element_t<1, sliced>, float>);
}
+static_assert(std::is_same_v<char*, CharArrayToCharPtr<char[2]>>);
+static_assert(std::is_same_v<const char*, CharArrayToCharPtr<const char[2]>>);
+static_assert(std::is_same_v<int, CharArrayToCharPtr<int>>);
+static_assert(std::is_same_v<int[2], CharArrayToCharPtr<int[2]>>);
+
} // namespace tint::utils::traits
diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc
index 8fcdd3d..85644e2 100644
--- a/src/tint/writer/glsl/generator_impl.cc
+++ b/src/tint/writer/glsl/generator_impl.cc
@@ -170,7 +170,6 @@
manager.Add<transform::PreservePadding>(); // Must come before DirectVariableAccess
manager.Add<transform::Unshadow>(); // Must come before DirectVariableAccess
- manager.Add<transform::DirectVariableAccess>();
manager.Add<transform::PromoteSideEffectsToDecl>();
@@ -203,9 +202,11 @@
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
polyfills.workgroup_uniform_load = true;
data.Add<transform::BuiltinPolyfill::Config>(polyfills);
- manager.Add<transform::BuiltinPolyfill>();
+ manager.Add<transform::BuiltinPolyfill>(); // Must come before DirectVariableAccess
}
+ manager.Add<transform::DirectVariableAccess>();
+
if (!options.disable_workgroup_init) {
// ZeroInitWorkgroupMemory must come before CanonicalizeEntryPointIO as
// ZeroInitWorkgroupMemory may inject new builtin parameters.
@@ -2147,9 +2148,8 @@
}
},
[&](Default) {
- diagnostics_.add_error(
- diag::System::Writer,
- "unhandled constant type: " + builder_.FriendlyName(constant->Type()));
+ diagnostics_.add_error(diag::System::Writer,
+ "unhandled constant type: " + constant->Type()->FriendlyName());
});
}
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index ed86e9e..e8b697b 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -176,8 +176,6 @@
manager.Add<transform::Unshadow>(); // Must come before DirectVariableAccess
- manager.Add<transform::DirectVariableAccess>();
-
// LocalizeStructArrayAssignment must come after:
// * SimplifyPointers, because it assumes assignment to arrays in structs are
// done directly, not indirectly.
@@ -229,9 +227,11 @@
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
polyfills.workgroup_uniform_load = true;
data.Add<transform::BuiltinPolyfill::Config>(polyfills);
- manager.Add<transform::BuiltinPolyfill>();
+ manager.Add<transform::BuiltinPolyfill>(); // Must come before DirectVariableAccess
}
+ manager.Add<transform::DirectVariableAccess>();
+
if (!options.disable_workgroup_init) {
// ZeroInitWorkgroupMemory must come before CanonicalizeEntryPointIO as
// ZeroInitWorkgroupMemory may inject new builtin parameters.
@@ -3482,9 +3482,8 @@
return true;
},
[&](Default) {
- diagnostics_.add_error(
- diag::System::Writer,
- "unhandled constant type: " + builder_.FriendlyName(constant->Type()));
+ diagnostics_.add_error(diag::System::Writer,
+ "unhandled constant type: " + constant->Type()->FriendlyName());
return false;
});
}
diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc
index 14288ee..d955d78 100644
--- a/src/tint/writer/msl/generator_impl.cc
+++ b/src/tint/writer/msl/generator_impl.cc
@@ -1788,9 +1788,8 @@
return true;
},
[&](Default) {
- diagnostics_.add_error(
- diag::System::Writer,
- "unhandled constant type: " + builder_.FriendlyName(constant->Type()));
+ diagnostics_.add_error(diag::System::Writer,
+ "unhandled constant type: " + constant->Type()->FriendlyName());
return false;
});
}
diff --git a/src/tint/writer/spirv/binary_writer.cc b/src/tint/writer/spirv/binary_writer.cc
index 69ac353..4952bdb 100644
--- a/src/tint/writer/spirv/binary_writer.cc
+++ b/src/tint/writer/spirv/binary_writer.cc
@@ -28,9 +28,9 @@
BinaryWriter::~BinaryWriter() = default;
-void BinaryWriter::WriteBuilder(Builder* builder) {
- out_.reserve(builder->total_size());
- builder->iterate([this](const Instruction& inst) { this->process_instruction(inst); });
+void BinaryWriter::WriteModule(const Module* module) {
+ out_.reserve(module->TotalSize());
+ module->Iterate([this](const Instruction& inst) { this->process_instruction(inst); });
}
void BinaryWriter::WriteInstruction(const Instruction& inst) {
diff --git a/src/tint/writer/spirv/binary_writer.h b/src/tint/writer/spirv/binary_writer.h
index e1e7f68..0b1c234 100644
--- a/src/tint/writer/spirv/binary_writer.h
+++ b/src/tint/writer/spirv/binary_writer.h
@@ -17,11 +17,11 @@
#include <vector>
-#include "src/tint/writer/spirv/builder.h"
+#include "src/tint/writer/spirv/module.h"
namespace tint::writer::spirv {
-/// Writer to convert from builder to SPIR-V binary
+/// Writer to convert from module to SPIR-V binary.
class BinaryWriter {
public:
/// Constructor
@@ -32,11 +32,10 @@
/// @param bound the bound to output
void WriteHeader(uint32_t bound);
- /// Writes the given builder data into a binary. Note, this does not emit
- /// the SPIR-V header. You **must** call WriteHeader() before WriteBuilder()
- /// if you want the SPIR-V to be emitted.
- /// @param builder the builder to assemble from
- void WriteBuilder(Builder* builder);
+ /// Writes the given module data into a binary. Note, this does not emit the SPIR-V header. You
+ /// **must** call WriteHeader() before WriteModule() if you want the SPIR-V to be emitted.
+ /// @param module the module to assemble from
+ void WriteModule(const Module* module);
/// Writes the given instruction into the binary.
/// @param inst the instruction to assemble
diff --git a/src/tint/writer/spirv/binary_writer_test.cc b/src/tint/writer/spirv/binary_writer_test.cc
index 11812cf..c043b25 100644
--- a/src/tint/writer/spirv/binary_writer_test.cc
+++ b/src/tint/writer/spirv/binary_writer_test.cc
@@ -33,11 +33,11 @@
}
TEST_F(BinaryWriterTest, Float) {
- spirv::Builder& b = Build();
+ Module m;
- b.push_annot(spv::Op::OpKill, {Operand(2.4f)});
+ m.PushAnnot(spv::Op::OpKill, {Operand(2.4f)});
BinaryWriter bw;
- bw.WriteBuilder(&b);
+ bw.WriteModule(&m);
auto res = bw.result();
ASSERT_EQ(res.size(), 2u);
@@ -47,11 +47,11 @@
}
TEST_F(BinaryWriterTest, Int) {
- spirv::Builder& b = Build();
+ Module m;
- b.push_annot(spv::Op::OpKill, {Operand(2u)});
+ m.PushAnnot(spv::Op::OpKill, {Operand(2u)});
BinaryWriter bw;
- bw.WriteBuilder(&b);
+ bw.WriteModule(&m);
auto res = bw.result();
ASSERT_EQ(res.size(), 2u);
@@ -59,11 +59,11 @@
}
TEST_F(BinaryWriterTest, String) {
- spirv::Builder& b = Build();
+ Module m;
- b.push_annot(spv::Op::OpKill, {Operand("my_string")});
+ m.PushAnnot(spv::Op::OpKill, {Operand("my_string")});
BinaryWriter bw;
- bw.WriteBuilder(&b);
+ bw.WriteModule(&m);
auto res = bw.result();
ASSERT_EQ(res.size(), 4u);
@@ -84,11 +84,11 @@
}
TEST_F(BinaryWriterTest, String_Multiple4Length) {
- spirv::Builder& b = Build();
+ Module m;
- b.push_annot(spv::Op::OpKill, {Operand("mystring")});
+ m.PushAnnot(spv::Op::OpKill, {Operand("mystring")});
BinaryWriter bw;
- bw.WriteBuilder(&b);
+ bw.WriteModule(&m);
auto res = bw.result();
ASSERT_EQ(res.size(), 4u);
diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc
index 972ba7c..add10aa 100644
--- a/src/tint/writer/spirv/builder.cc
+++ b/src/tint/writer/spirv/builder.cc
@@ -58,15 +58,6 @@
const char kGLSLstd450[] = "GLSL.std.450";
-uint32_t size_of(const InstructionList& instructions) {
- uint32_t size = 0;
- for (const auto& inst : instructions) {
- size += inst.word_length();
- }
-
- return size;
-}
-
uint32_t pipeline_stage_to_execution_model(ast::PipelineStage stage) {
SpvExecutionModel model = SpvExecutionModelVertex;
@@ -270,14 +261,13 @@
builtin::Extension::kChromiumExperimentalPushConstant,
builtin::Extension::kF16,
})) {
- error_ = builder_.Diagnostics().str();
return false;
}
- push_capability(SpvCapabilityShader);
+ module_.PushCapability(SpvCapabilityShader);
- push_memory_model(spv::Op::OpMemoryModel,
- {U32Operand(SpvAddressingModelLogical), U32Operand(SpvMemoryModelGLSL450)});
+ module_.PushMemoryModel(spv::Op::OpMemoryModel, {U32Operand(SpvAddressingModelLogical),
+ U32Operand(SpvMemoryModelGLSL450)});
for (auto ext : builder_.Sem().Module()->Extensions()) {
GenerateExtension(ext);
@@ -309,7 +299,8 @@
uint32_t Builder::LookupVariableID(const sem::Variable* var) {
auto it = var_to_id_.find(var);
if (it == var_to_id_.end()) {
- error_ = "unable to find ID for variable: " + var->Declaration()->name->symbol.Name();
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "unable to find ID for variable: " + var->Declaration()->name->symbol.Name();
return 0;
}
return it->second;
@@ -325,85 +316,21 @@
}
Operand Builder::result_op() {
- return Operand(next_id());
-}
-
-uint32_t Builder::total_size() const {
- // The 5 covers the magic, version, generator, id bound and reserved.
- uint32_t size = 5;
-
- size += size_of(capabilities_);
- size += size_of(extensions_);
- size += size_of(ext_imports_);
- size += size_of(memory_model_);
- size += size_of(entry_points_);
- size += size_of(execution_modes_);
- size += size_of(debug_);
- size += size_of(annotations_);
- size += size_of(types_);
- for (const auto& func : functions_) {
- size += func.word_length();
- }
-
- return size;
-}
-
-void Builder::iterate(std::function<void(const Instruction&)> cb) const {
- for (const auto& inst : capabilities_) {
- cb(inst);
- }
- for (const auto& inst : extensions_) {
- cb(inst);
- }
- for (const auto& inst : ext_imports_) {
- cb(inst);
- }
- for (const auto& inst : memory_model_) {
- cb(inst);
- }
- for (const auto& inst : entry_points_) {
- cb(inst);
- }
- for (const auto& inst : execution_modes_) {
- cb(inst);
- }
- for (const auto& inst : debug_) {
- cb(inst);
- }
- for (const auto& inst : annotations_) {
- cb(inst);
- }
- for (const auto& inst : types_) {
- cb(inst);
- }
- for (const auto& func : functions_) {
- func.iterate(cb);
- }
-}
-
-void Builder::push_capability(uint32_t cap) {
- if (capability_set_.count(cap) == 0) {
- capability_set_.insert(cap);
- capabilities_.push_back(Instruction{spv::Op::OpCapability, {Operand(cap)}});
- }
-}
-
-void Builder::push_extension(const char* extension) {
- extensions_.push_back(Instruction{spv::Op::OpExtension, {Operand(extension)}});
+ return Operand(module_.NextId());
}
bool Builder::GenerateExtension(builtin::Extension extension) {
switch (extension) {
case builtin::Extension::kChromiumExperimentalDp4A:
- push_extension("SPV_KHR_integer_dot_product");
- push_capability(SpvCapabilityDotProductKHR);
- push_capability(SpvCapabilityDotProductInput4x8BitPackedKHR);
+ module_.PushExtension("SPV_KHR_integer_dot_product");
+ module_.PushCapability(SpvCapabilityDotProductKHR);
+ module_.PushCapability(SpvCapabilityDotProductInput4x8BitPackedKHR);
break;
case builtin::Extension::kF16:
- push_capability(SpvCapabilityFloat16);
- push_capability(SpvCapabilityUniformAndStorageBuffer16BitAccess);
- push_capability(SpvCapabilityStorageBuffer16BitAccess);
- push_capability(SpvCapabilityStorageInputOutput16);
+ module_.PushCapability(SpvCapabilityFloat16);
+ module_.PushCapability(SpvCapabilityUniformAndStorageBuffer16BitAccess);
+ module_.PushCapability(SpvCapabilityStorageBuffer16BitAccess);
+ module_.PushCapability(SpvCapabilityStorageInputOutput16);
break;
default:
return false;
@@ -447,7 +374,7 @@
bool Builder::GenerateBreakStatement(const ast::BreakStatement*) {
if (merge_stack_.empty()) {
- error_ = "Attempted to break without a merge block";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "Attempted to break without a merge block";
return false;
}
if (!push_function_inst(spv::Op::OpBranch, {Operand(merge_stack_.back())})) {
@@ -471,7 +398,8 @@
bool Builder::GenerateContinueStatement(const ast::ContinueStatement*) {
if (continue_stack_.empty()) {
- error_ = "Attempted to continue without a continue block";
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "Attempted to continue without a continue block";
return false;
}
if (!push_function_inst(spv::Op::OpBranch, {Operand(continue_stack_.back())})) {
@@ -493,7 +421,7 @@
bool Builder::GenerateEntryPoint(const ast::Function* func, uint32_t id) {
auto stage = pipeline_stage_to_execution_model(func->PipelineStage());
if (stage == SpvExecutionModelMax) {
- error_ = "Unknown pipeline stage provided";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "Unknown pipeline stage provided";
return false;
}
@@ -510,14 +438,14 @@
uint32_t var_id = LookupVariableID(var);
if (var_id == 0) {
- error_ =
- "unable to find ID for global variable: " + var->Declaration()->name->symbol.Name();
+ TINT_ICE(Writer, builder_.Diagnostics()) << "unable to find ID for global variable: " +
+ var->Declaration()->name->symbol.Name();
return false;
}
operands.push_back(Operand(var_id));
}
- push_entry_point(spv::Op::OpEntryPoint, operands);
+ module_.PushEntryPoint(spv::Op::OpEntryPoint, operands);
return true;
}
@@ -527,19 +455,19 @@
// WGSL fragment shader origin is upper left
if (func->PipelineStage() == ast::PipelineStage::kFragment) {
- push_execution_mode(spv::Op::OpExecutionMode,
- {Operand(id), U32Operand(SpvExecutionModeOriginUpperLeft)});
+ module_.PushExecutionMode(spv::Op::OpExecutionMode,
+ {Operand(id), U32Operand(SpvExecutionModeOriginUpperLeft)});
} else if (func->PipelineStage() == ast::PipelineStage::kCompute) {
auto& wgsize = func_sem->WorkgroupSize();
// Check if the workgroup_size uses pipeline-overridable constants.
if (!wgsize[0].has_value() || !wgsize[1].has_value() || !wgsize[2].has_value()) {
- error_ =
- "override-expressions should have been removed with the SubstituteOverride "
- "transform";
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "override-expressions should have been removed with the SubstituteOverride "
+ "transform";
return false;
}
- push_execution_mode(
+ module_.PushExecutionMode(
spv::Op::OpExecutionMode,
{Operand(id), U32Operand(SpvExecutionModeLocalSize), //
Operand(wgsize[0].value()), Operand(wgsize[1].value()), Operand(wgsize[2].value())});
@@ -548,8 +476,8 @@
for (auto it : func_sem->TransitivelyReferencedBuiltinVariables()) {
auto builtin = builder_.Sem().Get(it.second)->Value();
if (builtin == builtin::BuiltinValue::kFragDepth) {
- push_execution_mode(spv::Op::OpExecutionMode,
- {Operand(id), U32Operand(SpvExecutionModeDepthReplacing)});
+ module_.PushExecutionMode(spv::Op::OpExecutionMode,
+ {Operand(id), U32Operand(SpvExecutionModeDepthReplacing)});
}
}
@@ -579,7 +507,8 @@
[&](const ast::LiteralExpression* l) { return GenerateLiteralIfNeeded(l); },
[&](const ast::UnaryOpExpression* u) { return GenerateUnaryOpExpression(u); },
[&](Default) {
- error_ = "unknown expression type: " + std::string(expr->TypeInfo().name);
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "unknown expression type: " + std::string(expr->TypeInfo().name);
return 0;
});
}
@@ -599,7 +528,7 @@
auto func_op = result_op();
auto func_id = std::get<uint32_t>(func_op);
- push_debug(spv::Op::OpName, {Operand(func_id), Operand(func_ast->name->symbol.Name())});
+ module_.PushDebug(spv::Op::OpName, {Operand(func_id), Operand(func_ast->name->symbol.Name())});
auto ret_id = GenerateTypeIfNeeded(func->ReturnType());
if (ret_id == 0) {
@@ -623,15 +552,18 @@
return false;
}
- push_debug(spv::Op::OpName,
- {Operand(param_id), Operand(param->Declaration()->name->symbol.Name())});
+ module_.PushDebug(spv::Op::OpName,
+ {Operand(param_id), Operand(param->Declaration()->name->symbol.Name())});
params.push_back(
Instruction{spv::Op::OpFunctionParameter, {Operand(param_type_id), param_op}});
RegisterVariable(param, param_id);
}
- push_function(Function{definition_inst, result_op(), std::move(params)});
+ // Start a new function.
+ current_function_ = Function{definition_inst, result_op(), std::move(params)};
+ current_label_id_ = current_function_.label_id();
+ TINT_DEFER(current_function_ = Function());
for (auto* stmt : func_ast->body->statements) {
if (!GenerateStatement(stmt)) {
@@ -659,6 +591,9 @@
func_symbol_to_id_[func_ast->name->symbol] = func_id;
+ // Add the function to the module.
+ module_.PushFunction(std::move(current_function_));
+
return true;
}
@@ -681,7 +616,7 @@
ops.push_back(Operand(param_type_id));
}
- push_type(spv::Op::OpTypeFunction, std::move(ops));
+ module_.PushType(spv::Op::OpTypeFunction, std::move(ops));
return func_type_id;
});
}
@@ -705,7 +640,7 @@
if (v->Is<ast::Let>()) {
if (!v->initializer) {
- error_ = "missing initializer for let";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "missing initializer for let";
return false;
}
RegisterVariable(sem, init_id);
@@ -721,7 +656,7 @@
return false;
}
- push_debug(spv::Op::OpName, {Operand(var_id), Operand(v->name->symbol.Name())});
+ module_.PushDebug(spv::Op::OpName, {Operand(var_id), Operand(v->name->symbol.Name())});
// TODO(dsinclair) We could detect if the initializer is fully const and emit
// an initializer value for the variable instead of doing the OpLoad.
@@ -782,7 +717,7 @@
return false;
}
- push_debug(spv::Op::OpName, {Operand(var_id), Operand(v->name->symbol.Name())});
+ module_.PushDebug(spv::Op::OpName, {Operand(var_id), Operand(v->name->symbol.Name())});
OperandList ops = {Operand(type_id), result, U32Operand(ConvertAddressSpace(sc))};
@@ -795,12 +730,12 @@
auto access = st ? st->access() : sem->Access();
switch (access) {
case builtin::Access::kWrite:
- push_annot(spv::Op::OpDecorate,
- {Operand(var_id), U32Operand(SpvDecorationNonReadable)});
+ module_.PushAnnot(spv::Op::OpDecorate,
+ {Operand(var_id), U32Operand(SpvDecorationNonReadable)});
break;
case builtin::Access::kRead:
- push_annot(spv::Op::OpDecorate,
- {Operand(var_id), U32Operand(SpvDecorationNonWritable)});
+ module_.PushAnnot(spv::Op::OpDecorate,
+ {Operand(var_id), U32Operand(SpvDecorationNonWritable)});
break;
case builtin::Access::kUndefined:
case builtin::Access::kReadWrite:
@@ -826,21 +761,22 @@
}
}
- push_type(spv::Op::OpVariable, std::move(ops));
+ module_.PushType(spv::Op::OpVariable, std::move(ops));
for (auto* attr : v->attributes) {
bool ok = Switch(
attr,
[&](const ast::BuiltinAttribute* builtin_attr) {
auto builtin = builder_.Sem().Get(builtin_attr)->Value();
- push_annot(spv::Op::OpDecorate,
- {Operand(var_id), U32Operand(SpvDecorationBuiltIn),
- U32Operand(ConvertBuiltin(builtin, sem->AddressSpace()))});
+ module_.PushAnnot(spv::Op::OpDecorate,
+ {Operand(var_id), U32Operand(SpvDecorationBuiltIn),
+ U32Operand(ConvertBuiltin(builtin, sem->AddressSpace()))});
return true;
},
[&](const ast::LocationAttribute*) {
- push_annot(spv::Op::OpDecorate, {Operand(var_id), U32Operand(SpvDecorationLocation),
- Operand(sem->Location().value())});
+ module_.PushAnnot(spv::Op::OpDecorate,
+ {Operand(var_id), U32Operand(SpvDecorationLocation),
+ Operand(sem->Location().value())});
return true;
},
[&](const ast::InterpolateAttribute* interpolate) {
@@ -860,19 +796,20 @@
return true;
},
[&](const ast::InvariantAttribute*) {
- push_annot(spv::Op::OpDecorate,
- {Operand(var_id), U32Operand(SpvDecorationInvariant)});
+ module_.PushAnnot(spv::Op::OpDecorate,
+ {Operand(var_id), U32Operand(SpvDecorationInvariant)});
return true;
},
[&](const ast::BindingAttribute*) {
auto bp = sem->BindingPoint();
- push_annot(spv::Op::OpDecorate, {Operand(var_id), U32Operand(SpvDecorationBinding),
- Operand(bp->binding)});
+ module_.PushAnnot(
+ spv::Op::OpDecorate,
+ {Operand(var_id), U32Operand(SpvDecorationBinding), Operand(bp->binding)});
return true;
},
[&](const ast::GroupAttribute*) {
auto bp = sem->BindingPoint();
- push_annot(
+ module_.PushAnnot(
spv::Op::OpDecorate,
{Operand(var_id), U32Operand(SpvDecorationDescriptorSet), Operand(bp->group)});
return true;
@@ -884,7 +821,7 @@
return true; // ignored
},
[&](Default) {
- error_ = "unknown attribute";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "unknown attribute";
return false;
});
if (!ok) {
@@ -1119,7 +1056,8 @@
return GenerateMemberAccessor(member, &info);
},
[&](Default) {
- error_ = "invalid accessor in list: " + std::string(accessor->TypeInfo().name);
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "invalid accessor in list: " + std::string(accessor->TypeInfo().name);
return false;
});
if (!ok) {
@@ -1157,7 +1095,8 @@
return LookupVariableID(user->Variable());
}
}
- error_ = "identifier '" + expr->identifier->symbol.Name() + "' does not resolve to a variable";
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "identifier '" + expr->identifier->symbol.Name() + "' does not resolve to a variable";
return 0;
}
@@ -1232,7 +1171,7 @@
auto result = result_op();
auto id = std::get<uint32_t>(result);
- push_ext_import(spv::Op::OpExtInstImport, {result, Operand(kGLSLstd450)});
+ module_.PushExtImport(spv::Op::OpExtInstImport, {result, Operand(kGLSLstd450)});
// Remember it for later.
import_name_to_id_[kGLSLstd450] = id;
@@ -1251,7 +1190,7 @@
return GenerateValueConstructorOrConversion(call, var);
}
}
- error_ = "unknown constructor expression";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "unknown constructor expression";
return 0;
}
@@ -1404,9 +1343,9 @@
if (idx_id == 0) {
return 0;
}
- push_type(spv::Op::OpSpecConstantOp,
- {Operand(value_type_id), extract, U32Operand(SpvOpCompositeExtract),
- Operand(id), Operand(idx_id)});
+ module_.PushType(spv::Op::OpSpecConstantOp, {Operand(value_type_id), extract,
+ U32Operand(SpvOpCompositeExtract),
+ Operand(id), Operand(idx_id)});
result_is_spec_composite = true;
}
@@ -1414,7 +1353,7 @@
ops.push_back(Operand(extract_id));
}
} else {
- error_ = "Unhandled type cast value type";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "Unhandled type cast value type";
return 0;
}
}
@@ -1438,9 +1377,9 @@
ops[kOpsResultIdx] = result;
if (result_is_spec_composite) {
- push_type(spv::Op::OpSpecConstantComposite, ops);
+ module_.PushType(spv::Op::OpSpecConstantComposite, ops);
} else if (result_is_constant_composite) {
- push_type(spv::Op::OpConstantComposite, ops);
+ module_.PushType(spv::Op::OpConstantComposite, ops);
} else {
if (!push_function_inst(spv::Op::OpCompositeConstruct, ops)) {
return 0;
@@ -1554,7 +1493,8 @@
zero_id = GenerateConstantIfNeeded(ScalarConstant::I32(0));
one_id = GenerateConstantIfNeeded(ScalarConstant::I32(1));
} else {
- error_ = "invalid destination type for bool conversion";
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "invalid destination type for bool conversion";
return false;
}
if (auto* to_vec = to_type->As<type::Vector>()) {
@@ -1590,9 +1530,9 @@
}
if (op == spv::Op::OpNop) {
- error_ =
- "unable to determine conversion type for cast, from: " + from_type->FriendlyName() +
- " to: " + to_type->FriendlyName();
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "unable to determine conversion type for cast, from: " + from_type->FriendlyName() +
+ " to: " + to_type->FriendlyName();
return 0;
}
@@ -1637,9 +1577,9 @@
return;
}
},
- [&](Default) { error_ = "unknown literal type"; });
+ [&](Default) { TINT_ICE(Writer, builder_.Diagnostics()) << "unknown literal type"; });
- if (!error_.empty()) {
+ if (has_error()) {
return false;
}
@@ -1674,13 +1614,13 @@
}
auto& global_scope = scope_stack_[0];
- return utils::GetOrCreate(global_scope.type_init_to_id_, OperandListKey{ops},
- [&]() -> uint32_t {
- auto result = result_op();
- ops[kOpsResultIdx] = result;
- push_type(spv::Op::OpConstantComposite, std::move(ops));
- return std::get<uint32_t>(result);
- });
+ return utils::GetOrCreate(
+ global_scope.type_init_to_id_, OperandListKey{ops}, [&]() -> uint32_t {
+ auto result = result_op();
+ ops[kOpsResultIdx] = result;
+ module_.PushType(spv::Op::OpConstantComposite, std::move(ops));
+ return std::get<uint32_t>(result);
+ });
};
return Switch(
@@ -1710,14 +1650,15 @@
[&](const type::Array* a) {
auto count = a->ConstantCount();
if (!count) {
- error_ = type::Array::kErrExpectedConstantCount;
+ TINT_ICE(Writer, builder_.Diagnostics()) << type::Array::kErrExpectedConstantCount;
return static_cast<uint32_t>(0);
}
return composite(count.value());
},
[&](const type::Struct* s) { return composite(s->Members().Length()); },
[&](Default) {
- error_ = "unhandled constant type: " + builder_.FriendlyName(ty);
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "unhandled constant type: " + ty->FriendlyName();
return 0;
});
}
@@ -1762,28 +1703,31 @@
switch (constant.kind) {
case ScalarConstant::Kind::kU32: {
- push_type(spv::Op::OpConstant, {Operand(type_id), result, Operand(constant.value.u32)});
+ module_.PushType(spv::Op::OpConstant,
+ {Operand(type_id), result, Operand(constant.value.u32)});
break;
}
case ScalarConstant::Kind::kI32: {
- push_type(spv::Op::OpConstant,
- {Operand(type_id), result, U32Operand(constant.value.i32)});
+ module_.PushType(spv::Op::OpConstant,
+ {Operand(type_id), result, U32Operand(constant.value.i32)});
break;
}
case ScalarConstant::Kind::kF32: {
- push_type(spv::Op::OpConstant, {Operand(type_id), result, Operand(constant.value.f32)});
+ module_.PushType(spv::Op::OpConstant,
+ {Operand(type_id), result, Operand(constant.value.f32)});
break;
}
case ScalarConstant::Kind::kF16: {
- push_type(spv::Op::OpConstant, {Operand(type_id), result,
- U32Operand(constant.value.f16.bits_representation)});
+ module_.PushType(
+ spv::Op::OpConstant,
+ {Operand(type_id), result, U32Operand(constant.value.f16.bits_representation)});
break;
}
case ScalarConstant::Kind::kBool: {
if (constant.value.b) {
- push_type(spv::Op::OpConstantTrue, {Operand(type_id), result});
+ module_.PushType(spv::Op::OpConstantTrue, {Operand(type_id), result});
} else {
- push_type(spv::Op::OpConstantFalse, {Operand(type_id), result});
+ module_.PushType(spv::Op::OpConstantFalse, {Operand(type_id), result});
}
break;
}
@@ -1802,7 +1746,7 @@
return utils::GetOrCreate(const_null_to_id_, type, [&] {
auto result = result_op();
- push_type(spv::Op::OpConstantNull, {Operand(type_id), result});
+ module_.PushType(spv::Op::OpConstantNull, {Operand(type_id), result});
return std::get<uint32_t>(result);
});
@@ -1825,7 +1769,7 @@
for (uint32_t i = 0; i < type->Width(); i++) {
ops.push_back(Operand(value_id));
}
- push_type(spv::Op::OpConstantComposite, ops);
+ module_.PushType(spv::Op::OpConstantComposite, ops);
const_splat_to_id_[key] = result_id;
return result_id;
@@ -2025,7 +1969,8 @@
// This should already have been validated by resolver
if (lhs_mat->rows() != rhs_mat->rows() || lhs_mat->columns() != rhs_mat->columns()) {
- error_ = "matrices must have same dimensionality for add or subtract";
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "matrices must have same dimensionality for add or subtract";
return 0;
}
@@ -2070,7 +2015,7 @@
} else if (lhs_is_bool_or_vec) {
op = spv::Op::OpLogicalAnd;
} else {
- error_ = "invalid and expression";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "invalid and expression";
return 0;
}
} else if (expr->IsAdd()) {
@@ -2091,7 +2036,7 @@
} else if (lhs_is_integer_or_vec) {
op = spv::Op::OpIEqual;
} else {
- error_ = "invalid equal expression";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "invalid equal expression";
return 0;
}
} else if (expr->IsGreaterThan()) {
@@ -2171,7 +2116,7 @@
// float matrix * matrix
op = spv::Op::OpMatrixTimesMatrix;
} else {
- error_ = "invalid multiply expression";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "invalid multiply expression";
return 0;
}
} else if (expr->IsNotEqual()) {
@@ -2182,7 +2127,7 @@
} else if (lhs_is_integer_or_vec) {
op = spv::Op::OpINotEqual;
} else {
- error_ = "invalid not-equal expression";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "invalid not-equal expression";
return 0;
}
} else if (expr->IsOr()) {
@@ -2191,7 +2136,7 @@
} else if (lhs_is_bool_or_vec) {
op = spv::Op::OpLogicalOr;
} else {
- error_ = "invalid and expression";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "invalid and expression";
return 0;
}
} else if (expr->IsShiftLeft()) {
@@ -2206,7 +2151,7 @@
} else if (expr->IsXor()) {
op = spv::Op::OpBitwiseXor;
} else {
- error_ = "unknown binary expression";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "unknown binary expression";
return 0;
}
@@ -2267,7 +2212,8 @@
auto func_id = func_symbol_to_id_[ident->symbol];
if (func_id == 0) {
- error_ = "unable to find called function: " + ident->symbol.Name();
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "unable to find called function: " + ident->symbol.Name();
return 0;
}
ops.push_back(Operand(func_id));
@@ -2297,11 +2243,11 @@
}
if (builtin->IsFineDerivative() || builtin->IsCoarseDerivative()) {
- push_capability(SpvCapabilityDerivativeControl);
+ module_.PushCapability(SpvCapabilityDerivativeControl);
}
if (builtin->IsImageQuery()) {
- push_capability(SpvCapabilityImageQuery);
+ module_.PushCapability(SpvCapabilityImageQuery);
}
if (builtin->IsTexture()) {
@@ -2371,16 +2317,18 @@
case builtin::Function::kArrayLength: {
auto* address_of = call->Arguments()[0]->Declaration()->As<ast::UnaryOpExpression>();
if (!address_of || address_of->op != ast::UnaryOp::kAddressOf) {
- error_ = "arrayLength() expected pointer to member access, got " +
- std::string(address_of->TypeInfo().name);
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "arrayLength() expected pointer to member access, got " +
+ std::string(address_of->TypeInfo().name);
return 0;
}
auto* array_expr = address_of->expr;
auto* accessor = array_expr->As<ast::MemberAccessorExpression>();
if (!accessor) {
- error_ = "arrayLength() expected pointer to member access, got pointer to " +
- std::string(array_expr->TypeInfo().name);
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "arrayLength() expected pointer to member access, got pointer to " +
+ std::string(array_expr->TypeInfo().name);
return 0;
}
@@ -2392,7 +2340,8 @@
auto* type = TypeOf(accessor->object)->UnwrapRef();
if (!type->Is<type::Struct>()) {
- error_ = "invalid type (" + type->FriendlyName() + ") for runtime array length";
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "invalid type (" + type->FriendlyName() + ") for runtime array length";
return 0;
}
// Runtime array must be the last member in the structure
@@ -2589,7 +2538,8 @@
default: {
auto inst_id = builtin_to_glsl_method(builtin);
if (inst_id == 0) {
- error_ = "unknown method " + std::string(builtin->str());
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "unknown method " + std::string(builtin->str());
return 0;
}
glsl_std450(inst_id);
@@ -2598,7 +2548,8 @@
}
if (op == spv::Op::OpNop) {
- error_ = "unable to determine operator for: " + std::string(builtin->str());
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "unable to determine operator for: " + std::string(builtin->str());
return 0;
}
@@ -2789,7 +2740,7 @@
uint32_t spirv_dims = 0;
switch (texture_type->dim()) {
case type::TextureDimension::kNone:
- error_ = "texture dimension is kNone";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "texture dimension is kNone";
return false;
case type::TextureDimension::k1d:
case type::TextureDimension::k2d:
@@ -2826,7 +2777,7 @@
uint32_t spirv_dims = 0;
switch (texture_type->dim()) {
default:
- error_ = "texture is not arrayed";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "texture is not arrayed";
return false;
case type::TextureDimension::k2dArray:
case type::TextureDimension::kCubeArray:
@@ -3016,7 +2967,8 @@
}
if (op == spv::Op::OpNop) {
- error_ = "unable to determine operator for: " + std::string(builtin->str());
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "unable to determine operator for: " + std::string(builtin->str());
return false;
}
@@ -3046,8 +2998,8 @@
semantics = static_cast<uint32_t>(spv::MemorySemanticsMask::AcquireRelease) |
static_cast<uint32_t>(spv::MemorySemanticsMask::UniformMemory);
} else {
- error_ = "unexpected barrier builtin type ";
- error_ += builtin::str(builtin->Type());
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "unexpected barrier builtin type " << builtin::str(builtin->Type());
return false;
}
@@ -3290,7 +3242,8 @@
// We need to create the sampled image type and cache the result.
auto sampled_image_type = result_op();
auto texture_type_id = GenerateTypeIfNeeded(texture_type);
- push_type(spv::Op::OpTypeSampledImage, {sampled_image_type, Operand(texture_type_id)});
+ module_.PushType(spv::Op::OpTypeSampledImage,
+ {sampled_image_type, Operand(texture_type_id)});
return std::get<uint32_t>(sampled_image_type);
});
@@ -3357,7 +3310,7 @@
// if there are no more else statements we branch on false to the merge
// block otherwise we branch to the false block
- auto false_block_id = else_stmt ? next_id() : merge_block_id;
+ auto false_block_id = else_stmt ? module_.NextId() : merge_block_id;
if (!push_function_inst(spv::Op::OpBranchConditional,
{Operand(cond_id), Operand(true_block_id), Operand(false_block_id)})) {
@@ -3620,7 +3573,8 @@
return true; // Not emitted
},
[&](Default) {
- error_ = "unknown statement type: " + std::string(stmt->TypeInfo().name);
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "unknown statement type: " + std::string(stmt->TypeInfo().name);
return false;
});
}
@@ -3631,7 +3585,7 @@
uint32_t Builder::GenerateTypeIfNeeded(const type::Type* type) {
if (type == nullptr) {
- error_ = "attempting to generate type from null type";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "attempting to generate type from null type";
return 0;
}
@@ -3677,19 +3631,19 @@
return GenerateArrayType(arr, result);
},
[&](const type::Bool*) {
- push_type(spv::Op::OpTypeBool, {result});
+ module_.PushType(spv::Op::OpTypeBool, {result});
return true;
},
[&](const type::F32*) {
- push_type(spv::Op::OpTypeFloat, {result, Operand(32u)});
+ module_.PushType(spv::Op::OpTypeFloat, {result, Operand(32u)});
return true;
},
[&](const type::F16*) {
- push_type(spv::Op::OpTypeFloat, {result, Operand(16u)});
+ module_.PushType(spv::Op::OpTypeFloat, {result, Operand(16u)});
return true;
},
[&](const type::I32*) {
- push_type(spv::Op::OpTypeInt, {result, Operand(32u), Operand(1u)});
+ module_.PushType(spv::Op::OpTypeInt, {result, Operand(32u), Operand(1u)});
return true;
},
[&](const type::Matrix* mat) { //
@@ -3705,14 +3659,14 @@
return GenerateStructType(str, result);
},
[&](const type::U32*) {
- push_type(spv::Op::OpTypeInt, {result, Operand(32u), Operand(0u)});
+ module_.PushType(spv::Op::OpTypeInt, {result, Operand(32u), Operand(0u)});
return true;
},
[&](const type::Vector* vec) { //
return GenerateVectorType(vec, result);
},
[&](const type::Void*) {
- push_type(spv::Op::OpTypeVoid, {result});
+ module_.PushType(spv::Op::OpTypeVoid, {result});
return true;
},
[&](const type::StorageTexture* tex) {
@@ -3734,7 +3688,7 @@
},
[&](const type::Texture* tex) { return GenerateTextureType(tex, result); },
[&](const type::Sampler* s) {
- push_type(spv::Op::OpTypeSampler, {result});
+ module_.PushType(spv::Op::OpTypeSampler, {result});
// Register both of the sampler type names. In SPIR-V they're the same
// sampler type, so we need to match that when we do the dedup check.
@@ -3747,7 +3701,8 @@
return true;
},
[&](Default) {
- error_ = "unable to convert type: " + type->FriendlyName();
+ TINT_ICE(Writer, builder_.Diagnostics())
+ << "unable to convert type: " + type->FriendlyName();
return false;
});
@@ -3776,9 +3731,9 @@
if (dim == type::TextureDimension::k1d) {
dim_literal = SpvDim1D;
if (texture->Is<type::SampledTexture>()) {
- push_capability(SpvCapabilitySampled1D);
+ module_.PushCapability(SpvCapabilitySampled1D);
} else if (texture->Is<type::StorageTexture>()) {
- push_capability(SpvCapabilityImage1D);
+ module_.PushCapability(SpvCapabilityImage1D);
}
}
if (dim == type::TextureDimension::k3d) {
@@ -3806,7 +3761,7 @@
if (dim == type::TextureDimension::kCubeArray) {
if (texture->IsAnyOf<type::SampledTexture, type::DepthTexture>()) {
- push_capability(SpvCapabilitySampledCubeArray);
+ module_.PushCapability(SpvCapabilitySampledCubeArray);
}
}
@@ -3831,10 +3786,10 @@
format_literal = convert_texel_format_to_spv(t->texel_format());
}
- push_type(spv::Op::OpTypeImage,
- {result, Operand(type_id), Operand(dim_literal), Operand(depth_literal),
- Operand(array_literal), Operand(ms_literal), Operand(sampled_literal),
- Operand(format_literal)});
+ module_.PushType(spv::Op::OpTypeImage,
+ {result, Operand(type_id), Operand(dim_literal), Operand(depth_literal),
+ Operand(array_literal), Operand(ms_literal), Operand(sampled_literal),
+ Operand(format_literal)});
return true;
}
@@ -3847,11 +3802,11 @@
auto result_id = std::get<uint32_t>(result);
if (arr->Count()->Is<type::RuntimeArrayCount>()) {
- push_type(spv::Op::OpTypeRuntimeArray, {result, Operand(elem_type)});
+ module_.PushType(spv::Op::OpTypeRuntimeArray, {result, Operand(elem_type)});
} else {
auto count = arr->ConstantCount();
if (!count) {
- error_ = type::Array::kErrExpectedConstantCount;
+ TINT_ICE(Writer, builder_.Diagnostics()) << type::Array::kErrExpectedConstantCount;
return static_cast<uint32_t>(0);
}
@@ -3860,11 +3815,12 @@
return false;
}
- push_type(spv::Op::OpTypeArray, {result, Operand(elem_type), Operand(len_id)});
+ module_.PushType(spv::Op::OpTypeArray, {result, Operand(elem_type), Operand(len_id)});
}
- push_annot(spv::Op::OpDecorate,
- {Operand(result_id), U32Operand(SpvDecorationArrayStride), Operand(arr->Stride())});
+ module_.PushAnnot(
+ spv::Op::OpDecorate,
+ {Operand(result_id), U32Operand(SpvDecorationArrayStride), Operand(arr->Stride())});
return true;
}
@@ -3875,7 +3831,8 @@
return false;
}
- push_type(spv::Op::OpTypeMatrix, {result, Operand(col_type_id), Operand(mat->columns())});
+ module_.PushType(spv::Op::OpTypeMatrix,
+ {result, Operand(col_type_id), Operand(mat->columns())});
return true;
}
@@ -3887,11 +3844,11 @@
auto stg_class = ConvertAddressSpace(ptr->AddressSpace());
if (stg_class == SpvStorageClassMax) {
- error_ = "invalid address space for pointer";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "invalid address space for pointer";
return false;
}
- push_type(spv::Op::OpTypePointer, {result, U32Operand(stg_class), Operand(subtype_id)});
+ module_.PushType(spv::Op::OpTypePointer, {result, U32Operand(stg_class), Operand(subtype_id)});
return true;
}
@@ -3904,11 +3861,11 @@
auto stg_class = ConvertAddressSpace(ref->AddressSpace());
if (stg_class == SpvStorageClassMax) {
- error_ = "invalid address space for reference";
+ TINT_ICE(Writer, builder_.Diagnostics()) << "invalid address space for reference";
return false;
}
- push_type(spv::Op::OpTypePointer, {result, U32Operand(stg_class), Operand(subtype_id)});
+ module_.PushType(spv::Op::OpTypePointer, {result, U32Operand(stg_class), Operand(subtype_id)});
return true;
}
@@ -3917,7 +3874,8 @@
auto struct_id = std::get<uint32_t>(result);
if (struct_type->Name().IsValid()) {
- push_debug(spv::Op::OpName, {Operand(struct_id), Operand(struct_type->Name().Name())});
+ module_.PushDebug(spv::Op::OpName,
+ {Operand(struct_id), Operand(struct_type->Name().Name())});
}
OperandList ops;
@@ -3926,7 +3884,8 @@
if (auto* sem_str = struct_type->As<sem::Struct>()) {
auto* decl = sem_str->Declaration();
if (ast::HasAttribute<transform::AddBlockAttribute::BlockAttribute>(decl->attributes)) {
- push_annot(spv::Op::OpDecorate, {Operand(struct_id), U32Operand(SpvDecorationBlock)});
+ module_.PushAnnot(spv::Op::OpDecorate,
+ {Operand(struct_id), U32Operand(SpvDecorationBlock)});
}
}
@@ -3939,15 +3898,15 @@
ops.push_back(Operand(mem_id));
}
- push_type(spv::Op::OpTypeStruct, std::move(ops));
+ module_.PushType(spv::Op::OpTypeStruct, std::move(ops));
return true;
}
uint32_t Builder::GenerateStructMember(uint32_t struct_id,
uint32_t idx,
const type::StructMember* member) {
- push_debug(spv::Op::OpMemberName,
- {Operand(struct_id), Operand(idx), Operand(member->Name().Name())});
+ module_.PushDebug(spv::Op::OpMemberName,
+ {Operand(struct_id), Operand(idx), Operand(member->Name().Name())});
// Note: This will generate layout annotations for *all* structs, whether or
// not they are used in host-shareable variables. This is officially ok in
@@ -3955,20 +3914,20 @@
// to only generate the layout info for structs used for certain storage
// classes.
- push_annot(spv::Op::OpMemberDecorate,
- {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationOffset),
- Operand(member->Offset())});
+ module_.PushAnnot(spv::Op::OpMemberDecorate,
+ {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationOffset),
+ Operand(member->Offset())});
// Infer and emit matrix layout.
auto* matrix_type = GetNestedMatrixType(member->Type());
if (matrix_type) {
- push_annot(spv::Op::OpMemberDecorate,
- {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationColMajor)});
+ module_.PushAnnot(spv::Op::OpMemberDecorate,
+ {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationColMajor)});
const uint32_t scalar_elem_size = matrix_type->type()->Size();
const uint32_t effective_row_count = (matrix_type->rows() == 2) ? 2 : 4;
- push_annot(spv::Op::OpMemberDecorate,
- {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationMatrixStride),
- Operand(effective_row_count * scalar_elem_size)});
+ module_.PushAnnot(spv::Op::OpMemberDecorate,
+ {Operand(struct_id), Operand(idx), U32Operand(SpvDecorationMatrixStride),
+ Operand(effective_row_count * scalar_elem_size)});
}
return GenerateTypeIfNeeded(member->Type());
@@ -3980,7 +3939,7 @@
return false;
}
- push_type(spv::Op::OpTypeVector, {result, Operand(type_id), Operand(vec->Width())});
+ module_.PushType(spv::Op::OpTypeVector, {result, Operand(type_id), Operand(vec->Width())});
return true;
}
@@ -4042,7 +4001,7 @@
case builtin::BuiltinValue::kNumWorkgroups:
return SpvBuiltInNumWorkgroups;
case builtin::BuiltinValue::kSampleIndex:
- push_capability(SpvCapabilitySampleRateShading);
+ module_.PushCapability(SpvCapabilitySampleRateShading);
return SpvBuiltInSampleId;
case builtin::BuiltinValue::kSampleMask:
return SpvBuiltInSampleMask;
@@ -4057,10 +4016,11 @@
builtin::InterpolationSampling sampling) {
switch (type) {
case builtin::InterpolationType::kLinear:
- push_annot(spv::Op::OpDecorate, {Operand(id), U32Operand(SpvDecorationNoPerspective)});
+ module_.PushAnnot(spv::Op::OpDecorate,
+ {Operand(id), U32Operand(SpvDecorationNoPerspective)});
break;
case builtin::InterpolationType::kFlat:
- push_annot(spv::Op::OpDecorate, {Operand(id), U32Operand(SpvDecorationFlat)});
+ module_.PushAnnot(spv::Op::OpDecorate, {Operand(id), U32Operand(SpvDecorationFlat)});
break;
case builtin::InterpolationType::kPerspective:
case builtin::InterpolationType::kUndefined:
@@ -4068,11 +4028,12 @@
}
switch (sampling) {
case builtin::InterpolationSampling::kCentroid:
- push_annot(spv::Op::OpDecorate, {Operand(id), U32Operand(SpvDecorationCentroid)});
+ module_.PushAnnot(spv::Op::OpDecorate,
+ {Operand(id), U32Operand(SpvDecorationCentroid)});
break;
case builtin::InterpolationSampling::kSample:
- push_capability(SpvCapabilitySampleRateShading);
- push_annot(spv::Op::OpDecorate, {Operand(id), U32Operand(SpvDecorationSample)});
+ module_.PushCapability(SpvCapabilitySampleRateShading);
+ module_.PushAnnot(spv::Op::OpDecorate, {Operand(id), U32Operand(SpvDecorationSample)});
break;
case builtin::InterpolationSampling::kCenter:
case builtin::InterpolationSampling::kUndefined:
@@ -4101,13 +4062,13 @@
case builtin::TexelFormat::kRgba8Sint:
return SpvImageFormatRgba8i;
case builtin::TexelFormat::kRg32Uint:
- push_capability(SpvCapabilityStorageImageExtendedFormats);
+ module_.PushCapability(SpvCapabilityStorageImageExtendedFormats);
return SpvImageFormatRg32ui;
case builtin::TexelFormat::kRg32Sint:
- push_capability(SpvCapabilityStorageImageExtendedFormats);
+ module_.PushCapability(SpvCapabilityStorageImageExtendedFormats);
return SpvImageFormatRg32i;
case builtin::TexelFormat::kRg32Float:
- push_capability(SpvCapabilityStorageImageExtendedFormats);
+ module_.PushCapability(SpvCapabilityStorageImageExtendedFormats);
return SpvImageFormatRg32f;
case builtin::TexelFormat::kRgba16Uint:
return SpvImageFormatRgba16ui;
@@ -4128,22 +4089,22 @@
}
bool Builder::push_function_inst(spv::Op op, const OperandList& operands) {
- if (functions_.empty()) {
+ if (!current_function_) {
utils::StringStream ss;
ss << "Internal error: trying to add SPIR-V instruction " << int(op)
<< " outside a function";
- error_ = ss.str();
+ TINT_ICE(Writer, builder_.Diagnostics()) << ss.str();
return false;
}
- functions_.back().push_inst(op, operands);
+ current_function_.push_inst(op, operands);
return true;
}
bool Builder::InsideBasicBlock() const {
- if (functions_.empty()) {
+ if (!current_function_) {
return false;
}
- const auto& instructions = functions_.back().instructions();
+ const auto& instructions = current_function_.instructions();
if (instructions.empty()) {
// The Function object does not explicitly represent its entry block
// label. So return *true* because an empty list means the only
diff --git a/src/tint/writer/spirv/builder.h b/src/tint/writer/spirv/builder.h
index 1bbffc8..17e96cd 100644
--- a/src/tint/writer/spirv/builder.h
+++ b/src/tint/writer/spirv/builder.h
@@ -15,6 +15,7 @@
#ifndef SRC_TINT_WRITER_SPIRV_BUILDER_H_
#define SRC_TINT_WRITER_SPIRV_BUILDER_H_
+#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
@@ -39,6 +40,7 @@
#include "src/tint/sem/builtin.h"
#include "src/tint/type/storage_texture.h"
#include "src/tint/writer/spirv/function.h"
+#include "src/tint/writer/spirv/module.h"
#include "src/tint/writer/spirv/scalar_constant.h"
// Forward declarations
@@ -54,7 +56,7 @@
namespace tint::writer::spirv {
-/// Builder class to create SPIR-V instructions from a module.
+/// Builder class to create a SPIR-V module from a Tint AST.
class Builder {
public:
/// Contains information for generating accessor chains
@@ -87,105 +89,23 @@
/// @returns true if the SPIR-V was successfully built
bool Build();
- /// @returns the error string or blank if no error was reported.
- const std::string& error() const { return error_; }
+ /// @returns the list of diagnostics raised by the builder
+ const diag::List& Diagnostics() const { return builder_.Diagnostics(); }
+
/// @returns true if the builder encountered an error
- bool has_error() const { return !error_.empty(); }
+ bool has_error() const { return Diagnostics().contains_errors(); }
- /// @returns the number of uint32_t's needed to make up the results
- uint32_t total_size() const;
+ /// @returns the module that this builder has produced
+ spirv::Module& Module() { return module_; }
- /// @returns the id bound for this program
- uint32_t id_bound() const { return next_id_; }
-
- /// @returns the next id to be used
- uint32_t next_id() {
- auto id = next_id_;
- next_id_ += 1;
- return id;
+ /// Add an empty function to the builder, to be used for testing purposes.
+ void PushFunctionForTesting() {
+ current_function_ = Function(Instruction(spv::Op::OpFunction, {}), {}, {});
}
- /// Iterates over all the instructions in the correct order and calls the
- /// given callback
- /// @param cb the callback to execute
- void iterate(std::function<void(const Instruction&)> cb) const;
+ /// @returns the current function
+ const Function& CurrentFunction() { return current_function_; }
- /// Adds an instruction to the list of capabilities, if the capability
- /// hasn't already been added.
- /// @param cap the capability to set
- void push_capability(uint32_t cap);
- /// @returns the capabilities
- const InstructionList& capabilities() const { return capabilities_; }
- /// Adds an instruction to the extensions
- /// @param extension the name of the extension
- void push_extension(const char* extension);
- /// @returns the extensions
- const InstructionList& extensions() const { return extensions_; }
- /// Adds an instruction to the ext import
- /// @param op the op to set
- /// @param operands the operands for the instruction
- void push_ext_import(spv::Op op, const OperandList& operands) {
- ext_imports_.push_back(Instruction{op, operands});
- }
- /// @returns the ext imports
- const InstructionList& ext_imports() const { return ext_imports_; }
- /// Adds an instruction to the memory model
- /// @param op the op to set
- /// @param operands the operands for the instruction
- void push_memory_model(spv::Op op, const OperandList& operands) {
- memory_model_.push_back(Instruction{op, operands});
- }
- /// @returns the memory model
- const InstructionList& memory_model() const { return memory_model_; }
- /// Adds an instruction to the entry points
- /// @param op the op to set
- /// @param operands the operands for the instruction
- void push_entry_point(spv::Op op, const OperandList& operands) {
- entry_points_.push_back(Instruction{op, operands});
- }
- /// @returns the entry points
- const InstructionList& entry_points() const { return entry_points_; }
- /// Adds an instruction to the execution modes
- /// @param op the op to set
- /// @param operands the operands for the instruction
- void push_execution_mode(spv::Op op, const OperandList& operands) {
- execution_modes_.push_back(Instruction{op, operands});
- }
- /// @returns the execution modes
- const InstructionList& execution_modes() const { return execution_modes_; }
- /// Adds an instruction to the debug
- /// @param op the op to set
- /// @param operands the operands for the instruction
- void push_debug(spv::Op op, const OperandList& operands) {
- debug_.push_back(Instruction{op, operands});
- }
- /// @returns the debug instructions
- const InstructionList& debug() const { return debug_; }
- /// Adds an instruction to the types
- /// @param op the op to set
- /// @param operands the operands for the instruction
- void push_type(spv::Op op, const OperandList& operands) {
- types_.push_back(Instruction{op, operands});
- }
- /// @returns the type instructions
- const InstructionList& types() const { return types_; }
- /// Adds an instruction to the annotations
- /// @param op the op to set
- /// @param operands the operands for the instruction
- void push_annot(spv::Op op, const OperandList& operands) {
- annotations_.push_back(Instruction{op, operands});
- }
- /// @returns the annotations
- const InstructionList& annots() const { return annotations_; }
-
- /// Adds a function to the builder
- /// @param func the function to add
- void push_function(const Function& func) {
- functions_.push_back(func);
- current_label_id_ = func.label_id();
- }
- /// @returns the functions
- const std::vector<Function>& functions() const { return functions_; }
/// Pushes an instruction to the current function. If we're outside
/// a function then issue an internal error and return false.
/// @param op the operation
@@ -195,11 +115,11 @@
/// Pushes a variable to the current function
/// @param operands the variable operands
void push_function_var(const OperandList& operands) {
- if (TINT_UNLIKELY(functions_.empty())) {
+ if (TINT_UNLIKELY(!current_function_)) {
TINT_ICE(Writer, builder_.Diagnostics())
<< "push_function_var() called without a function";
}
- functions_.back().push_var(operands);
+ current_function_.push_var(operands);
}
/// @returns true if the current instruction insertion point is
@@ -590,19 +510,9 @@
void PopScope();
ProgramBuilder builder_;
- std::string error_;
- uint32_t next_id_ = 1;
+ spirv::Module module_;
+ Function current_function_;
uint32_t current_label_id_ = 0;
- InstructionList capabilities_;
- InstructionList extensions_;
- InstructionList ext_imports_;
- InstructionList memory_model_;
- InstructionList entry_points_;
- InstructionList execution_modes_;
- InstructionList debug_;
- InstructionList types_;
- InstructionList annotations_;
- std::vector<Function> functions_;
// Scope holds per-block information
struct Scope {
@@ -625,7 +535,6 @@
std::vector<Scope> scope_stack_;
std::vector<uint32_t> merge_stack_;
std::vector<uint32_t> continue_stack_;
- std::unordered_set<uint32_t> capability_set_;
bool zero_initialize_workgroup_memory_ = false;
struct ContinuingInfo {
diff --git a/src/tint/writer/spirv/builder_accessor_expression_test.cc b/src/tint/writer/spirv/builder_accessor_expression_test.cc
index e6692ab..d93b414 100644
--- a/src/tint/writer/spirv/builder_accessor_expression_test.cc
+++ b/src/tint/writer/spirv/builder_accessor_expression_test.cc
@@ -32,9 +32,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeInt 32 1
%5 = OpTypeVector %6 3
@@ -45,9 +45,10 @@
%13 = OpTypePointer Function %6
%14 = OpConstantNull %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%12 = OpVariable %13 Function %14
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%12 = OpVariable %13 Function %14
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%11 = OpCompositeExtract %6 %10 1
OpStore %12 %11
OpReturn
@@ -66,18 +67,19 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeInt 32 1
%6 = OpConstant %5 2
%8 = OpTypePointer Function %5
%9 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%7 = OpVariable %8 Function %9
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%7 = OpVariable %8 Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(OpStore %7 %6
OpReturn
)");
@@ -95,9 +97,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%8 = OpTypeInt 32 0
%7 = OpTypeVector %8 3
@@ -108,10 +110,12 @@
%12 = OpTypePointer Function %8
%16 = OpConstantNull %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %9
%15 = OpVariable %12 Function %16
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpAccessChain %12 %5 %11
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+ R"(%13 = OpAccessChain %12 %5 %11
%14 = OpLoad %8 %13
OpStore %15 %14
OpReturn
@@ -132,9 +136,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%8 = OpTypeFloat 32
%7 = OpTypeVector %8 3
@@ -146,11 +150,12 @@
%15 = OpTypePointer Function %8
%19 = OpConstantNull %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %9
%10 = OpVariable %11 Function %13
%18 = OpVariable %15 Function %19
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%14 = OpLoad %12 %10
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(%14 = OpLoad %12 %10
%16 = OpAccessChain %15 %5 %14
%17 = OpLoad %8 %16
OpStore %18 %17
@@ -170,9 +175,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeInt 32 1
%5 = OpTypeVector %6 3
@@ -183,9 +188,10 @@
%13 = OpTypePointer Function %6
%14 = OpConstantNull %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%12 = OpVariable %13 Function %14
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%12 = OpVariable %13 Function %14
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%11 = OpCompositeExtract %6 %10 2
OpStore %12 %11
OpReturn
@@ -204,9 +210,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%8 = OpTypeFloat 32
%7 = OpTypeVector %8 3
@@ -217,10 +223,12 @@
%12 = OpTypePointer Function %8
%16 = OpConstantNull %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %9
%15 = OpVariable %12 Function %16
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpAccessChain %12 %5 %11
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+ R"(%13 = OpAccessChain %12 %5 %11
%14 = OpLoad %8 %13
OpStore %15 %14
OpReturn
@@ -241,9 +249,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%8 = OpTypeFloat 32
%7 = OpTypeVector %8 3
@@ -257,11 +265,12 @@
%18 = OpTypePointer Function %8
%22 = OpConstantNull %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %9
%12 = OpVariable %13 Function %14
%21 = OpVariable %18 Function %22
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %12 %11
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %12 %11
%15 = OpLoad %10 %12
%17 = OpIAdd %10 %15 %16
%19 = OpAccessChain %18 %5 %17
@@ -284,9 +293,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%7 = OpTypeFloat 32
%6 = OpTypeVector %7 3
@@ -308,9 +317,10 @@
%25 = OpTypePointer Function %7
%26 = OpConstantNull %7
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%24 = OpVariable %25 Function %26
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%24 = OpVariable %25 Function %26
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%21 = OpCompositeExtract %6 %18 1
%23 = OpCompositeExtract %7 %21 2
OpStore %24 %23
@@ -331,18 +341,19 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeFloat 32
%6 = OpConstant %5 6
%8 = OpTypePointer Function %5
%9 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%7 = OpVariable %8 Function %9
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%7 = OpVariable %8 Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(OpStore %7 %6
OpReturn
)");
@@ -360,9 +371,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%9 = OpTypeFloat 32
%8 = OpTypeVector %9 3
@@ -377,10 +388,11 @@
%16 = OpTypePointer Function %9
%20 = OpConstantNull %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %12
%19 = OpVariable %16 Function %20
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%17 = OpAccessChain %16 %5 %14 %15
%18 = OpLoad %9 %17
OpStore %19 %18
@@ -402,9 +414,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%9 = OpTypeFloat 32
%8 = OpTypeVector %9 3
@@ -421,11 +433,12 @@
%20 = OpTypePointer Function %9
%24 = OpConstantNull %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %12
%15 = OpVariable %16 Function %17
%23 = OpVariable %20 Function %24
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %15 %14
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %15 %14
%18 = OpLoad %13 %15
%21 = OpAccessChain %20 %5 %18 %19
%22 = OpLoad %9 %21
@@ -447,9 +460,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%7 = OpTypeFloat 32
%6 = OpTypeVector %7 3
@@ -471,9 +484,10 @@
%25 = OpTypePointer Function %22
%26 = OpConstantNull %22
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%24 = OpVariable %25 Function %26
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%24 = OpVariable %25 Function %26
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%21 = OpCompositeExtract %6 %18 1
%23 = OpVectorShuffle %22 %21 %21 0 1
OpStore %24 %23
@@ -493,9 +507,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%9 = OpTypeFloat 32
%8 = OpTypeVector %9 3
@@ -511,10 +525,12 @@
%21 = OpTypePointer Function %17
%22 = OpConstantNull %17
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %12
%20 = OpVariable %21 Function %22
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%16 = OpAccessChain %15 %5 %14
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+ R"(%16 = OpAccessChain %15 %5 %14
%18 = OpLoad %8 %16
%19 = OpVectorShuffle %17 %18 %18 0 1
OpStore %20 %19
@@ -536,9 +552,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%9 = OpTypeFloat 32
%8 = OpTypeVector %9 3
@@ -556,11 +572,12 @@
%25 = OpTypePointer Function %21
%26 = OpConstantNull %21
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %12
%15 = OpVariable %16 Function %17
%24 = OpVariable %25 Function %26
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %15 %14
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %15 %14
%18 = OpLoad %13 %15
%20 = OpAccessChain %19 %5 %18
%22 = OpLoad %8 %20
@@ -587,9 +604,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%7 = OpTypeFloat 32
%6 = OpTypeVector %7 2
@@ -607,9 +624,10 @@
%19 = OpConstantNull %8
%22 = OpTypePointer Function %7
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%21 = OpVariable %22 Function %10
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%21 = OpVariable %22 Function %10
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%18 = OpCompositeExtract %6 %16 1
%20 = OpCompositeExtract %7 %18 0
OpStore %21 %20
@@ -634,18 +652,19 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeFloat 32
%6 = OpConstant %5 -0.5
%8 = OpTypePointer Function %5
%9 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%7 = OpVariable %8 Function %9
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%7 = OpVariable %8 Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(OpStore %7 %6
OpReturn
)");
@@ -663,9 +682,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%9 = OpTypeFloat 32
%8 = OpTypeVector %9 3
@@ -679,10 +698,11 @@
%15 = OpTypePointer Function %9
%19 = OpConstantNull %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %12
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %12
%18 = OpVariable %15 Function %19
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%16 = OpAccessChain %15 %5 %13 %14
%17 = OpLoad %9 %16
OpStore %18 %17
@@ -704,9 +724,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%9 = OpTypeFloat 32
%10 = OpTypeInt 32 0
@@ -722,11 +742,12 @@
%19 = OpTypePointer Function %9
%23 = OpConstantNull %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %13
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %13
%15 = OpVariable %16 Function %17
%22 = OpVariable %19 Function %23
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %15 %14
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %15 %14
%18 = OpLoad %10 %15
%20 = OpAccessChain %19 %5 %18 %14
%21 = OpLoad %9 %20
@@ -749,9 +770,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%7 = OpTypeFloat 32
%6 = OpTypeVector %7 2
@@ -768,9 +789,10 @@
%19 = OpTypePointer Function %6
%20 = OpConstantNull %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%18 = OpVariable %19 Function %20
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%18 = OpVariable %19 Function %20
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%17 = OpCompositeExtract %6 %14 1
OpStore %18 %17
OpReturn
@@ -791,9 +813,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 2
@@ -803,9 +825,10 @@
%11 = OpTypePointer Function %5
%12 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%10 = OpVariable %11 Function %12
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%10 = OpVariable %11 Function %12
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(OpStore %10 %9
OpReturn
)");
@@ -823,9 +846,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%9 = OpTypeFloat 32
%8 = OpTypeVector %9 2
@@ -837,10 +860,12 @@
%13 = OpTypePointer Function %8
%17 = OpConstantNull %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %10
%16 = OpVariable %13 Function %17
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%14 = OpAccessChain %13 %5 %12
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+ R"(%14 = OpAccessChain %13 %5 %12
%15 = OpLoad %8 %14
OpStore %16 %15
OpReturn
@@ -861,9 +886,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%9 = OpTypeFloat 32
%8 = OpTypeVector %9 2
@@ -876,11 +901,12 @@
%16 = OpTypePointer Function %8
%20 = OpConstantNull %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %10
%11 = OpVariable %12 Function %14
%19 = OpVariable %16 Function %20
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%15 = OpLoad %13 %11
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(%15 = OpLoad %13 %11
%17 = OpAccessChain %16 %5 %15
%18 = OpLoad %8 %17
OpStore %19 %18
@@ -910,9 +936,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%8 = OpTypeFloat 32
%7 = OpTypeStruct %8 %8
@@ -922,9 +948,11 @@
%11 = OpConstant %10 1
%12 = OpTypePointer Function %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpAccessChain %12 %5 %11
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+ R"(%13 = OpAccessChain %12 %5 %11
%14 = OpLoad %8 %13
OpReturn
)");
@@ -956,9 +984,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%9 = OpTypeFloat 32
%8 = OpTypeStruct %9 %9
@@ -970,9 +998,10 @@
%13 = OpConstant %11 1
%14 = OpTypePointer Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %10
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%15 = OpAccessChain %14 %5 %12 %13
%16 = OpLoad %9 %15
OpReturn
@@ -1001,16 +1030,17 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeStruct %6 %6
%7 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%8 = OpCompositeExtract %6 %7 1
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+ R"(%8 = OpCompositeExtract %6 %7 1
OpReturn
)");
@@ -1042,17 +1072,17 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%7 = OpTypeFloat 32
%6 = OpTypeStruct %7 %7
%5 = OpTypeStruct %6
%8 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%9 = OpCompositeExtract %6 %8 0
%10 = OpCompositeExtract %7 %9 1
OpReturn
@@ -1087,9 +1117,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%9 = OpTypeFloat 32
%8 = OpTypeStruct %9 %9
@@ -1100,9 +1130,10 @@
%12 = OpConstant %11 0
%13 = OpTypePointer Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %10
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%14 = OpAccessChain %13 %5 %12 %12
%15 = OpLoad %9 %14
OpReturn
@@ -1134,9 +1165,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%9 = OpTypeFloat 32
%8 = OpTypeStruct %9 %9
@@ -1148,9 +1179,10 @@
%13 = OpTypePointer Function %9
%15 = OpConstant %9 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %10
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%14 = OpAccessChain %13 %5 %12 %12
OpStore %14 %15
OpReturn
@@ -1186,9 +1218,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%9 = OpTypeFloat 32
%8 = OpTypeStruct %9 %9
@@ -1200,10 +1232,11 @@
%14 = OpTypeInt 32 0
%15 = OpConstant %14 0
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %10
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %10
%11 = OpVariable %12 Function %13
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%16 = OpAccessChain %12 %5 %15 %15
%17 = OpLoad %9 %16
OpStore %11 %17
@@ -1223,9 +1256,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%8 = OpTypeFloat 32
%7 = OpTypeVector %8 3
@@ -1235,9 +1268,11 @@
%11 = OpConstant %10 1
%12 = OpTypePointer Function %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%13 = OpAccessChain %12 %5 %11
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+ R"(%13 = OpAccessChain %12 %5 %11
%14 = OpLoad %8 %13
OpReturn
)");
@@ -1255,9 +1290,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%8 = OpTypeFloat 32
%7 = OpTypeVector %8 3
@@ -1265,9 +1300,10 @@
%9 = OpConstantNull %7
%11 = OpTypeVector %8 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%10 = OpLoad %7 %5
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(%10 = OpLoad %7 %5
%12 = OpVectorShuffle %11 %10 %10 1 0
OpReturn
)");
@@ -1285,9 +1321,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%8 = OpTypeFloat 32
%7 = OpTypeVector %8 3
@@ -1295,9 +1331,10 @@
%9 = OpConstantNull %7
%12 = OpTypeVector %8 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%10 = OpLoad %7 %5
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(%10 = OpLoad %7 %5
%11 = OpVectorShuffle %7 %10 %10 1 0 2
%13 = OpVectorShuffle %12 %11 %11 0 2
OpReturn
@@ -1316,18 +1353,19 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%8 = OpTypeFloat 32
%7 = OpTypeVector %8 3
%6 = OpTypePointer Function %7
%9 = OpConstantNull %7
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%10 = OpLoad %7 %5
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(%10 = OpLoad %7 %5
%11 = OpVectorShuffle %7 %10 %10 1 0 2
%12 = OpCompositeExtract %8 %11 0
OpReturn
@@ -1346,9 +1384,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%8 = OpTypeFloat 32
%7 = OpTypeVector %8 3
@@ -1357,9 +1395,10 @@
%12 = OpTypeInt 32 1
%13 = OpConstant %12 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %9
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(%10 = OpLoad %7 %5
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(%10 = OpLoad %7 %5
%11 = OpVectorShuffle %7 %10 %10 1 0 2
%14 = OpCompositeExtract %8 %11 1
OpReturn
@@ -1399,9 +1438,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%13 = OpTypeFloat 32
%12 = OpTypeVector %13 3
@@ -1422,9 +1461,10 @@
%22 = OpTypePointer Function %12
%24 = OpTypeVector %13 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%5 = OpVariable %6 Function %17
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()),
+ R"(%5 = OpVariable %6 Function %17
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%23 = OpAccessChain %22 %5 %19 %20 %21 %20 %20
%25 = OpLoad %12 %23
%26 = OpVectorShuffle %24 %25 %25 1 0
diff --git a/src/tint/writer/spirv/builder_assign_test.cc b/src/tint/writer/spirv/builder_assign_test.cc
index a6b8bc9..cab0ed4 100644
--- a/src/tint/writer/spirv/builder_assign_test.cc
+++ b/src/tint/writer/spirv/builder_assign_test.cc
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "gmock/gmock.h"
#include "src/tint/writer/spirv/spv_dump.h"
#include "src/tint/writer/spirv/test_helper.h"
@@ -31,21 +32,21 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
+ EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.Diagnostics();
EXPECT_FALSE(b.has_error());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
%5 = OpConstant %3 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %1 %5
)");
}
@@ -59,14 +60,15 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_FALSE(b.GenerateAssignStatement(assign)) << b.error();
+ tint::SetInternalCompilerErrorReporter(nullptr);
+
+ EXPECT_FALSE(b.GenerateAssignStatement(assign)) << b.Diagnostics();
EXPECT_TRUE(b.has_error());
- EXPECT_EQ(b.error(),
- "Internal error: trying to add SPIR-V instruction 62 outside a "
- "function");
+ EXPECT_THAT(b.Diagnostics().str(),
+ ::testing::HasSubstr("trying to add SPIR-V instruction 62 outside a function"));
}
TEST_F(BuilderTest, Assign_Var_ZeroInitializer) {
@@ -79,21 +81,21 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
+ EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.Diagnostics();
EXPECT_FALSE(b.has_error());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
%1 = OpVariable %2 Private %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %1 %5
)");
}
@@ -109,14 +111,14 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
+ EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.Diagnostics();
EXPECT_FALSE(b.has_error());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -126,7 +128,7 @@
%8 = OpConstant %4 3
%9 = OpConstantComposite %3 %6 %7 %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %1 %9
)");
}
@@ -142,14 +144,14 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
+ EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.Diagnostics();
EXPECT_FALSE(b.has_error());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -159,7 +161,7 @@
%8 = OpConstant %4 3
%9 = OpConstantComposite %3 %6 %7 %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %1 %9
)");
}
@@ -185,14 +187,14 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
+ EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.Diagnostics();
EXPECT_FALSE(b.has_error());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeStruct %4 %4
%2 = OpTypePointer Function %3
%5 = OpConstantNull %3
@@ -202,7 +204,7 @@
%10 = OpConstant %4 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpAccessChain %8 %1 %7
OpStore %9 %10
)");
@@ -218,14 +220,14 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
+ EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.Diagnostics();
EXPECT_FALSE(b.has_error());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -235,7 +237,7 @@
%8 = OpConstantComposite %3 %6 %6 %7
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %1 %8
)");
}
@@ -251,14 +253,14 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
+ EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.Diagnostics();
EXPECT_FALSE(b.has_error());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -269,7 +271,7 @@
%10 = OpConstant %4 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpAccessChain %8 %1 %7
OpStore %9 %10
)");
@@ -286,14 +288,14 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.error();
+ EXPECT_TRUE(b.GenerateAssignStatement(assign)) << b.Diagnostics();
EXPECT_FALSE(b.has_error());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -304,7 +306,7 @@
%10 = OpConstant %4 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpAccessChain %8 %1 %7
OpStore %9 %10
)");
diff --git a/src/tint/writer/spirv/builder_binary_expression_test.cc b/src/tint/writer/spirv/builder_binary_expression_test.cc
index 705bf77..36bd427 100644
--- a/src/tint/writer/spirv/builder_binary_expression_test.cc
+++ b/src/tint/writer/spirv/builder_binary_expression_test.cc
@@ -46,14 +46,14 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 3
%3 = OpConstant %1 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%4 = " + param.name + " %1 %2 %3\n");
}
@@ -75,15 +75,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstantComposite %1 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%5 = " + param.name + " %1 %4 %4\n");
}
TEST_P(BinaryArithSignedIntegerTest, Scalar_Loads) {
@@ -96,19 +96,19 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 7u) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 7u) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
%2 = OpTypePointer Function %3
%4 = OpConstantNull %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
R"(%1 = OpVariable %2 Function %4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%5 = OpLoad %3 %1
%6 = OpLoad %3 %1
%7 = )" + param.name +
@@ -140,14 +140,14 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 3
%3 = OpConstant %1 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%4 = " + param.name + " %1 %2 %3\n");
}
TEST_P(BinaryArithUnsignedIntegerTest, Vector) {
@@ -168,15 +168,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 0
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstantComposite %1 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%5 = " + param.name + " %1 %4 %4\n");
}
INSTANTIATE_TEST_SUITE_P(
@@ -206,14 +206,14 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 3.20000005
%3 = OpConstant %1 4.5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%4 = " + param.name + " %1 %2 %3\n");
}
@@ -229,15 +229,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstantComposite %1 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%5 = " + param.name + " %1 %4 %4\n");
}
INSTANTIATE_TEST_SUITE_P(BuilderTest,
@@ -263,14 +263,14 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1.998p+1
%3 = OpConstant %1 0x1.2p+2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%4 = " + param.name + " %1 %2 %3\n");
}
@@ -288,15 +288,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+0
%4 = OpConstantComposite %1 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%5 = " + param.name + " %1 %4 %4\n");
}
INSTANTIATE_TEST_SUITE_P(BuilderTest,
@@ -320,14 +320,14 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
%2 = OpConstantTrue %1
%3 = OpConstantNull %1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%4 = " + param.name + " %1 %2 %3\n");
}
@@ -343,17 +343,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 7u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 7u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
%1 = OpTypeVector %2 3
%3 = OpConstantNull %2
%4 = OpConstantTrue %2
%5 = OpConstantComposite %1 %3 %4 %3
%6 = OpConstantComposite %1 %4 %3 %4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%7 = " + param.name + " %1 %5 %6\n");
}
INSTANTIATE_TEST_SUITE_P(BuilderTest,
@@ -376,15 +376,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 3
%3 = OpConstant %1 4
%5 = OpTypeBool
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%4 = " + param.name + " %5 %2 %3\n");
}
@@ -400,17 +400,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 0
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstantComposite %1 %3 %3 %3
%7 = OpTypeBool
%6 = OpTypeVector %7 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%5 = " + param.name + " %6 %4 %4\n");
}
INSTANTIATE_TEST_SUITE_P(
@@ -436,15 +436,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 3
%3 = OpConstant %1 4
%5 = OpTypeBool
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%4 = " + param.name + " %5 %2 %3\n");
}
@@ -460,17 +460,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstantComposite %1 %3 %3 %3
%7 = OpTypeBool
%6 = OpTypeVector %7 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%5 = " + param.name + " %6 %4 %4\n");
}
INSTANTIATE_TEST_SUITE_P(
@@ -496,15 +496,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 3.20000005
%3 = OpConstant %1 4.5
%5 = OpTypeBool
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%4 = " + param.name + " %5 %2 %3\n");
}
@@ -520,17 +520,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstantComposite %1 %3 %3 %3
%7 = OpTypeBool
%6 = OpTypeVector %7 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%5 = " + param.name + " %6 %4 %4\n");
}
INSTANTIATE_TEST_SUITE_P(
@@ -558,15 +558,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 4u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1.998p+1
%3 = OpConstant %1 0x1.2p+2
%5 = OpTypeBool
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%4 = " + param.name + " %5 %2 %3\n");
}
@@ -584,17 +584,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+0
%4 = OpConstantComposite %1 %3 %3 %3
%7 = OpTypeBool
%6 = OpTypeVector %7 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%5 = " + param.name + " %6 %4 %4\n");
}
INSTANTIATE_TEST_SUITE_P(
@@ -617,16 +617,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstantComposite %1 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%5 = OpVectorTimesScalar %1 %4 %3\n");
}
@@ -642,16 +642,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+0
%4 = OpConstantComposite %1 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%5 = OpVectorTimesScalar %1 %4 %3\n");
}
@@ -665,16 +665,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 1
%3 = OpTypeVector %1 3
%4 = OpConstantComposite %3 %2 %2 %2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%5 = OpVectorTimesScalar %3 %4 %2\n");
}
@@ -690,16 +690,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 5u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1p+0
%3 = OpTypeVector %1 3
%4 = OpConstantComposite %3 %2 %2 %2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
"%5 = OpVectorTimesScalar %3 %4 %2\n");
}
@@ -711,11 +711,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%5 = OpTypeFloat 32
%4 = OpTypeVector %5 3
%3 = OpTypeMatrix %4 3
@@ -723,7 +723,7 @@
%6 = OpConstantNull %3
%8 = OpConstant %5 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%7 = OpLoad %3 %1
%9 = OpMatrixTimesScalar %3 %7 %8
)");
@@ -739,11 +739,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%5 = OpTypeFloat 16
%4 = OpTypeVector %5 3
%3 = OpTypeMatrix %4 3
@@ -751,7 +751,7 @@
%6 = OpConstantNull %3
%8 = OpConstant %5 0x1p+0
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%7 = OpLoad %3 %1
%9 = OpMatrixTimesScalar %3 %7 %8
)");
@@ -765,11 +765,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%5 = OpTypeFloat 32
%4 = OpTypeVector %5 3
%3 = OpTypeMatrix %4 3
@@ -777,7 +777,7 @@
%6 = OpConstantNull %3
%7 = OpConstant %5 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%8 = OpLoad %3 %1
%9 = OpMatrixTimesScalar %3 %8 %7
)");
@@ -793,11 +793,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%5 = OpTypeFloat 16
%4 = OpTypeVector %5 3
%3 = OpTypeMatrix %4 3
@@ -805,7 +805,7 @@
%6 = OpConstantNull %3
%7 = OpConstant %5 0x1p+0
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%8 = OpLoad %3 %1
%9 = OpMatrixTimesScalar %3 %8 %7
)");
@@ -820,11 +820,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%5 = OpTypeFloat 32
%4 = OpTypeVector %5 3
%3 = OpTypeMatrix %4 3
@@ -833,7 +833,7 @@
%8 = OpConstant %5 1
%9 = OpConstantComposite %4 %8 %8 %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%7 = OpLoad %3 %1
%10 = OpMatrixTimesVector %4 %7 %9
)");
@@ -850,11 +850,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%5 = OpTypeFloat 16
%4 = OpTypeVector %5 3
%3 = OpTypeMatrix %4 3
@@ -863,7 +863,7 @@
%8 = OpConstant %5 0x1p+0
%9 = OpConstantComposite %4 %8 %8 %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%7 = OpLoad %3 %1
%10 = OpMatrixTimesVector %4 %7 %9
)");
@@ -878,11 +878,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%5 = OpTypeFloat 32
%4 = OpTypeVector %5 3
%3 = OpTypeMatrix %4 3
@@ -891,7 +891,7 @@
%7 = OpConstant %5 1
%8 = OpConstantComposite %4 %7 %7 %7
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%10 = OpVectorTimesMatrix %4 %8 %9
)");
@@ -909,11 +909,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%5 = OpTypeFloat 16
%4 = OpTypeVector %5 3
%3 = OpTypeMatrix %4 3
@@ -922,7 +922,7 @@
%7 = OpConstant %5 0x1p+0
%8 = OpConstantComposite %4 %7 %7 %7
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%10 = OpVectorTimesMatrix %4 %8 %9
)");
@@ -936,18 +936,18 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%5 = OpTypeFloat 32
%4 = OpTypeVector %5 3
%3 = OpTypeMatrix %4 3
%2 = OpTypePointer Function %3
%6 = OpConstantNull %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%7 = OpLoad %3 %1
%8 = OpLoad %3 %1
%9 = OpMatrixTimesMatrix %3 %7 %8
@@ -964,18 +964,18 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 9u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%5 = OpTypeFloat 16
%4 = OpTypeVector %5 3
%3 = OpTypeMatrix %4 3
%2 = OpTypePointer Function %3
%6 = OpConstantNull %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%7 = OpLoad %3 %1
%8 = OpLoad %3 %1
%9 = OpMatrixTimesMatrix %3 %7 %8
@@ -993,15 +993,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- b.GenerateLabel(b.next_id());
- ASSERT_TRUE(b.GenerateFunctionVariable(v0)) << b.error();
- ASSERT_TRUE(b.GenerateFunctionVariable(v1)) << b.error();
- ASSERT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
- ASSERT_TRUE(b.GenerateFunctionVariable(v3)) << b.error();
+ b.PushFunctionForTesting();
+ b.GenerateLabel(b.Module().NextId());
+ ASSERT_TRUE(b.GenerateFunctionVariable(v0)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunctionVariable(v1)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunctionVariable(v2)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunctionVariable(v3)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 22u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 22u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeInt 32 1
%3 = OpConstant %2 1
%5 = OpTypePointer Function %2
@@ -1011,7 +1011,7 @@
%11 = OpConstant %2 4
%16 = OpTypeBool
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%1 = OpLabel
OpStore %4 %3
OpStore %8 %7
@@ -1041,21 +1041,21 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- b.GenerateLabel(b.next_id());
+ b.PushFunctionForTesting();
+ b.GenerateLabel(b.Module().NextId());
- ASSERT_TRUE(b.GenerateGlobalVariable(a_var)) << b.error();
- ASSERT_TRUE(b.GenerateGlobalVariable(b_var)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(a_var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateGlobalVariable(b_var)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 12u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 12u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
%3 = OpConstantTrue %2
%5 = OpTypePointer Private %2
%4 = OpVariable %5 Private %3
%6 = OpConstantNull %2
%7 = OpVariable %5 Private %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%1 = OpLabel
%8 = OpLoad %2 %4
OpSelectionMerge %9 None
@@ -1086,17 +1086,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(t)) << b.error();
- ASSERT_TRUE(b.GenerateFunctionVariable(f)) << b.error();
- b.GenerateLabel(b.next_id());
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(t)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunctionVariable(f)) << b.Diagnostics();
+ b.GenerateLabel(b.Module().NextId());
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
%2 = OpConstantTrue %1
%3 = OpConstantNull %1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%4 = OpLabel
OpSelectionMerge %5 None
OpBranchConditional %2 %5 %6
@@ -1131,17 +1131,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(t)) << b.error();
- ASSERT_TRUE(b.GenerateFunctionVariable(f)) << b.error();
- b.GenerateLabel(b.next_id());
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(t)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunctionVariable(f)) << b.Diagnostics();
+ b.GenerateLabel(b.Module().NextId());
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 10u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
%2 = OpConstantTrue %1
%3 = OpConstantNull %1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%4 = OpLabel
OpSelectionMerge %5 None
OpBranchConditional %2 %6 %5
@@ -1169,15 +1169,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- b.GenerateLabel(b.next_id());
- ASSERT_TRUE(b.GenerateFunctionVariable(v0)) << b.error();
- ASSERT_TRUE(b.GenerateFunctionVariable(v1)) << b.error();
- ASSERT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
- ASSERT_TRUE(b.GenerateFunctionVariable(v3)) << b.error();
+ b.PushFunctionForTesting();
+ b.GenerateLabel(b.Module().NextId());
+ ASSERT_TRUE(b.GenerateFunctionVariable(v0)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunctionVariable(v1)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunctionVariable(v2)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunctionVariable(v3)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 22u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 22u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeInt 32 1
%3 = OpConstant %2 1
%5 = OpTypePointer Function %2
@@ -1187,7 +1187,7 @@
%11 = OpConstant %2 4
%16 = OpTypeBool
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%1 = OpLabel
OpStore %4 %3
OpStore %8 %7
@@ -1218,21 +1218,21 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- b.GenerateLabel(b.next_id());
+ b.PushFunctionForTesting();
+ b.GenerateLabel(b.Module().NextId());
- ASSERT_TRUE(b.GenerateGlobalVariable(a_var)) << b.error();
- ASSERT_TRUE(b.GenerateGlobalVariable(b_var)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(a_var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateGlobalVariable(b_var)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr), 12u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+ EXPECT_EQ(b.GenerateBinaryExpression(expr), 12u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
%3 = OpConstantTrue %2
%5 = OpTypePointer Private %2
%4 = OpVariable %5 Private %3
%6 = OpConstantNull %2
%7 = OpVariable %5 Private %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%1 = OpLabel
%8 = OpLoad %2 %4
OpSelectionMerge %9 None
@@ -1357,7 +1357,7 @@
WrapInFunction(expr);
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), capability_decl + R"(
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %11 "test_function"
@@ -1409,7 +1409,7 @@
WrapInFunction(expr);
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), capability_decl + R"(
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %11 "test_function"
@@ -1489,7 +1489,7 @@
WrapInFunction(expr);
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), capability_decl + R"(
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %11 "test_function"
@@ -1537,7 +1537,7 @@
WrapInFunction(expr);
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), capability_decl + R"(
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %11 "test_function"
@@ -1651,7 +1651,7 @@
WrapInFunction(expr);
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), capability_decl + R"(
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %10 "test_function"
@@ -1714,7 +1714,7 @@
WrapInFunction(expr);
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), capability_decl + R"(
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %14 "test_function"
diff --git a/src/tint/writer/spirv/builder_bitcast_expression_test.cc b/src/tint/writer/spirv/builder_bitcast_expression_test.cc
index 3841e69..cc417ab 100644
--- a/src/tint/writer/spirv/builder_bitcast_expression_test.cc
+++ b/src/tint/writer/spirv/builder_bitcast_expression_test.cc
@@ -29,14 +29,14 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateBitcastExpression(bitcast), 1u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 0
%3 = OpTypeFloat 32
%4 = OpConstant %3 2.4000001
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%1 = OpBitcast %2 %4
)");
}
@@ -48,13 +48,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateBitcastExpression(bitcast), 1u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%3 = OpConstant %2 2.4000001
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%1 = OpCopyObject %2 %3
)");
}
diff --git a/src/tint/writer/spirv/builder_block_test.cc b/src/tint/writer/spirv/builder_block_test.cc
index f89db11..4783360 100644
--- a/src/tint/writer/spirv/builder_block_test.cc
+++ b/src/tint/writer/spirv/builder_block_test.cc
@@ -32,13 +32,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateStatement(outer)) << b.error();
+ EXPECT_TRUE(b.GenerateStatement(outer)) << b.Diagnostics();
EXPECT_FALSE(b.has_error());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypePointer Function %3
%4 = OpConstantNull %3
%5 = OpConstant %3 1
@@ -46,12 +46,12 @@
%8 = OpConstant %3 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
R"(%1 = OpVariable %2 Function %4
%6 = OpVariable %2 Function %4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %1 %5
OpStore %6 %7
OpStore %1 %8
diff --git a/src/tint/writer/spirv/builder_builtin_test.cc b/src/tint/writer/spirv/builder_builtin_test.cc
index 280b878..ba33a443 100644
--- a/src/tint/writer/spirv/builder_builtin_test.cc
+++ b/src/tint/writer/spirv/builder_builtin_test.cc
@@ -63,15 +63,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.error();
- ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(tex)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateExpression(expr1), 8u) << b.error();
- EXPECT_EQ(b.GenerateExpression(expr2), 17u) << b.error();
+ EXPECT_EQ(b.GenerateExpression(expr1), 8u) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(expr2), 17u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeImage %4 2D 0 0 0 1 Unknown
%2 = OpTypePointer UniformConstant %3
%1 = OpVariable %2 UniformConstant
@@ -85,7 +85,7 @@
%16 = OpConstantComposite %13 %14 %15
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %7 %5
%10 = OpLoad %3 %1
%12 = OpSampledImage %11 %10 %9
@@ -107,8 +107,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect =
@@ -143,8 +143,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect =
@@ -182,10 +182,10 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeBool
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeBool
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
@@ -194,7 +194,8 @@
)");
// both any and all are 'passthrough' for scalar booleans
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), "%10 = OpLoad %3 %1\nOpReturn\n");
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
+ "%10 = OpLoad %3 %1\nOpReturn\n");
}
TEST_P(BuiltinBoolTest, Call_Bool_Vector) {
@@ -208,10 +209,10 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeBool
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeBool
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -225,7 +226,7 @@
OpReturn
)",
"${op}", param.op);
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
}
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
BuiltinBoolTest,
@@ -243,11 +244,11 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(v3)) << b.error();
- ASSERT_TRUE(b.GenerateGlobalVariable(bool_v3)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(v3)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateGlobalVariable(bool_v3)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -260,7 +261,7 @@
%12 = OpTypeVoid
%11 = OpTypeFunction %12
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%16 = OpLoad %8 %6
%17 = OpLoad %3 %1
%18 = OpLoad %3 %1
@@ -292,9 +293,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- ASSERT_EQ(b.functions().size(), 1_u);
+ ASSERT_EQ(b.Module().Functions().size(), 1_u);
auto* expected_types = R"(%5 = OpTypeFloat 32
%4 = OpTypeRuntimeArray %5
@@ -305,13 +306,13 @@
%6 = OpTypeFunction %7
%11 = OpTypeInt 32 0
)";
- auto got_types = DumpInstructions(b.types());
+ auto got_types = DumpInstructions(b.Module().Types());
EXPECT_EQ(expected_types, got_types);
auto* expected_instructions = R"(%10 = OpArrayLength %11 %1 0
OpReturn
)";
- auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+ auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
EXPECT_EQ(expected_instructions, got_instructions);
Validate(b);
@@ -336,9 +337,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- ASSERT_EQ(b.functions().size(), 1_u);
+ ASSERT_EQ(b.Module().Functions().size(), 1_u);
auto* expected_types = R"(%4 = OpTypeFloat 32
%5 = OpTypeRuntimeArray %4
@@ -349,13 +350,13 @@
%6 = OpTypeFunction %7
%11 = OpTypeInt 32 0
)";
- auto got_types = DumpInstructions(b.types());
+ auto got_types = DumpInstructions(b.Module().Types());
EXPECT_EQ(expected_types, got_types);
auto* expected_instructions = R"(%10 = OpArrayLength %11 %1 1
OpReturn
)";
- auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+ auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
EXPECT_EQ(expected_instructions, got_instructions);
Validate(b);
@@ -384,9 +385,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- ASSERT_EQ(b.functions().size(), 1_u);
+ ASSERT_EQ(b.Module().Functions().size(), 1_u);
auto* expected_types = R"(%5 = OpTypeFloat 32
%4 = OpTypeRuntimeArray %5
@@ -397,13 +398,13 @@
%6 = OpTypeFunction %7
%11 = OpTypeInt 32 0
)";
- auto got_types = DumpInstructions(b.types());
+ auto got_types = DumpInstructions(b.Module().Types());
EXPECT_EQ(expected_types, got_types);
auto* expected_instructions = R"(%10 = OpArrayLength %11 %1 0
OpReturn
)";
- auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+ auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
EXPECT_EQ(expected_instructions, got_instructions);
Validate(b);
@@ -445,9 +446,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- ASSERT_EQ(b.functions().size(), 1_u);
+ ASSERT_EQ(b.Module().Functions().size(), 1_u);
auto* expected_types = R"(%5 = OpTypeFloat 32
%4 = OpTypeRuntimeArray %5
@@ -458,13 +459,13 @@
%6 = OpTypeFunction %7
%11 = OpTypeInt 32 0
)";
- auto got_types = DumpInstructions(b.types());
+ auto got_types = DumpInstructions(b.Module().Types());
EXPECT_EQ(expected_types, got_types);
auto* expected_instructions = R"(%10 = OpArrayLength %11 %1 0
OpReturn
)";
- auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+ auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
EXPECT_EQ(expected_instructions, got_instructions);
Validate(b);
@@ -489,7 +490,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -530,7 +531,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -570,7 +571,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -614,7 +615,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -680,7 +681,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -717,7 +718,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -752,7 +753,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -791,7 +792,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -828,7 +829,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -867,7 +868,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -906,7 +907,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -947,7 +948,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -986,7 +987,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -1029,7 +1030,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -1077,7 +1078,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -1117,7 +1118,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -1155,7 +1156,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -1193,7 +1194,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -1229,7 +1230,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -1269,7 +1270,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -1307,7 +1308,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -1347,7 +1348,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -1387,7 +1388,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -1429,7 +1430,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -1469,7 +1470,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -1513,7 +1514,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -1562,7 +1563,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -1603,7 +1604,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -1645,7 +1646,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
auto got = DumpBuilder(b);
auto* expect = R"(OpCapability Shader
%15 = OpExtInstImport "GLSL.std.450"
@@ -1699,7 +1700,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
auto got = DumpBuilder(b);
auto* expect = R"(OpCapability Shader
OpCapability Float16
@@ -1753,7 +1754,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
auto got = DumpBuilder(b);
auto* expect = R"(OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -1799,7 +1800,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
auto got = DumpBuilder(b);
auto* expect = R"(OpCapability Shader
OpCapability Float16
@@ -1849,7 +1850,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
auto got = DumpBuilder(b);
auto* expect = R"(OpCapability Shader
%17 = OpExtInstImport "GLSL.std.450"
@@ -1905,7 +1906,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
auto got = DumpBuilder(b);
auto* expect = R"(OpCapability Shader
OpCapability Float16
@@ -1960,7 +1961,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
auto got = DumpBuilder(b);
auto* expect = R"(OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -2008,7 +2009,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
auto got = DumpBuilder(b);
auto* expect = R"(OpCapability Shader
OpCapability Float16
@@ -2060,7 +2061,7 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
auto got = DumpBuilder(b);
auto* expect = R"(OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -2099,7 +2100,7 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
auto got = DumpBuilder(b);
auto* expect = R"(OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -2163,10 +2164,10 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
@@ -2179,7 +2180,7 @@
OpReturn
)",
"${op}", param.op);
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
}
TEST_P(BuiltinIntTest, Call_SInt_Vector) {
@@ -2193,10 +2194,10 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 1
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -2210,7 +2211,7 @@
OpReturn
)",
"${op}", param.op);
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
}
TEST_P(BuiltinIntTest, Call_UInt_Scalar) {
@@ -2224,10 +2225,10 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 0
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
@@ -2240,7 +2241,7 @@
OpReturn
)",
"${op}", param.op);
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
}
TEST_P(BuiltinIntTest, Call_UInt_Vector) {
@@ -2254,10 +2255,10 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 0
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -2271,7 +2272,7 @@
OpReturn
)",
"${op}", param.op);
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
}
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
BuiltinIntTest,
@@ -2291,7 +2292,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -2329,7 +2330,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -2373,7 +2374,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpName %3 "a_func"
@@ -2406,7 +2407,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpName %3 "a_func"
@@ -2443,7 +2444,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -2482,7 +2483,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -2527,7 +2528,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -2566,7 +2567,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -2611,7 +2612,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -2651,7 +2652,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -2697,7 +2698,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
@@ -2737,7 +2738,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
@@ -2779,7 +2780,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpEntryPoint GLCompute %3 "test_function"
@@ -2820,7 +2821,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpEntryPoint GLCompute %3 "test_function"
@@ -2858,7 +2859,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpEntryPoint GLCompute %3 "test_function"
@@ -2900,7 +2901,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpEntryPoint GLCompute %3 "test_function"
@@ -2942,7 +2943,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpEntryPoint GLCompute %3 "test_function"
@@ -2987,7 +2988,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpEntryPoint GLCompute %3 "test_function"
@@ -3029,7 +3030,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpEntryPoint GLCompute %3 "test_function"
@@ -3075,7 +3076,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpEntryPoint GLCompute %3 "test_function"
@@ -3125,8 +3126,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%12 = OpExtInstImport "GLSL.std.450"
@@ -3162,8 +3163,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(%12 = OpExtInstImport "GLSL.std.450"
@@ -3197,8 +3198,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpName %1 "var"
@@ -3235,8 +3236,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpName %1 "var"
@@ -3276,10 +3277,10 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -3287,7 +3288,7 @@
%7 = OpTypeVoid
%6 = OpTypeFunction %7
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%11 = OpLoad %3 %1
%12 = OpLoad %3 %1
%10 = OpDot %4 %11 %12
@@ -3307,10 +3308,10 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 16
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -3318,7 +3319,7 @@
%7 = OpTypeVoid
%6 = OpTypeFunction %7
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%11 = OpLoad %3 %1
%12 = OpLoad %3 %1
%10 = OpDot %4 %11 %12
@@ -3336,10 +3337,10 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 0
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -3347,7 +3348,7 @@
%7 = OpTypeVoid
%6 = OpTypeFunction %7
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%11 = OpLoad %3 %1
%12 = OpLoad %3 %1
%13 = OpCompositeExtract %4 %11 0
@@ -3375,10 +3376,10 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 1
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -3386,7 +3387,7 @@
%7 = OpTypeVoid
%6 = OpTypeFunction %7
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%11 = OpLoad %3 %1
%12 = OpLoad %3 %1
%13 = OpCompositeExtract %4 %11 0
@@ -3424,10 +3425,10 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
@@ -3440,7 +3441,7 @@
OpReturn
)",
"${op}", param.op);
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
}
TEST_P(BuiltinDeriveTest, Call_Derivative_Vector) {
@@ -3457,16 +3458,16 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
if (param.name != "dpdx" && param.name != "dpdy" && param.name != "fwidth") {
- EXPECT_EQ(DumpInstructions(b.capabilities()),
+ EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
R"(OpCapability DerivativeControl
)");
}
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -3480,7 +3481,7 @@
OpReturn
)",
"${op}", param.op);
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), expected);
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), expected);
}
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
BuiltinDeriveTest,
@@ -3529,9 +3530,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- ASSERT_EQ(b.functions().size(), 1_u);
+ ASSERT_EQ(b.Module().Functions().size(), 1_u);
auto* expected_types = R"(%5 = OpTypeInt 32 0
%6 = OpTypeInt 32 1
@@ -3546,7 +3547,7 @@
%15 = OpTypePointer StorageBuffer %5
%19 = OpTypePointer StorageBuffer %6
)";
- auto got_types = DumpInstructions(b.types());
+ auto got_types = DumpInstructions(b.Module().Types());
EXPECT_EQ(expected_types, got_types);
auto* expected_instructions = R"(%16 = OpAccessChain %15 %1 %13 %13
@@ -3555,7 +3556,7 @@
%17 = OpAtomicLoad %6 %20 %12 %13
OpReturn
)";
- auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+ auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
EXPECT_EQ(expected_instructions, got_instructions);
Validate(b);
@@ -3595,9 +3596,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- ASSERT_EQ(b.functions().size(), 1_u);
+ ASSERT_EQ(b.Module().Functions().size(), 1_u);
auto* expected_types = R"(%5 = OpTypeInt 32 0
%6 = OpTypeInt 32 1
@@ -3617,7 +3618,7 @@
%22 = OpTypePointer StorageBuffer %5
%27 = OpTypePointer StorageBuffer %6
)";
- auto got_types = DumpInstructions(b.types());
+ auto got_types = DumpInstructions(b.Module().Types());
EXPECT_EQ(expected_types, got_types);
auto* expected_instructions = R"(OpStore %12 %11
@@ -3630,7 +3631,7 @@
OpAtomicStore %28 %11 %20 %29
OpReturn
)";
- auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+ auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
EXPECT_EQ(expected_instructions, got_instructions);
Validate(b);
@@ -3666,9 +3667,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- ASSERT_EQ(b.functions().size(), 1_u);
+ ASSERT_EQ(b.Module().Functions().size(), 1_u);
std::string expected_types = R"(%5 = OpTypeInt 32 1
%4 = OpTypeStruct %5
@@ -3685,7 +3686,7 @@
%17 = OpConstant %15 0
%19 = OpTypePointer StorageBuffer %5
)";
- auto got_types = DumpInstructions(b.types());
+ auto got_types = DumpInstructions(b.Module().Types());
EXPECT_EQ(expected_types, got_types);
std::string expected_instructions = R"(OpStore %11 %10
@@ -3695,7 +3696,7 @@
expected_instructions += "%14 = " + GetParam().op + " %5 %20 %16 %17 %21\n";
expected_instructions += "OpReturn\n";
- auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+ auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
EXPECT_EQ(expected_instructions, got_instructions);
Validate(b);
@@ -3739,9 +3740,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- ASSERT_EQ(b.functions().size(), 1_u);
+ ASSERT_EQ(b.Module().Functions().size(), 1_u);
std::string expected_types = R"(%5 = OpTypeInt 32 0
%4 = OpTypeStruct %5
@@ -3757,7 +3758,7 @@
%16 = OpConstant %5 0
%18 = OpTypePointer StorageBuffer %5
)";
- auto got_types = DumpInstructions(b.types());
+ auto got_types = DumpInstructions(b.Module().Types());
EXPECT_EQ(expected_types, got_types);
std::string expected_instructions = R"(OpStore %11 %10
@@ -3767,7 +3768,7 @@
expected_instructions += "%14 = " + GetParam().op + " %5 %19 %15 %16 %20\n";
expected_instructions += "OpReturn\n";
- auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+ auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
EXPECT_EQ(expected_instructions, got_instructions);
Validate(b);
@@ -3817,9 +3818,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- ASSERT_EQ(b.functions().size(), 1_u);
+ ASSERT_EQ(b.Module().Functions().size(), 1_u);
auto* expected_types = R"(%5 = OpTypeInt 32 0
%6 = OpTypeInt 32 1
@@ -3840,7 +3841,7 @@
%23 = OpTypePointer StorageBuffer %5
%28 = OpTypePointer StorageBuffer %6
)";
- auto got_types = DumpInstructions(b.types());
+ auto got_types = DumpInstructions(b.Module().Types());
EXPECT_EQ(expected_types, got_types);
auto* expected_instructions = R"(OpStore %12 %11
@@ -3853,7 +3854,7 @@
%26 = OpAtomicExchange %6 %29 %20 %21 %30
OpReturn
)";
- auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+ auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
EXPECT_EQ(expected_instructions, got_instructions);
Validate(b);
@@ -3891,9 +3892,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- ASSERT_EQ(b.functions().size(), 1_u);
+ ASSERT_EQ(b.Module().Functions().size(), 1_u);
auto* expected_types = R"(%5 = OpTypeInt 32 0
%6 = OpTypeInt 32 1
@@ -3915,7 +3916,7 @@
%28 = OpConstant %6 20
%29 = OpConstant %6 10
)";
- auto got_types = DumpInstructions(b.types());
+ auto got_types = DumpInstructions(b.Module().Types());
EXPECT_EQ(expected_types, got_types);
auto* expected_instructions = R"(%18 = OpAccessChain %17 %1 %15 %15
@@ -3928,7 +3929,7 @@
%23 = OpCompositeConstruct %24 %30 %31
OpReturn
)";
- auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+ auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
EXPECT_EQ(expected_instructions, got_instructions);
Validate(b);
@@ -3953,7 +3954,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
if (pack4) {
auto got = DumpBuilder(b);
@@ -4024,7 +4025,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
if (pack4) {
auto got = DumpBuilder(b);
@@ -4092,9 +4093,9 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- ASSERT_EQ(b.functions().size(), 1_u);
+ ASSERT_EQ(b.Module().Functions().size(), 1_u);
auto* expected_types = R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
@@ -4102,13 +4103,13 @@
%7 = OpConstant %6 2
%8 = OpConstant %6 264
)";
- auto got_types = DumpInstructions(b.types());
+ auto got_types = DumpInstructions(b.Module().Types());
EXPECT_EQ(expected_types, got_types);
auto* expected_instructions = R"(OpControlBarrier %7 %7 %8
OpReturn
)";
- auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+ auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
EXPECT_EQ(expected_instructions, got_instructions);
Validate(b);
@@ -4126,9 +4127,9 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- ASSERT_EQ(b.functions().size(), 1_u);
+ ASSERT_EQ(b.Module().Functions().size(), 1_u);
auto* expected_types = R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
@@ -4136,13 +4137,13 @@
%7 = OpConstant %6 2
%8 = OpConstant %6 72
)";
- auto got_types = DumpInstructions(b.types());
+ auto got_types = DumpInstructions(b.Module().Types());
EXPECT_EQ(expected_types, got_types);
auto* expected_instructions = R"(OpControlBarrier %7 %7 %8
OpReturn
)";
- auto got_instructions = DumpInstructions(b.functions()[0].instructions());
+ auto got_instructions = DumpInstructions(b.Module().Functions()[0].instructions());
EXPECT_EQ(expected_instructions, got_instructions);
Validate(b);
@@ -4163,7 +4164,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpEntryPoint GLCompute %3 "test_function"
@@ -4200,7 +4201,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
auto got = DumpBuilder(b);
auto expect = R"(OpEntryPoint GLCompute %3 "test_function"
diff --git a/src/tint/writer/spirv/builder_builtin_texture_test.cc b/src/tint/writer/spirv/builder_builtin_texture_test.cc
index 4697582..cd17ec1 100644
--- a/src/tint/writer/spirv/builder_builtin_texture_test.cc
+++ b/src/tint/writer/spirv/builder_builtin_texture_test.cc
@@ -3726,16 +3726,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(texture)) << b.error();
- ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(texture)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateExpression(call), 8u) << b.error();
+ EXPECT_EQ(b.GenerateExpression(call), 8u) << b.Diagnostics();
auto expected = expected_texture_overload(param.overload);
- EXPECT_EQ(expected.types, "\n" + DumpInstructions(b.types()));
- EXPECT_EQ(expected.instructions, "\n" + DumpInstructions(b.functions()[0].instructions()));
- EXPECT_EQ(expected.capabilities, "\n" + DumpInstructions(b.capabilities()));
+ EXPECT_EQ(expected.types, "\n" + DumpInstructions(b.Module().Types()));
+ EXPECT_EQ(expected.instructions, "\n" + DumpInstructions(b.CurrentFunction().instructions()));
+ EXPECT_EQ(expected.capabilities, "\n" + DumpInstructions(b.Module().Capabilities()));
}
// Check the SPIRV generated passes validation
@@ -3756,7 +3756,7 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
Validate(b);
}
@@ -3781,12 +3781,14 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(texture)) << b.error();
- ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.error();
+ tint::SetInternalCompilerErrorReporter(nullptr);
+
+ ASSERT_TRUE(b.GenerateGlobalVariable(texture)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateGlobalVariable(sampler)) << b.Diagnostics();
EXPECT_EQ(b.GenerateExpression(call), 0u);
- EXPECT_THAT(b.error(),
- ::testing::StartsWith("Internal error: trying to add SPIR-V instruction "));
- EXPECT_THAT(b.error(), ::testing::EndsWith(" outside a function"));
+ EXPECT_THAT(b.Diagnostics().str(),
+ ::testing::HasSubstr("Internal error: trying to add SPIR-V instruction "));
+ EXPECT_THAT(b.Diagnostics().str(), ::testing::HasSubstr(" outside a function"));
}
} // namespace
diff --git a/src/tint/writer/spirv/builder_call_test.cc b/src/tint/writer/spirv/builder_call_test.cc
index a0631ea..b4774cb 100644
--- a/src/tint/writer/spirv/builder_call_test.cc
+++ b/src/tint/writer/spirv/builder_call_test.cc
@@ -36,8 +36,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(a_func)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(a_func)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func"
OpName %4 "a"
@@ -76,8 +76,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(a_func)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(a_func)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "a_func"
OpName %4 "a"
diff --git a/src/tint/writer/spirv/builder_const_assert_test.cc b/src/tint/writer/spirv/builder_const_assert_test.cc
index bca6deb..0644c28 100644
--- a/src/tint/writer/spirv/builder_const_assert_test.cc
+++ b/src/tint/writer/spirv/builder_const_assert_test.cc
@@ -27,11 +27,11 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
// const asserts are not emitted
- EXPECT_EQ(DumpInstructions(b.types()), "");
- EXPECT_EQ(b.functions().size(), 0u);
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), "");
+ EXPECT_EQ(b.Module().Functions().size(), 0u);
}
TEST_F(BuilderTest, FunctionConstAssert) {
@@ -39,13 +39,13 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
// const asserts are not emitted
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
)");
}
diff --git a/src/tint/writer/spirv/builder_constructor_expression_test.cc b/src/tint/writer/spirv/builder_constructor_expression_test.cc
index 29a47ac..7416bc2 100644
--- a/src/tint/writer/spirv/builder_constructor_expression_test.cc
+++ b/src/tint/writer/spirv/builder_constructor_expression_test.cc
@@ -29,9 +29,9 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateConstructorExpression(g, c), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 42.2000008
)");
}
@@ -43,9 +43,9 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateConstructorExpression(nullptr, t), 5u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 3
@@ -59,17 +59,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 4u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 1
%4 = OpConstantComposite %1 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_WithAlias) {
@@ -82,13 +82,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 2u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_IdentifierExpression_Param) {
@@ -99,23 +99,23 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
EXPECT_EQ(b.GenerateExpression(t), 8u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypePointer Function %3
%4 = OpConstantNull %3
%5 = OpTypeVector %3 2
%6 = OpConstant %3 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
R"(%1 = OpVariable %2 Function %4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%7 = OpLoad %3 %1
%8 = OpCompositeConstruct %5 %6 %7
)");
@@ -128,11 +128,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
- ASSERT_EQ(b.GenerateExpression(cast), 10u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
+ ASSERT_EQ(b.GenerateExpression(cast), 10u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -143,7 +143,7 @@
%12 = OpTypeInt 32 0
%11 = OpTypeVector %12 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %7 %6
%13 = OpLoad %1 %7
%10 = OpBitcast %11 %13
@@ -156,15 +156,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
%2 = OpConstantTrue %1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_I32_With_I32) {
@@ -173,13 +173,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 2u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_U32_With_U32) {
@@ -188,13 +188,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 2u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_F32_With_F32) {
@@ -203,13 +203,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 2u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_F16_With_F16) {
@@ -220,13 +220,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 2u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1p+1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_Bool_Literal) {
@@ -235,15 +235,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
%1 = OpTypeVector %2 2
%3 = OpConstantTrue %2
%4 = OpConstantComposite %1 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_Bool_Var) {
@@ -253,17 +253,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
- ASSERT_EQ(b.GenerateExpression(cast), 8u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
+ ASSERT_EQ(b.GenerateExpression(cast), 8u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
%2 = OpConstantTrue %1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%6 = OpTypeVector %1 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%7 = OpLoad %1 %3
%8 = OpCompositeConstruct %6 %7 %7
@@ -276,15 +276,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_F16_Literal) {
@@ -295,15 +295,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 2
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_F32_F32) {
@@ -313,17 +313,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 9u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 2
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%6 = OpTypeVector %1 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%7 = OpLoad %1 %3
%8 = OpLoad %1 %3
@@ -340,17 +340,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 9u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1p+1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%6 = OpTypeVector %1 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%7 = OpLoad %1 %3
%8 = OpLoad %1 %3
@@ -364,16 +364,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 5u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 1
%4 = OpConstant %2 2
%5 = OpConstantComposite %1 %3 %4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec2_With_F16_F16_Const) {
@@ -384,16 +384,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 5u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 2
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
%5 = OpConstantComposite %1 %3 %4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec2_F32_With_Vec2) {
@@ -403,11 +403,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 10u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -415,7 +415,7 @@
%7 = OpTypePointer Function %1
%8 = OpConstantNull %1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%10 = OpLoad %1 %6
)");
@@ -430,11 +430,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 10u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 2
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
@@ -442,7 +442,7 @@
%7 = OpTypePointer Function %1
%8 = OpConstantNull %1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%10 = OpLoad %1 %6
)");
@@ -454,16 +454,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 5u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 1
%4 = OpConstant %2 2
%5 = OpConstantComposite %1 %3 %4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec2_F16_With_Vec2_Const) {
@@ -474,16 +474,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 5u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 2
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
%5 = OpConstantComposite %1 %3 %4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F32) {
@@ -493,17 +493,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 10u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 2
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%6 = OpTypeVector %1 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%7 = OpLoad %1 %3
%8 = OpLoad %1 %3
@@ -521,17 +521,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 10u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1p+1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%6 = OpTypeVector %1 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%7 = OpLoad %1 %3
%8 = OpLoad %1 %3
@@ -546,17 +546,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
%5 = OpConstant %2 3
%6 = OpConstantComposite %1 %3 %4 %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F16_Const) {
@@ -567,17 +567,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
%5 = OpConstant %2 0x1.8p+1
%6 = OpConstantComposite %1 %3 %4 %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_Bool) {
@@ -587,17 +587,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 10u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
%2 = OpConstantTrue %1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%6 = OpTypeVector %1 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%7 = OpLoad %1 %3
%8 = OpLoad %1 %3
@@ -612,16 +612,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 5u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
%1 = OpTypeVector %2 3
%3 = OpConstantTrue %2
%4 = OpConstantNull %2
%5 = OpConstantComposite %1 %3 %4 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F32_F32_F32) {
@@ -631,17 +631,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 10u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 2
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%6 = OpTypeVector %1 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%7 = OpLoad %1 %3
%8 = OpLoad %1 %3
@@ -659,17 +659,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 10u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1p+1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%6 = OpTypeVector %1 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%7 = OpLoad %1 %3
%8 = OpLoad %1 %3
@@ -684,17 +684,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
%5 = OpConstant %2 3
%6 = OpConstantComposite %1 %3 %4 %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F16_F16_F16_Const) {
@@ -705,17 +705,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
%5 = OpConstant %2 0x1.8p+1
%6 = OpConstantComposite %1 %3 %4 %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F32_Vec2) {
@@ -725,11 +725,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 14u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 2
%4 = OpConstant %2 3
@@ -739,7 +739,7 @@
%9 = OpTypeVector %2 3
%10 = OpConstant %2 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%11 = OpLoad %1 %6
%12 = OpCompositeExtract %2 %11 0
@@ -757,11 +757,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 14u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 2
%3 = OpConstant %2 0x1p+1
%4 = OpConstant %2 0x1.8p+1
@@ -771,7 +771,7 @@
%9 = OpTypeVector %2 3
%10 = OpConstant %2 0x1p+0
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%11 = OpLoad %1 %6
%12 = OpCompositeExtract %2 %11 0
@@ -786,17 +786,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
%5 = OpConstant %2 3
%6 = OpConstantComposite %1 %3 %4 %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_F16_Vec2_Const) {
@@ -807,17 +807,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
%5 = OpConstant %2 0x1.8p+1
%6 = OpConstantComposite %1 %3 %4 %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_Vec2_F32) {
@@ -827,11 +827,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 14u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -841,7 +841,7 @@
%9 = OpTypeVector %2 3
%13 = OpConstant %2 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%10 = OpLoad %1 %6
%11 = OpCompositeExtract %2 %10 0
@@ -859,11 +859,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 14u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 2
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
@@ -873,7 +873,7 @@
%9 = OpTypeVector %2 3
%13 = OpConstant %2 0x1.8p+1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%10 = OpLoad %1 %6
%11 = OpCompositeExtract %2 %10 0
@@ -888,17 +888,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
%5 = OpConstant %2 3
%6 = OpConstantComposite %1 %3 %4 %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec3_With_Vec2_F16_Const) {
@@ -909,17 +909,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
%5 = OpConstant %2 0x1.8p+1
%6 = OpConstantComposite %1 %3 %4 %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec3_F32_With_Vec3) {
@@ -929,11 +929,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 11u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -942,7 +942,7 @@
%8 = OpTypePointer Function %1
%9 = OpConstantNull %1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %7 %6
%11 = OpLoad %1 %7
)");
@@ -957,11 +957,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 11u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
@@ -970,7 +970,7 @@
%8 = OpTypePointer Function %1
%9 = OpConstantNull %1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %7 %6
%11 = OpLoad %1 %7
)");
@@ -982,17 +982,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
%5 = OpConstant %2 3
%6 = OpConstantComposite %1 %3 %4 %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec3_F16_With_Vec3_Const) {
@@ -1003,17 +1003,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
%5 = OpConstant %2 0x1.8p+1
%6 = OpConstantComposite %1 %3 %4 %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Bool) {
@@ -1023,17 +1023,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 8u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
%2 = OpConstantTrue %1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%6 = OpTypeVector %1 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%7 = OpLoad %1 %3
%8 = OpCompositeConstruct %6 %7 %7 %7 %7
@@ -1046,15 +1046,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
%1 = OpTypeVector %2 4
%3 = OpConstantTrue %2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32) {
@@ -1064,17 +1064,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 8u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 2
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%6 = OpTypeVector %1 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%7 = OpLoad %1 %3
%8 = OpCompositeConstruct %6 %7 %7 %7 %7
@@ -1090,17 +1090,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 8u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1p+1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%6 = OpTypeVector %1 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%7 = OpLoad %1 %3
%8 = OpCompositeConstruct %6 %7 %7 %7 %7
@@ -1113,15 +1113,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F16_Const) {
@@ -1132,15 +1132,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_F32_F32_F32) {
@@ -1150,17 +1150,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 11u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 2
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%6 = OpTypeVector %1 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%7 = OpLoad %1 %3
%8 = OpLoad %1 %3
@@ -1179,17 +1179,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 11u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1p+1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%6 = OpTypeVector %1 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%7 = OpLoad %1 %3
%8 = OpLoad %1 %3
@@ -1205,10 +1205,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 7u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -1216,7 +1216,7 @@
%6 = OpConstant %2 4
%7 = OpConstantComposite %1 %3 %4 %5 %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F16_F16_F16_F16_Const) {
@@ -1227,10 +1227,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 7u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
@@ -1238,7 +1238,7 @@
%6 = OpConstant %2 0x1p+2
%7 = OpConstantComposite %1 %3 %4 %5 %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_F32_Vec2) {
@@ -1248,11 +1248,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 13u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -1261,7 +1261,7 @@
%8 = OpConstantNull %1
%9 = OpTypeVector %2 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%10 = OpLoad %1 %6
%11 = OpCompositeExtract %2 %10 0
@@ -1279,11 +1279,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 13u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 2
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
@@ -1292,7 +1292,7 @@
%8 = OpConstantNull %1
%9 = OpTypeVector %2 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%10 = OpLoad %1 %6
%11 = OpCompositeExtract %2 %10 0
@@ -1307,10 +1307,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 7u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -1318,7 +1318,7 @@
%6 = OpConstant %2 4
%7 = OpConstantComposite %1 %3 %4 %5 %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F16_F16_Vec2_Const) {
@@ -1329,10 +1329,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 7u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
@@ -1340,7 +1340,7 @@
%6 = OpConstant %2 0x1p+2
%7 = OpConstantComposite %1 %3 %4 %5 %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_Vec2_F32) {
@@ -1350,11 +1350,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 15u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 2
%4 = OpConstant %2 3
@@ -1365,7 +1365,7 @@
%10 = OpConstant %2 1
%14 = OpConstant %2 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%11 = OpLoad %1 %6
%12 = OpCompositeExtract %2 %11 0
@@ -1383,11 +1383,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 15u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 2
%3 = OpConstant %2 0x1p+1
%4 = OpConstant %2 0x1.8p+1
@@ -1398,7 +1398,7 @@
%10 = OpConstant %2 0x1p+0
%14 = OpConstant %2 0x1p+2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%11 = OpLoad %1 %6
%12 = OpCompositeExtract %2 %11 0
@@ -1413,10 +1413,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 7u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -1424,7 +1424,7 @@
%6 = OpConstant %2 4
%7 = OpConstantComposite %1 %3 %4 %5 %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F16_Vec2_F16_Const) {
@@ -1435,10 +1435,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 7u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
@@ -1446,7 +1446,7 @@
%6 = OpConstant %2 0x1p+2
%7 = OpConstantComposite %1 %3 %4 %5 %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec2_F32_F32) {
@@ -1456,11 +1456,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 15u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -1471,7 +1471,7 @@
%13 = OpConstant %2 3
%14 = OpConstant %2 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%10 = OpLoad %1 %6
%11 = OpCompositeExtract %2 %10 0
@@ -1489,11 +1489,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 15u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 2
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
@@ -1504,7 +1504,7 @@
%13 = OpConstant %2 0x1.8p+1
%14 = OpConstant %2 0x1p+2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%10 = OpLoad %1 %6
%11 = OpCompositeExtract %2 %10 0
@@ -1519,10 +1519,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 7u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -1530,7 +1530,7 @@
%6 = OpConstant %2 4
%7 = OpConstantComposite %1 %3 %4 %5 %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec2_F16_F16_Const) {
@@ -1541,10 +1541,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 7u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
@@ -1552,7 +1552,7 @@
%6 = OpConstant %2 0x1p+2
%7 = OpConstantComposite %1 %3 %4 %5 %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_F32_With_Vec2_Vec2) {
@@ -1562,11 +1562,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 16u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -1575,7 +1575,7 @@
%8 = OpConstantNull %1
%9 = OpTypeVector %2 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%10 = OpLoad %1 %6
%11 = OpCompositeExtract %2 %10 0
@@ -1596,11 +1596,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 16u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 2
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
@@ -1609,7 +1609,7 @@
%8 = OpConstantNull %1
%9 = OpTypeVector %2 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
%10 = OpLoad %1 %6
%11 = OpCompositeExtract %2 %10 0
@@ -1627,16 +1627,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 5u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 1
%4 = OpConstant %2 2
%5 = OpConstantComposite %1 %3 %4 %3 %4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_F16_With_Vec2_Vec2_Const) {
@@ -1647,16 +1647,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 5u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
%5 = OpConstantComposite %1 %3 %4 %3 %4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F32_Vec3) {
@@ -1666,11 +1666,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 13u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3
@@ -1678,7 +1678,7 @@
%7 = OpConstantNull %1
%8 = OpTypeVector %2 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %5 %4
%9 = OpLoad %1 %5
%10 = OpCompositeExtract %2 %9 0
@@ -1697,11 +1697,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 13u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3
@@ -1709,7 +1709,7 @@
%7 = OpConstantNull %1
%8 = OpTypeVector %2 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %5 %4
%9 = OpLoad %1 %5
%10 = OpCompositeExtract %2 %9 0
@@ -1725,15 +1725,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_F16_Vec3_Const) {
@@ -1744,15 +1744,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec3_F32) {
@@ -1762,11 +1762,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 13u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3
@@ -1774,7 +1774,7 @@
%7 = OpConstantNull %1
%8 = OpTypeVector %2 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %5 %4
%9 = OpLoad %1 %5
%10 = OpCompositeExtract %2 %9 0
@@ -1793,11 +1793,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateStatement(var));
EXPECT_EQ(b.GenerateExpression(cast), 13u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3
@@ -1805,7 +1805,7 @@
%7 = OpConstantNull %1
%8 = OpTypeVector %2 4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %5 %4
%9 = OpLoad %1 %5
%10 = OpCompositeExtract %2 %9 0
@@ -1821,15 +1821,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec3_F16_Const) {
@@ -1840,15 +1840,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_F32_With_Vec4) {
@@ -1858,15 +1858,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_Vec4_F16_With_Vec4) {
@@ -1878,15 +1878,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_F32_With_F32) {
@@ -1897,14 +1897,14 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeFloat 32
%6 = OpConstant %5 2
%8 = OpTypePointer Function %5
%9 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %7 %6
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %7 %6
OpReturn
)");
Validate(b);
@@ -1920,14 +1920,14 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeFloat 16
%6 = OpConstant %5 0x1p+1
%8 = OpTypePointer Function %5
%9 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %7 %6
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %7 %6
OpReturn
)");
Validate(b);
@@ -1940,7 +1940,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 2
%4 = OpTypePointer Private %1
%3 = OpVariable %4 Private %2
@@ -1959,7 +1959,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1p+1
%4 = OpTypePointer Private %1
%3 = OpVariable %4 Private %2
@@ -1977,14 +1977,14 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeInt 32 0
%6 = OpConstant %5 1
%8 = OpTypePointer Function %5
%9 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %7 %6
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %7 %6
OpReturn
)");
Validate(b);
@@ -2000,14 +2000,14 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeInt 32 0
%6 = OpConstant %5 1
%8 = OpTypePointer Function %5
%9 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %7 %6
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %7 %6
OpReturn
)");
Validate(b);
@@ -2020,7 +2020,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 1
%4 = OpTypePointer Private %1
%3 = OpVariable %4 Private %2
@@ -2039,7 +2039,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 1
%4 = OpTypePointer Private %1
%3 = OpVariable %4 Private %2
@@ -2057,7 +2057,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 2
@@ -2066,7 +2066,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2082,7 +2082,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 16
%5 = OpTypeVector %6 2
@@ -2091,7 +2091,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2103,10 +2103,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3
@@ -2121,10 +2121,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 2
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3
@@ -2139,7 +2139,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 2
@@ -2148,7 +2148,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2164,7 +2164,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 16
%5 = OpTypeVector %6 2
@@ -2173,7 +2173,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2186,7 +2186,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3
@@ -2208,7 +2208,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 2
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3
@@ -2229,7 +2229,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 3
@@ -2238,7 +2238,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2254,7 +2254,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 16
%5 = OpTypeVector %6 3
@@ -2263,7 +2263,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2276,7 +2276,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3
@@ -2298,7 +2298,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3
@@ -2319,7 +2319,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
@@ -2328,7 +2328,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2344,7 +2344,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 16
%5 = OpTypeVector %6 4
@@ -2353,7 +2353,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2366,7 +2366,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2388,7 +2388,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2409,7 +2409,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 3
@@ -2418,7 +2418,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2434,7 +2434,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 16
%5 = OpTypeVector %6 3
@@ -2443,7 +2443,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2455,10 +2455,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3
@@ -2473,10 +2473,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3
@@ -2491,7 +2491,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 3
@@ -2500,7 +2500,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2516,7 +2516,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 16
%5 = OpTypeVector %6 3
@@ -2525,7 +2525,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2537,10 +2537,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3
@@ -2555,10 +2555,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3
@@ -2573,7 +2573,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 3
@@ -2582,7 +2582,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2598,7 +2598,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 16
%5 = OpTypeVector %6 3
@@ -2607,7 +2607,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2619,10 +2619,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3
@@ -2637,10 +2637,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3
@@ -2655,7 +2655,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
@@ -2664,7 +2664,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2680,7 +2680,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 16
%5 = OpTypeVector %6 4
@@ -2689,7 +2689,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2701,10 +2701,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2719,10 +2719,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2737,7 +2737,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
@@ -2746,7 +2746,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2762,7 +2762,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 16
%5 = OpTypeVector %6 4
@@ -2771,7 +2771,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2783,10 +2783,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2801,10 +2801,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2819,7 +2819,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
@@ -2828,7 +2828,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2844,7 +2844,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 16
%5 = OpTypeVector %6 4
@@ -2853,7 +2853,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2865,10 +2865,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2883,10 +2883,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2901,7 +2901,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
@@ -2910,7 +2910,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2926,7 +2926,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 16
%5 = OpTypeVector %6 4
@@ -2935,7 +2935,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -2947,10 +2947,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2965,10 +2965,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -2983,7 +2983,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
@@ -2992,7 +2992,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -3008,7 +3008,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 16
%5 = OpTypeVector %6 4
@@ -3017,7 +3017,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -3029,10 +3029,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -3047,10 +3047,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -3065,7 +3065,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
@@ -3074,7 +3074,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -3086,10 +3086,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -3104,10 +3104,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -3122,7 +3122,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
@@ -3131,7 +3131,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -3147,7 +3147,7 @@
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 16
%5 = OpTypeVector %6 4
@@ -3156,7 +3156,7 @@
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
@@ -3168,10 +3168,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -3186,10 +3186,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 4
%3 = OpConstant %2 0x1p+1
%4 = OpConstantComposite %1 %3 %3 %3 %3
@@ -3202,10 +3202,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypeVector %3 2
%1 = OpTypeMatrix %2 2
%4 = OpConstant %3 2
@@ -3222,10 +3222,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
%2 = OpTypeVector %3 2
%1 = OpTypeMatrix %2 2
%4 = OpConstant %3 0x1p+1
@@ -3240,10 +3240,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypeVector %3 2
%1 = OpTypeMatrix %2 3
%4 = OpConstant %3 2
@@ -3260,10 +3260,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
%2 = OpTypeVector %3 2
%1 = OpTypeMatrix %2 3
%4 = OpConstant %3 0x1p+1
@@ -3279,10 +3279,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypeVector %3 2
%1 = OpTypeMatrix %2 4
%4 = OpConstant %3 2
@@ -3300,10 +3300,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
%2 = OpTypeVector %3 2
%1 = OpTypeMatrix %2 4
%4 = OpConstant %3 0x1p+1
@@ -3318,10 +3318,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypeVector %3 3
%1 = OpTypeMatrix %2 2
%4 = OpConstant %3 2
@@ -3338,10 +3338,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
%2 = OpTypeVector %3 3
%1 = OpTypeMatrix %2 2
%4 = OpConstant %3 0x1p+1
@@ -3357,10 +3357,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypeVector %3 3
%1 = OpTypeMatrix %2 3
%4 = OpConstant %3 2
@@ -3378,10 +3378,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
%2 = OpTypeVector %3 3
%1 = OpTypeMatrix %2 3
%4 = OpConstant %3 0x1p+1
@@ -3397,10 +3397,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypeVector %3 3
%1 = OpTypeMatrix %2 4
%4 = OpConstant %3 2
@@ -3418,10 +3418,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
%2 = OpTypeVector %3 3
%1 = OpTypeMatrix %2 4
%4 = OpConstant %3 0x1p+1
@@ -3436,10 +3436,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypeVector %3 4
%1 = OpTypeMatrix %2 2
%4 = OpConstant %3 2
@@ -3456,10 +3456,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
%2 = OpTypeVector %3 4
%1 = OpTypeMatrix %2 2
%4 = OpConstant %3 0x1p+1
@@ -3475,10 +3475,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypeVector %3 4
%1 = OpTypeMatrix %2 3
%4 = OpConstant %3 2
@@ -3496,10 +3496,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
%2 = OpTypeVector %3 4
%1 = OpTypeMatrix %2 3
%4 = OpConstant %3 0x1p+1
@@ -3515,10 +3515,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypeVector %3 4
%1 = OpTypeMatrix %2 4
%4 = OpConstant %3 2
@@ -3536,10 +3536,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
%2 = OpTypeVector %3 4
%1 = OpTypeMatrix %2 4
%4 = OpConstant %3 0x1p+1
@@ -3554,10 +3554,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%3 = OpTypeInt 32 0
%4 = OpConstant %3 5
%1 = OpTypeArray %2 %4
@@ -3574,10 +3574,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(cast), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%3 = OpTypeInt 32 0
%4 = OpConstant %3 5
%1 = OpTypeArray %2 %4
@@ -3593,9 +3593,9 @@
WrapInFunction(t);
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 10u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypeVector %3 3
%4 = OpTypeInt 32 0
%5 = OpConstant %4 2
@@ -3617,9 +3617,9 @@
WrapInFunction(t);
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 10u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
%2 = OpTypeVector %3 3
%4 = OpTypeInt 32 0
%5 = OpConstant %4 2
@@ -3639,11 +3639,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(v1), 4u);
EXPECT_EQ(b.GenerateExpression(v2), 4u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3
@@ -3657,11 +3657,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(a1), 6u);
EXPECT_EQ(b.GenerateExpression(a2), 6u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%3 = OpTypeInt 32 0
%4 = OpConstant %3 3
%1 = OpTypeArray %2 %4
@@ -3679,11 +3679,11 @@
WrapInFunction(WrapInStatement(a1), WrapInStatement(a2));
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(a1), 7u);
EXPECT_EQ(b.GenerateExpression(a2), 9u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%3 = OpTypeInt 32 0
%4 = OpConstant %3 2
%1 = OpTypeArray %2 %4
@@ -3706,12 +3706,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 6u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%3 = OpTypeVector %2 3
%1 = OpTypeStruct %2 %3
%4 = OpConstant %2 2
@@ -3727,12 +3727,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstantNull %1
)");
}
@@ -3746,12 +3746,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstantNull %1
)");
}
@@ -3763,12 +3763,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstantNull %1
)");
}
@@ -3780,12 +3780,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstantNull %1
)");
}
@@ -3797,12 +3797,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
%2 = OpConstantNull %1
)");
}
@@ -3814,12 +3814,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 3u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%1 = OpTypeVector %2 2
%3 = OpConstantNull %1
)");
@@ -3832,12 +3832,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 4u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypeVector %3 2
%1 = OpTypeMatrix %2 4
%4 = OpConstantNull %1
@@ -3853,12 +3853,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 4u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
%2 = OpTypeVector %3 2
%1 = OpTypeMatrix %2 4
%4 = OpConstantNull %1
@@ -3872,12 +3872,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 5u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%3 = OpTypeInt 32 0
%4 = OpConstant %3 2
%1 = OpTypeArray %2 %4
@@ -3892,12 +3892,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_EQ(b.GenerateExpression(t), 3u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeStruct %2
%3 = OpConstantNull %1
)");
@@ -3910,17 +3910,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateStatement(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 2
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%7 = OpTypeInt 32 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%8 = OpLoad %1 %3
%6 = OpBitcast %7 %8
@@ -3934,17 +3934,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateStatement(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 2.4000001
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%7 = OpTypeInt 32 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%8 = OpLoad %1 %3
%6 = OpConvertFToS %7 %8
@@ -3960,17 +3960,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateStatement(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1.33p+1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%7 = OpTypeInt 32 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%8 = OpLoad %1 %3
%6 = OpConvertFToS %7 %8
@@ -3984,17 +3984,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateStatement(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 2
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%7 = OpTypeInt 32 0
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%8 = OpLoad %1 %3
%6 = OpBitcast %7 %8
@@ -4008,17 +4008,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateStatement(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 2.4000001
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%7 = OpTypeInt 32 0
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%8 = OpLoad %1 %3
%6 = OpConvertFToU %7 %8
@@ -4034,17 +4034,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateStatement(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1.33p+1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%7 = OpTypeInt 32 0
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%8 = OpLoad %1 %3
%6 = OpConvertFToU %7 %8
@@ -4058,17 +4058,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateStatement(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 2
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%7 = OpTypeFloat 32
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%8 = OpLoad %1 %3
%6 = OpConvertSToF %7 %8
@@ -4082,17 +4082,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateStatement(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 2
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%7 = OpTypeFloat 32
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%8 = OpLoad %1 %3
%6 = OpConvertUToF %7 %8
@@ -4108,17 +4108,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateStatement(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1p+1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%7 = OpTypeFloat 32
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%8 = OpLoad %1 %3
%6 = OpFConvert %7 %8
@@ -4134,17 +4134,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateStatement(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 2
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%7 = OpTypeFloat 16
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%8 = OpLoad %1 %3
%6 = OpConvertSToF %7 %8
@@ -4160,17 +4160,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateStatement(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 2
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%7 = OpTypeFloat 16
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%8 = OpLoad %1 %3
%6 = OpConvertUToF %7 %8
@@ -4186,17 +4186,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateStatement(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateStatement(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 2
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
%7 = OpTypeFloat 16
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%8 = OpLoad %1 %3
%6 = OpFConvert %7 %8
@@ -4211,11 +4211,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 0
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -4223,7 +4223,7 @@
%8 = OpTypeInt 32 1
%7 = OpTypeVector %8 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%6 = OpBitcast %7 %9
)");
@@ -4237,11 +4237,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -4249,7 +4249,7 @@
%8 = OpTypeInt 32 1
%7 = OpTypeVector %8 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%6 = OpConvertFToS %7 %9
)");
@@ -4265,11 +4265,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 16
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -4277,7 +4277,7 @@
%8 = OpTypeInt 32 1
%7 = OpTypeVector %8 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%6 = OpConvertFToS %7 %9
)");
@@ -4291,11 +4291,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 1
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -4303,7 +4303,7 @@
%8 = OpTypeInt 32 0
%7 = OpTypeVector %8 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%6 = OpBitcast %7 %9
)");
@@ -4317,11 +4317,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -4329,7 +4329,7 @@
%8 = OpTypeInt 32 0
%7 = OpTypeVector %8 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%6 = OpConvertFToU %7 %9
)");
@@ -4345,11 +4345,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 16
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -4357,7 +4357,7 @@
%8 = OpTypeInt 32 0
%7 = OpTypeVector %8 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%6 = OpConvertFToU %7 %9
)");
@@ -4371,11 +4371,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 1
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -4383,7 +4383,7 @@
%8 = OpTypeFloat 32
%7 = OpTypeVector %8 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%6 = OpConvertSToF %7 %9
)");
@@ -4397,11 +4397,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 0
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -4409,7 +4409,7 @@
%8 = OpTypeFloat 32
%7 = OpTypeVector %8 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%6 = OpConvertUToF %7 %9
)");
@@ -4425,11 +4425,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 16
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -4437,7 +4437,7 @@
%8 = OpTypeFloat 32
%7 = OpTypeVector %8 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%6 = OpFConvert %7 %9
)");
@@ -4453,11 +4453,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 1
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -4465,7 +4465,7 @@
%8 = OpTypeFloat 16
%7 = OpTypeVector %8 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%6 = OpConvertSToF %7 %9
)");
@@ -4481,11 +4481,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 0
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -4493,7 +4493,7 @@
%8 = OpTypeFloat 16
%7 = OpTypeVector %8 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%6 = OpConvertUToF %7 %9
)");
@@ -4509,11 +4509,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateExpression(cast), 6u) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3
%2 = OpTypePointer Private %3
%5 = OpConstantNull %3
@@ -4521,7 +4521,7 @@
%8 = OpTypeFloat 16
%7 = OpTypeVector %8 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%9 = OpLoad %3 %1
%6 = OpFConvert %7 %9
)");
diff --git a/src/tint/writer/spirv/builder_discard_test.cc b/src/tint/writer/spirv/builder_discard_test.cc
index 747b85c..f5c2f8a 100644
--- a/src/tint/writer/spirv/builder_discard_test.cc
+++ b/src/tint/writer/spirv/builder_discard_test.cc
@@ -28,9 +28,9 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateStatement(stmt)) << b.error();
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpKill
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateStatement(stmt)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"(OpKill
)");
}
diff --git a/src/tint/writer/spirv/builder_entry_point_test.cc b/src/tint/writer/spirv/builder_entry_point_test.cc
index 085a6f2..0e057a3 100644
--- a/src/tint/writer/spirv/builder_entry_point_test.cc
+++ b/src/tint/writer/spirv/builder_entry_point_test.cc
@@ -233,7 +233,7 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), R"(OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -330,14 +330,14 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
// Make sure we generate the SampleRateShading capability.
- EXPECT_EQ(DumpInstructions(b.capabilities()),
+ EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
R"(OpCapability Shader
OpCapability SampleRateShading
)");
- EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 BuiltIn SampleId
+ EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %1 BuiltIn SampleId
OpDecorate %1 Flat
)");
}
diff --git a/src/tint/writer/spirv/builder_format_conversion_test.cc b/src/tint/writer/spirv/builder_format_conversion_test.cc
index 1efdcca..6bd075d 100644
--- a/src/tint/writer/spirv/builder_format_conversion_test.cc
+++ b/src/tint/writer/spirv/builder_format_conversion_test.cc
@@ -39,11 +39,11 @@
EXPECT_EQ(b.convert_texel_format_to_spv(param.ast_format), param.spv_format);
if (param.extended_format) {
- EXPECT_EQ(DumpInstructions(b.capabilities()),
+ EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
R"(OpCapability StorageImageExtendedFormats
)");
} else {
- EXPECT_EQ(DumpInstructions(b.capabilities()), "");
+ EXPECT_EQ(DumpInstructions(b.Module().Capabilities()), "");
}
}
diff --git a/src/tint/writer/spirv/builder_function_attribute_test.cc b/src/tint/writer/spirv/builder_function_attribute_test.cc
index 1b23982..c215f21 100644
--- a/src/tint/writer/spirv/builder_function_attribute_test.cc
+++ b/src/tint/writer/spirv/builder_function_attribute_test.cc
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "gmock/gmock.h"
#include "src/tint/ast/stage_attribute.h"
#include "src/tint/ast/workgroup_attribute.h"
#include "src/tint/writer/spirv/spv_dump.h"
@@ -32,8 +33,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
- EXPECT_EQ(DumpInstructions(b.entry_points()),
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().EntryPoints()),
R"(OpEntryPoint Fragment %3 "main"
)");
}
@@ -72,11 +73,11 @@
spirv::Builder& b = Build();
if (var) {
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
}
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
- auto preamble = b.entry_points();
+ auto preamble = b.Module().EntryPoints();
ASSERT_GE(preamble.size(), 1u);
EXPECT_EQ(preamble[0].opcode(), spv::Op::OpEntryPoint);
@@ -98,8 +99,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
- EXPECT_EQ(DumpInstructions(b.execution_modes()),
+ ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().ExecutionModes()),
R"(OpExecutionMode %3 OriginUpperLeft
)");
}
@@ -110,8 +111,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
- EXPECT_EQ(DumpInstructions(b.execution_modes()),
+ ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().ExecutionModes()),
R"(OpExecutionMode %3 LocalSize 1 1 1
)");
}
@@ -125,8 +126,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
- EXPECT_EQ(DumpInstructions(b.execution_modes()),
+ ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().ExecutionModes()),
R"(OpExecutionMode %3 LocalSize 2 4 6
)");
}
@@ -143,8 +144,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
- EXPECT_EQ(DumpInstructions(b.execution_modes()),
+ ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().ExecutionModes()),
R"(OpExecutionMode %3 LocalSize 2 3 4
)");
}
@@ -161,10 +162,13 @@
spirv::Builder& b = Build();
- EXPECT_FALSE(b.GenerateExecutionModes(func, 3)) << b.error();
- EXPECT_EQ(
- b.error(),
- R"(override-expressions should have been removed with the SubstituteOverride transform)");
+ tint::SetInternalCompilerErrorReporter(nullptr);
+
+ EXPECT_FALSE(b.GenerateExecutionModes(func, 3)) << b.Diagnostics();
+ EXPECT_THAT(
+ b.Diagnostics().str(),
+ ::testing::HasSubstr(
+ "override-expressions should have been removed with the SubstituteOverride transform"));
}
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_LiteralAndConst) {
@@ -178,10 +182,13 @@
spirv::Builder& b = Build();
- EXPECT_FALSE(b.GenerateExecutionModes(func, 3)) << b.error();
- EXPECT_EQ(
- b.error(),
- R"(override-expressions should have been removed with the SubstituteOverride transform)");
+ tint::SetInternalCompilerErrorReporter(nullptr);
+
+ EXPECT_FALSE(b.GenerateExecutionModes(func, 3)) << b.Diagnostics();
+ EXPECT_THAT(
+ b.Diagnostics().str(),
+ ::testing::HasSubstr(
+ "override-expressions should have been removed with the SubstituteOverride transform"));
}
TEST_F(BuilderTest, Decoration_ExecutionMode_MultipleFragment) {
@@ -197,8 +204,8 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateFunction(func1)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func2)) << b.error();
+ ASSERT_TRUE(b.GenerateFunction(func1)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func2)) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b),
R"(OpEntryPoint Fragment %3 "main1"
OpEntryPoint Fragment %5 "main2"
@@ -235,7 +242,7 @@
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.execution_modes()),
+ EXPECT_EQ(DumpInstructions(b.Module().ExecutionModes()),
R"(OpExecutionMode %11 OriginUpperLeft
OpExecutionMode %11 DepthReplacing
)");
diff --git a/src/tint/writer/spirv/builder_function_test.cc b/src/tint/writer/spirv/builder_function_test.cc
index 5cf97ea..04b5a84 100644
--- a/src/tint/writer/spirv/builder_function_test.cc
+++ b/src/tint/writer/spirv/builder_function_test.cc
@@ -70,8 +70,8 @@
auto* var_a = program->AST().GlobalVariables()[0];
auto* func = program->AST().Functions()[0];
- ASSERT_TRUE(b.GenerateGlobalVariable(var_a)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var_a)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), R"(OpName %1 "a"
OpName %6 "a_func"
%3 = OpTypeFloat 32
@@ -161,7 +161,7 @@
auto* func = program->AST().Functions()[0];
ASSERT_TRUE(b.GenerateFunction(func));
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
)");
}
@@ -174,7 +174,7 @@
ASSERT_TRUE(b.GenerateFunction(func1));
ASSERT_TRUE(b.GenerateFunction(func2));
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
)");
}
diff --git a/src/tint/writer/spirv/builder_function_variable_test.cc b/src/tint/writer/spirv/builder_function_variable_test.cc
index 72cf12b..9f77d4e 100644
--- a/src/tint/writer/spirv/builder_function_variable_test.cc
+++ b/src/tint/writer/spirv/builder_function_variable_test.cc
@@ -28,16 +28,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "var"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypePointer Function %3
%4 = OpConstantNull %3
)");
- const auto& func = b.functions()[0];
+ const auto& func = b.CurrentFunction();
EXPECT_EQ(DumpInstructions(func.variables()),
R"(%1 = OpVariable %2 Function %4
)");
@@ -50,13 +50,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %6 "var"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %6 "var"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 3
@@ -64,10 +64,10 @@
%7 = OpTypePointer Function %1
%8 = OpConstantNull %1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
R"(%6 = OpVariable %7 Function %8
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %6 %5
)");
}
@@ -81,24 +81,24 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateFunctionVariable(a)) << b.error();
- EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateFunctionVariable(a)) << b.Diagnostics();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %7 "var"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %7 "var"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 3
%3 = OpTypeVector %1 2
%4 = OpConstant %1 1
%8 = OpTypePointer Function %3
%9 = OpConstantNull %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
R"(%7 = OpVariable %8 Function %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%5 = OpFAdd %1 %2 %2
%6 = OpCompositeConstruct %3 %4 %5
OpStore %7 %6
@@ -116,24 +116,24 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
- EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.Diagnostics();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "v"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "v"
OpName %7 "v2"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
R"(%3 = OpVariable %4 Function %5
%7 = OpVariable %4 Function %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%6 = OpLoad %1 %3
OpStore %7 %6
@@ -151,24 +151,24 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
- EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.Diagnostics();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "v"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "v"
OpName %7 "v2"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
R"(%3 = OpVariable %4 Function %5
%7 = OpVariable %4 Function %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
%6 = OpLoad %1 %3
OpStore %7 %6
@@ -186,22 +186,22 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
- EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.Diagnostics();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "v2"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "v2"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
R"(%3 = OpVariable %4 Function %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpStore %3 %2
)");
}
@@ -215,10 +215,10 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 3
@@ -235,10 +235,10 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), ""); // Not a mistake - 'const' is inlined
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), ""); // Not a mistake - 'const' is inlined
}
} // namespace
diff --git a/src/tint/writer/spirv/builder_global_variable_test.cc b/src/tint/writer/spirv/builder_global_variable_test.cc
index 569d5e9..671bacc 100644
--- a/src/tint/writer/spirv/builder_global_variable_test.cc
+++ b/src/tint/writer/spirv/builder_global_variable_test.cc
@@ -30,10 +30,10 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
+ EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "var"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
@@ -47,12 +47,12 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %6 "var"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %6 "var"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 3
@@ -71,17 +71,17 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 42
%4 = OpTypePointer Private %1
%3 = OpVariable %4 Private %2
%6 = OpTypeVoid
%5 = OpTypeFunction %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
)");
Validate(b);
@@ -96,9 +96,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -109,8 +109,8 @@
%10 = OpTypeVoid
%9 = OpTypeFunction %10
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
)");
Validate(b);
@@ -126,9 +126,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 16
%1 = OpTypeVector %2 3
%3 = OpConstant %2 0x1p+0
%4 = OpConstant %2 0x1p+1
@@ -139,8 +139,8 @@
%10 = OpTypeVoid
%9 = OpTypeFunction %10
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
)");
Validate(b);
@@ -155,9 +155,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -168,8 +168,8 @@
%10 = OpTypeVoid
%9 = OpTypeFunction %10
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
)");
Validate(b);
@@ -184,9 +184,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -197,8 +197,8 @@
%10 = OpTypeVoid
%9 = OpTypeFunction %10
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
)");
Validate(b);
@@ -213,9 +213,9 @@
spirv::Builder& b = SanitizeAndBuild();
- ASSERT_TRUE(b.Build()) << b.error();
+ ASSERT_TRUE(b.Build()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
@@ -226,8 +226,8 @@
%10 = OpTypeVoid
%9 = OpTypeFunction %10
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].variables()), R"()");
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()), R"(OpReturn
)");
Validate(b);
@@ -238,13 +238,13 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
+ EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "var"
)");
- EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 Binding 2
+ EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %1 Binding 2
OpDecorate %1 DescriptorSet 3
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeSampler
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeSampler
%2 = OpTypePointer UniformConstant %3
%1 = OpVariable %2 UniformConstant
)");
@@ -324,7 +324,7 @@
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %3 Block
+ EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %3 Block
OpMemberDecorate %3 0 Offset 0
OpMemberDecorate %4 0 Offset 0
OpMemberDecorate %4 1 Offset 4
@@ -332,7 +332,7 @@
OpDecorate %1 Binding 0
OpDecorate %1 DescriptorSet 0
)");
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "b_block"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "b_block"
OpMemberName %3 0 "inner"
OpName %4 "A"
OpMemberName %4 0 "a"
@@ -340,7 +340,7 @@
OpName %1 "b"
OpName %8 "unused_entry_point"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeInt 32 1
%4 = OpTypeStruct %5 %5
%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
@@ -366,21 +366,21 @@
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %3 Block
+ EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %3 Block
OpMemberDecorate %3 0 Offset 0
OpMemberDecorate %4 0 Offset 0
OpDecorate %1 NonWritable
OpDecorate %1 Binding 0
OpDecorate %1 DescriptorSet 0
)");
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "b_block"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "b_block"
OpMemberName %3 0 "inner"
OpName %4 "A"
OpMemberName %4 0 "a"
OpName %1 "b"
OpName %8 "unused_entry_point"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeInt 32 1
%4 = OpTypeStruct %5
%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
@@ -406,21 +406,21 @@
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %3 Block
+ EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %3 Block
OpMemberDecorate %3 0 Offset 0
OpMemberDecorate %4 0 Offset 0
OpDecorate %1 NonWritable
OpDecorate %1 Binding 0
OpDecorate %1 DescriptorSet 0
)");
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "b_block"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "b_block"
OpMemberName %3 0 "inner"
OpName %4 "A"
OpMemberName %4 0 "a"
OpName %1 "b"
OpName %8 "unused_entry_point"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeInt 32 1
%4 = OpTypeStruct %5
%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
@@ -447,7 +447,7 @@
ASSERT_TRUE(b.Build());
- EXPECT_EQ(DumpInstructions(b.annots()),
+ EXPECT_EQ(DumpInstructions(b.Module().Annots()),
R"(OpDecorate %3 Block
OpMemberDecorate %3 0 Offset 0
OpMemberDecorate %4 0 Offset 0
@@ -457,7 +457,7 @@
OpDecorate %6 DescriptorSet 1
OpDecorate %6 Binding 0
)");
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "b_block"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %3 "b_block"
OpMemberName %3 0 "inner"
OpName %4 "A"
OpMemberName %4 0 "a"
@@ -465,7 +465,7 @@
OpName %6 "c"
OpName %9 "unused_entry_point"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeInt 32 1
%4 = OpTypeStruct %5
%3 = OpTypeStruct %4
%2 = OpTypePointer StorageBuffer %3
@@ -486,13 +486,13 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateGlobalVariable(var_a)) << b.error();
+ EXPECT_TRUE(b.GenerateGlobalVariable(var_a)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 NonReadable
+ EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %1 NonReadable
OpDecorate %1 Binding 0
OpDecorate %1 DescriptorSet 0
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeInt 32 0
%3 = OpTypeImage %4 2D 0 0 0 2 R32ui
%2 = OpTypePointer UniformConstant %3
%1 = OpVariable %2 UniformConstant
@@ -518,12 +518,12 @@
std::unique_ptr<spirv::Builder> b =
std::make_unique<spirv::Builder>(program.get(), kZeroInitializeWorkgroupMemory);
- EXPECT_TRUE(b->GenerateGlobalVariable(var_scalar)) << b->error();
- EXPECT_TRUE(b->GenerateGlobalVariable(var_array)) << b->error();
- EXPECT_TRUE(b->GenerateGlobalVariable(var_struct)) << b->error();
- ASSERT_FALSE(b->has_error()) << b->error();
+ EXPECT_TRUE(b->GenerateGlobalVariable(var_scalar)) << b->Diagnostics();
+ EXPECT_TRUE(b->GenerateGlobalVariable(var_array)) << b->Diagnostics();
+ EXPECT_TRUE(b->GenerateGlobalVariable(var_struct)) << b->Diagnostics();
+ ASSERT_FALSE(b->has_error()) << b->Diagnostics();
- EXPECT_EQ(DumpInstructions(b->types()), R"(%3 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b->Module().Types()), R"(%3 = OpTypeInt 32 1
%2 = OpTypePointer Workgroup %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Workgroup %4
diff --git a/src/tint/writer/spirv/builder_ident_expression_test.cc b/src/tint/writer/spirv/builder_ident_expression_test.cc
index 7c56ba1..3917028 100644
--- a/src/tint/writer/spirv/builder_ident_expression_test.cc
+++ b/src/tint/writer/spirv/builder_ident_expression_test.cc
@@ -32,10 +32,10 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"()");
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"()");
EXPECT_EQ(b.GenerateIdentifierExpression(expr), 0u);
}
@@ -48,11 +48,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "var"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
@@ -71,10 +71,10 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 3
@@ -91,16 +91,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "var"
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "var"
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypePointer Function %3
%4 = OpConstantNull %3
)");
- const auto& func = b.functions()[0];
+ const auto& func = b.CurrentFunction();
EXPECT_EQ(DumpInstructions(func.variables()),
R"(%1 = OpVariable %2 Function %4
)");
@@ -115,16 +115,16 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr->As<ast::BinaryExpression>()), 7u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+ EXPECT_EQ(b.GenerateBinaryExpression(expr->As<ast::BinaryExpression>()), 7u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%5 = OpLoad %3 %1
%6 = OpLoad %3 %1
%7 = OpIAdd %3 %5 %6
@@ -138,14 +138,14 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateFunctionVariable(let)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateFunctionVariable(let)) << b.Diagnostics();
- EXPECT_EQ(b.GenerateBinaryExpression(expr->As<ast::BinaryExpression>()), 3u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+ EXPECT_EQ(b.GenerateBinaryExpression(expr->As<ast::BinaryExpression>()), 3u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%3 = OpIAdd %1 %2 %2
)");
}
diff --git a/src/tint/writer/spirv/builder_if_test.cc b/src/tint/writer/spirv/builder_if_test.cc
index 031ed68..3bd4bb2 100644
--- a/src/tint/writer/spirv/builder_if_test.cc
+++ b/src/tint/writer/spirv/builder_if_test.cc
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "gmock/gmock.h"
#include "src/tint/writer/spirv/spv_dump.h"
#include "src/tint/writer/spirv/test_helper.h"
@@ -30,13 +31,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+ EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
%2 = OpConstantTrue %1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpSelectionMerge %3 None
OpBranchConditional %2 %4 %3
%4 = OpLabel
@@ -56,11 +57,13 @@
spirv::Builder& b = Build();
- EXPECT_FALSE(b.GenerateIfStatement(expr)) << b.error();
+ tint::SetInternalCompilerErrorReporter(nullptr);
+
+ EXPECT_FALSE(b.GenerateIfStatement(expr)) << b.Diagnostics();
EXPECT_TRUE(b.has_error());
- EXPECT_EQ(b.error(),
- "Internal error: trying to add SPIR-V instruction 247 outside a "
- "function");
+ EXPECT_THAT(b.Diagnostics().str(),
+ ::testing::HasSubstr(
+ "Internal error: trying to add SPIR-V instruction 247 outside a function"));
}
TEST_F(BuilderTest, If_WithStatements) {
@@ -75,11 +78,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+ EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
@@ -87,7 +90,7 @@
%6 = OpConstantTrue %5
%9 = OpConstant %3 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpSelectionMerge %7 None
OpBranchConditional %6 %8 %7
%8 = OpLabel
@@ -113,11 +116,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+ EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
@@ -126,7 +129,7 @@
%10 = OpConstant %3 2
%11 = OpConstant %3 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpSelectionMerge %7 None
OpBranchConditional %6 %8 %9
%8 = OpLabel
@@ -155,11 +158,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+ EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
@@ -168,7 +171,7 @@
%10 = OpConstant %3 2
%13 = OpConstant %3 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpSelectionMerge %7 None
OpBranchConditional %6 %8 %9
%8 = OpLabel
@@ -211,11 +214,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+ EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
@@ -227,7 +230,7 @@
%19 = OpConstant %3 4
%20 = OpConstant %3 5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpSelectionMerge %7 None
OpBranchConditional %6 %8 %9
%8 = OpLabel
@@ -274,13 +277,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+ EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
%6 = OpConstantTrue %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %1
%1 = OpLabel
OpLoopMerge %2 %3 None
@@ -316,13 +319,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+ EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
%6 = OpConstantTrue %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %1
%1 = OpLabel
OpLoopMerge %2 %3 None
@@ -358,13 +361,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+ EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
%6 = OpConstantTrue %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %1
%1 = OpLabel
OpLoopMerge %2 %3 None
@@ -403,13 +406,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+ EXPECT_TRUE(b.GenerateLoopStatement(expr)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
%6 = OpConstantTrue %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %1
%1 = OpLabel
OpLoopMerge %2 %3 None
@@ -441,13 +444,13 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_TRUE(b.GenerateFunction(fn)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeBool
%6 = OpConstantTrue %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(OpSelectionMerge %7 None
OpBranchConditional %6 %8 %7
%8 = OpLabel
@@ -471,13 +474,13 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+ EXPECT_TRUE(b.GenerateFunction(fn)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
%1 = OpTypeFunction %2
%5 = OpConstantTrue %2
%8 = OpConstantNull %2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(OpSelectionMerge %6 None
OpBranchConditional %5 %7 %6
%7 = OpLabel
@@ -503,13 +506,13 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+ EXPECT_TRUE(b.GenerateFunction(fn)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
%1 = OpTypeFunction %2
%5 = OpConstantTrue %2
%9 = OpConstantNull %2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(OpSelectionMerge %6 None
OpBranchConditional %5 %7 %8
%7 = OpLabel
@@ -541,13 +544,13 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+ EXPECT_TRUE(b.GenerateFunction(fn)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
%1 = OpTypeFunction %2
%5 = OpConstantTrue %2
%8 = OpConstantNull %2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(OpSelectionMerge %6 None
OpBranchConditional %5 %7 %6
%7 = OpLabel
@@ -570,16 +573,16 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
- EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeBool
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
+ EXPECT_TRUE(b.GenerateFunction(fn)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeBool
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
%6 = OpTypeVoid
%5 = OpTypeFunction %6
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(%9 = OpLoad %3 %1
OpSelectionMerge %10 None
OpBranchConditional %9 %11 %10
@@ -602,14 +605,14 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_TRUE(b.GenerateFunction(fn)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeBool
%6 = OpConstantNull %5
%10 = OpConstantTrue %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(OpSelectionMerge %7 None
OpBranchConditional %6 %8 %9
%8 = OpLabel
@@ -643,14 +646,14 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
+ EXPECT_TRUE(b.GenerateFunction(fn)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%9 = OpTypeBool
%10 = OpConstantNull %9
%14 = OpConstantTrue %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.Module().Functions()[0].instructions()),
R"(OpBranch %5
%5 = OpLabel
OpLoopMerge %6 %7 None
diff --git a/src/tint/writer/spirv/builder_literal_test.cc b/src/tint/writer/spirv/builder_literal_test.cc
index 3a9ec29..0bfc7b3 100644
--- a/src/tint/writer/spirv/builder_literal_test.cc
+++ b/src/tint/writer/spirv/builder_literal_test.cc
@@ -28,10 +28,10 @@
spirv::Builder& b = Build();
auto id = b.GenerateLiteralIfNeeded(b_true);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(2u, id);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
%2 = OpConstantTrue %1
)");
}
@@ -43,10 +43,10 @@
spirv::Builder& b = Build();
auto id = b.GenerateLiteralIfNeeded(b_false);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(2u, id);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
%2 = OpConstantFalse %1
)");
}
@@ -59,13 +59,13 @@
spirv::Builder& b = Build();
ASSERT_NE(b.GenerateLiteralIfNeeded(b_true), 0u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
ASSERT_NE(b.GenerateLiteralIfNeeded(b_false), 0u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
ASSERT_NE(b.GenerateLiteralIfNeeded(b_true), 0u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeBool
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeBool
%2 = OpConstantTrue %1
%3 = OpConstantFalse %1
)");
@@ -77,10 +77,10 @@
spirv::Builder& b = Build();
auto id = b.GenerateLiteralIfNeeded(i);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(2u, id);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 -23
)");
}
@@ -94,9 +94,9 @@
ASSERT_NE(b.GenerateLiteralIfNeeded(i1), 0u);
ASSERT_NE(b.GenerateLiteralIfNeeded(i2), 0u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 -23
)");
}
@@ -108,10 +108,10 @@
spirv::Builder& b = Build();
auto id = b.GenerateLiteralIfNeeded(i);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(2u, id);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 23
)");
}
@@ -125,9 +125,9 @@
ASSERT_NE(b.GenerateLiteralIfNeeded(i1), 0u);
ASSERT_NE(b.GenerateLiteralIfNeeded(i2), 0u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 23
)");
}
@@ -139,10 +139,10 @@
spirv::Builder& b = Build();
auto id = b.GenerateLiteralIfNeeded(i);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(2u, id);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 23.2450008
)");
}
@@ -156,9 +156,9 @@
ASSERT_NE(b.GenerateLiteralIfNeeded(i1), 0u);
ASSERT_NE(b.GenerateLiteralIfNeeded(i2), 0u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 23.2450008
)");
}
@@ -172,10 +172,10 @@
spirv::Builder& b = Build();
auto id = b.GenerateLiteralIfNeeded(i);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(2u, id);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1.73cp+4
)");
}
@@ -191,9 +191,9 @@
ASSERT_NE(b.GenerateLiteralIfNeeded(i1), 0u);
ASSERT_NE(b.GenerateLiteralIfNeeded(i2), 0u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 16
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%1 = OpTypeFloat 16
%2 = OpConstant %1 0x1.73cp+4
)");
}
diff --git a/src/tint/writer/spirv/builder_loop_test.cc b/src/tint/writer/spirv/builder_loop_test.cc
index 5fc15b8..380b2b2 100644
--- a/src/tint/writer/spirv/builder_loop_test.cc
+++ b/src/tint/writer/spirv/builder_loop_test.cc
@@ -32,10 +32,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %1
%1 = OpLabel
OpLoopMerge %2 %3 None
@@ -63,17 +63,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+ EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
%9 = OpConstant %3 2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %5
%5 = OpLabel
OpLoopMerge %6 %7 None
@@ -106,18 +106,18 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
+ b.PushFunctionForTesting();
+ ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.Diagnostics();
- EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeInt 32 1
+ EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeInt 32 1
%2 = OpTypePointer Private %3
%4 = OpConstantNull %3
%1 = OpVariable %2 Private %4
%9 = OpConstant %3 2
%10 = OpConstant %3 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %5
%5 = OpLabel
OpLoopMerge %6 %7 None
@@ -150,15 +150,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%7 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%7 = OpTypeInt 32 1
%6 = OpTypePointer Function %7
%8 = OpConstantNull %7
%9 = OpConstant %7 3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %1
%1 = OpLabel
OpLoopMerge %2 %3 None
@@ -184,10 +184,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %1
%1 = OpLabel
OpLoopMerge %2 %3 None
@@ -215,10 +215,10 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %1
%1 = OpLabel
OpLoopMerge %2 %3 None
@@ -244,13 +244,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+ EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
%6 = OpConstantTrue %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %1
%1 = OpLabel
OpLoopMerge %2 %3 None
@@ -275,13 +275,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+ EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
%6 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %1
%1 = OpLabel
OpLoopMerge %2 %3 None
@@ -309,15 +309,15 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeBool
+ EXPECT_TRUE(b.GenerateLoopStatement(loop)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeBool
%6 = OpConstantTrue %5
%8 = OpTypePointer Function %5
%9 = OpConstantNull %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %1
%1 = OpLabel
OpLoopMerge %2 %3 None
@@ -355,13 +355,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_TRUE(b.GenerateLoopStatement(outer_loop)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%9 = OpTypeBool
+ EXPECT_TRUE(b.GenerateLoopStatement(outer_loop)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%9 = OpTypeBool
%10 = OpConstantTrue %9
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpBranch %1
%1 = OpLabel
OpLoopMerge %2 %3 None
diff --git a/src/tint/writer/spirv/builder_return_test.cc b/src/tint/writer/spirv/builder_return_test.cc
index 825529e..13a65d6 100644
--- a/src/tint/writer/spirv/builder_return_test.cc
+++ b/src/tint/writer/spirv/builder_return_test.cc
@@ -28,11 +28,11 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateReturnStatement(ret));
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()), R"(OpReturn
)");
}
@@ -44,17 +44,17 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
EXPECT_TRUE(b.GenerateReturnStatement(ret));
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 3
%5 = OpConstantComposite %1 %3 %3 %4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpReturnValue %5
)");
}
@@ -67,19 +67,19 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
- EXPECT_TRUE(b.GenerateReturnStatement(ret)) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
+ EXPECT_TRUE(b.GenerateReturnStatement(ret)) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypePointer Function %3
%4 = OpConstantNull %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
R"(%1 = OpVariable %2 Function %4
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%5 = OpLoad %3 %1
OpReturnValue %5
)");
diff --git a/src/tint/writer/spirv/builder_switch_test.cc b/src/tint/writer/spirv/builder_switch_test.cc
index 7e0bd18..a66ecd8 100644
--- a/src/tint/writer/spirv/builder_switch_test.cc
+++ b/src/tint/writer/spirv/builder_switch_test.cc
@@ -32,13 +32,13 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
+ b.PushFunctionForTesting();
- EXPECT_TRUE(b.GenerateSwitchStatement(expr)) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ EXPECT_TRUE(b.GenerateSwitchStatement(expr)) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%3 = OpConstant %2 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(OpSelectionMerge %1 None
OpSwitch %3 %4
%4 = OpLabel
@@ -69,9 +69,9 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), R"(OpName %1 "v"
OpName %5 "a"
@@ -126,9 +126,9 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), R"(OpName %1 "v"
OpName %5 "a"
@@ -181,9 +181,9 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), R"(OpName %1 "v"
OpName %5 "a"
@@ -235,9 +235,9 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), R"(OpName %1 "v"
OpName %5 "a"
@@ -294,9 +294,9 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), R"(OpName %1 "v"
OpName %5 "a"
@@ -352,9 +352,9 @@
spirv::Builder& b = Build();
- ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
- ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error();
- ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
+ ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.Diagnostics();
+ ASSERT_TRUE(b.GenerateFunction(func)) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), R"(OpName %1 "v"
OpName %5 "a"
@@ -413,7 +413,7 @@
spirv::Builder& b = Build();
- EXPECT_TRUE(b.GenerateFunction(fn)) << b.error();
+ EXPECT_TRUE(b.GenerateFunction(fn)) << b.Diagnostics();
EXPECT_EQ(DumpBuilder(b), R"(OpName %3 "f"
%2 = OpTypeInt 32 1
%1 = OpTypeFunction %2
diff --git a/src/tint/writer/spirv/builder_test.cc b/src/tint/writer/spirv/builder_test.cc
index 1c79988..718f246 100644
--- a/src/tint/writer/spirv/builder_test.cc
+++ b/src/tint/writer/spirv/builder_test.cc
@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "src/tint/writer/spirv/spv_dump.h"
#include "src/tint/writer/spirv/test_helper.h"
namespace tint::writer::spirv {
@@ -38,33 +37,5 @@
R"(12:34 error: SPIR-V backend does not support extension 'undefined')");
}
-TEST_F(BuilderTest, TracksIdBounds) {
- spirv::Builder& b = Build();
-
- for (size_t i = 0; i < 5; i++) {
- EXPECT_EQ(b.next_id(), i + 1);
- }
-
- EXPECT_EQ(6u, b.id_bound());
-}
-
-TEST_F(BuilderTest, Capabilities_Dedup) {
- spirv::Builder& b = Build();
-
- b.push_capability(SpvCapabilityShader);
- b.push_capability(SpvCapabilityShader);
- b.push_capability(SpvCapabilityShader);
-
- EXPECT_EQ(DumpInstructions(b.capabilities()), "OpCapability Shader\n");
-}
-
-TEST_F(BuilderTest, DeclareExtension) {
- spirv::Builder& b = Build();
-
- b.push_extension("SPV_KHR_integer_dot_product");
-
- EXPECT_EQ(DumpInstructions(b.extensions()), "OpExtension \"SPV_KHR_integer_dot_product\"\n");
-}
-
} // namespace
} // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/builder_type_test.cc b/src/tint/writer/spirv/builder_type_test.cc
index 89ba34e..87c4cf3 100644
--- a/src/tint/writer/spirv/builder_type_test.cc
+++ b/src/tint/writer/spirv/builder_type_test.cc
@@ -36,10 +36,10 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(program->TypeOf(type));
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(1u, id);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%1 = OpTypeRuntimeArray %2
)");
}
@@ -55,9 +55,9 @@
EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(type)), 1u);
EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(type)), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%1 = OpTypeRuntimeArray %2
)");
}
@@ -69,10 +69,10 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(program->TypeOf(type));
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(1u, id);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%3 = OpTypeInt 32 0
%4 = OpConstant %3 4
%1 = OpTypeArray %2 %4
@@ -86,13 +86,13 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(program->TypeOf(ty));
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(1u, id);
- EXPECT_EQ(DumpInstructions(b.annots()), R"(OpDecorate %1 ArrayStride 16
+ EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpDecorate %1 ArrayStride 16
)");
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%3 = OpTypeInt 32 0
%4 = OpConstant %3 4
%1 = OpTypeArray %2 %4
@@ -107,9 +107,9 @@
EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%3 = OpTypeInt 32 0
%4 = OpConstant %3 4
%1 = OpTypeArray %2 %4
@@ -122,11 +122,11 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(bool_);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(id, 1u);
- ASSERT_EQ(b.types().size(), 1u);
- EXPECT_EQ(DumpInstruction(b.types()[0]), R"(%1 = OpTypeBool
+ ASSERT_EQ(b.Module().Types().size(), 1u);
+ EXPECT_EQ(DumpInstruction(b.Module().Types()[0]), R"(%1 = OpTypeBool
)");
}
@@ -137,11 +137,11 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(bool_), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(i32), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(bool_), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
}
TEST_F(BuilderTest_Type, GenerateF32) {
@@ -150,11 +150,11 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(f32);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(id, 1u);
- ASSERT_EQ(b.types().size(), 1u);
- EXPECT_EQ(DumpInstruction(b.types()[0]), R"(%1 = OpTypeFloat 32
+ ASSERT_EQ(b.Module().Types().size(), 1u);
+ EXPECT_EQ(DumpInstruction(b.Module().Types()[0]), R"(%1 = OpTypeFloat 32
)");
}
@@ -165,11 +165,11 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(f32), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(i32), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(f32), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
}
TEST_F(BuilderTest_Type, GenerateF16) {
@@ -178,11 +178,11 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(f16);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(id, 1u);
- ASSERT_EQ(b.types().size(), 1u);
- EXPECT_EQ(DumpInstruction(b.types()[0]), R"(%1 = OpTypeFloat 16
+ ASSERT_EQ(b.Module().Types().size(), 1u);
+ EXPECT_EQ(DumpInstruction(b.Module().Types()[0]), R"(%1 = OpTypeFloat 16
)");
}
@@ -193,11 +193,11 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(f16), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(i32), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(f16), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
}
TEST_F(BuilderTest_Type, GenerateI32) {
@@ -206,11 +206,11 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(i32);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(id, 1u);
- ASSERT_EQ(b.types().size(), 1u);
- EXPECT_EQ(DumpInstruction(b.types()[0]), R"(%1 = OpTypeInt 32 1
+ ASSERT_EQ(b.Module().Types().size(), 1u);
+ EXPECT_EQ(DumpInstruction(b.Module().Types()[0]), R"(%1 = OpTypeInt 32 1
)");
}
@@ -221,11 +221,11 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(i32), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(f32), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(i32), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
}
TEST_F(BuilderTest_Type, GenerateMatrix) {
@@ -236,11 +236,11 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(mat2x3);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(id, 1u);
- EXPECT_EQ(b.types().size(), 3u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 32
+ EXPECT_EQ(b.Module().Types().size(), 3u);
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 32
%2 = OpTypeVector %3 3
%1 = OpTypeMatrix %2 2
)");
@@ -254,11 +254,11 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(mat), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(i32), 3u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(mat), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
}
TEST_F(BuilderTest_Type, GenerateF16Matrix) {
@@ -269,11 +269,11 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(mat2x3);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(id, 1u);
- EXPECT_EQ(b.types().size(), 3u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeFloat 16
+ EXPECT_EQ(b.Module().Types().size(), 3u);
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%3 = OpTypeFloat 16
%2 = OpTypeVector %3 3
%1 = OpTypeMatrix %2 2
)");
@@ -287,11 +287,11 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(mat), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(f16), 3u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(mat), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
}
TEST_F(BuilderTest_Type, GeneratePtr) {
@@ -302,10 +302,10 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(ptr);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(1u, id);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%1 = OpTypePointer Output %2
)");
}
@@ -329,14 +329,14 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(program->TypeOf(s));
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(id, 1u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%3 = OpTypeFloat 16
%1 = OpTypeStruct %2 %3
)");
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "my_struct"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "my_struct"
OpMemberName %1 0 "a"
OpMemberName %1 1 "b"
)");
@@ -355,20 +355,20 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(program->TypeOf(s));
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(id, 1u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%3 = OpTypeFloat 16
%1 = OpTypeStruct %2 %2 %3 %3
)");
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "S"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "S"
OpMemberName %1 0 "a"
OpMemberName %1 1 "b"
OpMemberName %1 2 "c"
OpMemberName %1 3 "d"
)");
- EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %1 0 Offset 0
+ EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpMemberDecorate %1 0 Offset 0
OpMemberDecorate %1 1 Offset 8
OpMemberDecorate %1 2 Offset 16
OpMemberDecorate %1 3 Offset 18
@@ -391,10 +391,10 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(program->TypeOf(s));
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(id, 1u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 2
%2 = OpTypeMatrix %3 2
%6 = OpTypeVector %4 3
@@ -410,7 +410,7 @@
%14 = OpTypeMatrix %15 4
%1 = OpTypeStruct %2 %5 %7 %9 %12 %14
)");
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "S"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "S"
OpMemberName %1 0 "mat2x2_f32"
OpMemberName %1 1 "mat2x3_f32"
OpMemberName %1 2 "mat4x4_f32"
@@ -418,7 +418,7 @@
OpMemberName %1 4 "mat2x3_f16"
OpMemberName %1 5 "mat4x4_f16"
)");
- EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %1 0 Offset 0
+ EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpMemberDecorate %1 0 Offset 0
OpMemberDecorate %1 0 ColMajor
OpMemberDecorate %1 0 MatrixStride 8
OpMemberDecorate %1 1 Offset 64
@@ -462,10 +462,10 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(program->TypeOf(s));
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(id, 1u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%5 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%5 = OpTypeFloat 32
%4 = OpTypeVector %5 2
%3 = OpTypeMatrix %4 2
%6 = OpTypeInt 32 0
@@ -489,14 +489,14 @@
%21 = OpTypeRuntimeArray %22
%1 = OpTypeStruct %2 %8 %12 %17 %21
)");
- EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %1 "S"
+ EXPECT_EQ(DumpInstructions(b.Module().Debug()), R"(OpName %1 "S"
OpMemberName %1 0 "arr_mat2x2_f32"
OpMemberName %1 1 "arr_mat2x2_f16"
OpMemberName %1 2 "arr_arr_mat2x3_f32"
OpMemberName %1 3 "arr_arr_mat2x3_f16"
OpMemberName %1 4 "rtarr_mat4x4"
)");
- EXPECT_EQ(DumpInstructions(b.annots()), R"(OpMemberDecorate %1 0 Offset 0
+ EXPECT_EQ(DumpInstructions(b.Module().Annots()), R"(OpMemberDecorate %1 0 Offset 0
OpMemberDecorate %1 0 ColMajor
OpMemberDecorate %1 0 MatrixStride 8
OpDecorate %2 ArrayStride 16
@@ -527,11 +527,11 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(u32);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(id, 1u);
- ASSERT_EQ(b.types().size(), 1u);
- EXPECT_EQ(DumpInstruction(b.types()[0]), R"(%1 = OpTypeInt 32 0
+ ASSERT_EQ(b.Module().Types().size(), 1u);
+ EXPECT_EQ(DumpInstruction(b.Module().Types()[0]), R"(%1 = OpTypeInt 32 0
)");
}
@@ -542,11 +542,11 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(u32), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(f32), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(u32), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
}
TEST_F(BuilderTest_Type, GenerateVector) {
@@ -555,11 +555,11 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(vec);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(id, 1u);
- EXPECT_EQ(b.types().size(), 2u);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(b.Module().Types().size(), 2u);
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
)");
}
@@ -571,11 +571,11 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(vec), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(i32), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(vec), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
}
TEST_F(BuilderTest_Type, GenerateVoid) {
@@ -584,11 +584,11 @@
spirv::Builder& b = Build();
auto id = b.GenerateTypeIfNeeded(void_);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(id, 1u);
- ASSERT_EQ(b.types().size(), 1u);
- EXPECT_EQ(DumpInstruction(b.types()[0]), R"(%1 = OpTypeVoid
+ ASSERT_EQ(b.Module().Types().size(), 1u);
+ EXPECT_EQ(DumpInstruction(b.Module().Types()[0]), R"(%1 = OpTypeVoid
)");
}
@@ -599,11 +599,11 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(void_), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(i32), 2u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(b.GenerateTypeIfNeeded(void_), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
}
struct PtrData {
@@ -643,10 +643,10 @@
spirv::Builder& b = Build();
auto id_two_d = b.GenerateTypeIfNeeded(two_d);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(1u, id_two_d);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 2D 0 0 0 1 Unknown
)");
}
@@ -657,10 +657,10 @@
spirv::Builder& b = Build();
auto id_two_d_array = b.GenerateTypeIfNeeded(two_d_array);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(1u, id_two_d_array);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 2D 0 1 0 1 Unknown
)");
}
@@ -671,13 +671,13 @@
spirv::Builder& b = Build();
auto id_cube = b.GenerateTypeIfNeeded(cube);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(1u, id_cube);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 Cube 0 0 0 1 Unknown
)");
- EXPECT_EQ(DumpInstructions(b.capabilities()), "");
+ EXPECT_EQ(DumpInstructions(b.Module().Capabilities()), "");
}
TEST_F(BuilderTest_Type, DepthTexture_Generate_CubeArray) {
@@ -686,13 +686,13 @@
spirv::Builder& b = Build();
auto id_cube_array = b.GenerateTypeIfNeeded(cube_array);
- ASSERT_FALSE(b.has_error()) << b.error();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
EXPECT_EQ(1u, id_cube_array);
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 Cube 0 1 0 1 Unknown
)");
- EXPECT_EQ(DumpInstructions(b.capabilities()),
+ EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
R"(OpCapability SampledCubeArray
)");
}
@@ -704,8 +704,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(1u, b.GenerateTypeIfNeeded(ms));
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%1 = OpTypeImage %2 2D 0 0 1 1 Unknown
)");
}
@@ -717,8 +717,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(ms), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeInt 32 0
%1 = OpTypeImage %2 2D 0 0 1 1 Unknown
)");
@@ -731,8 +731,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(ms), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 2D 0 0 1 1 Unknown
)");
@@ -744,13 +744,13 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeInt 32 1
%1 = OpTypeImage %2 1D 0 0 0 1 Unknown
)");
- EXPECT_EQ(DumpInstructions(b.capabilities()),
+ EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
R"(OpCapability Sampled1D
)");
}
@@ -762,13 +762,13 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeInt 32 0
%1 = OpTypeImage %2 1D 0 0 0 1 Unknown
)");
- EXPECT_EQ(DumpInstructions(b.capabilities()),
+ EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
R"(OpCapability Sampled1D
)");
}
@@ -780,13 +780,13 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 1D 0 0 0 1 Unknown
)");
- EXPECT_EQ(DumpInstructions(b.capabilities()),
+ EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
R"(OpCapability Sampled1D
)");
}
@@ -798,8 +798,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 2D 0 0 0 1 Unknown
)");
@@ -812,8 +812,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 2D 0 1 0 1 Unknown
)");
@@ -826,8 +826,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 3D 0 0 0 1 Unknown
)");
@@ -840,12 +840,12 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 Cube 0 0 0 1 Unknown
)");
- EXPECT_EQ(DumpInstructions(b.capabilities()), "");
+ EXPECT_EQ(DumpInstructions(b.Module().Capabilities()), "");
}
TEST_F(BuilderTest_Type, SampledTexture_Generate_CubeArray) {
@@ -855,12 +855,12 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(s), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()),
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()),
R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 Cube 0 1 0 1 Unknown
)");
- EXPECT_EQ(DumpInstructions(b.capabilities()),
+ EXPECT_EQ(DumpInstructions(b.Module().Capabilities()),
R"(OpCapability SampledCubeArray
)");
}
@@ -874,8 +874,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 1D 0 0 0 2 R32f
)");
}
@@ -889,8 +889,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 2D 0 0 0 2 R32f
)");
}
@@ -904,8 +904,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 2D 0 1 0 2 R32f
)");
}
@@ -919,8 +919,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 3D 0 0 0 2 R32f
)");
}
@@ -934,8 +934,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeImage %2 2D 0 0 0 2 R32f
)");
}
@@ -949,8 +949,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%1 = OpTypeImage %2 2D 0 0 0 2 R32i
)");
}
@@ -964,8 +964,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(program->TypeOf(ty)), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 0
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 0
%1 = OpTypeImage %2 2D 0 0 0 2 R32ui
)");
}
@@ -976,8 +976,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(sampler), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), "%1 = OpTypeSampler\n");
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), "%1 = OpTypeSampler\n");
}
TEST_F(BuilderTest_Type, ComparisonSampler) {
@@ -986,8 +986,8 @@
spirv::Builder& b = Build();
EXPECT_EQ(b.GenerateTypeIfNeeded(sampler), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), "%1 = OpTypeSampler\n");
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), "%1 = OpTypeSampler\n");
}
TEST_F(BuilderTest_Type, Dedup_Sampler_And_ComparisonSampler) {
@@ -1000,8 +1000,8 @@
EXPECT_EQ(b.GenerateTypeIfNeeded(sampler), 1u);
- ASSERT_FALSE(b.has_error()) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), "%1 = OpTypeSampler\n");
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), "%1 = OpTypeSampler\n");
}
} // namespace
diff --git a/src/tint/writer/spirv/builder_unary_op_expression_test.cc b/src/tint/writer/spirv/builder_unary_op_expression_test.cc
index e28eb78..3998371 100644
--- a/src/tint/writer/spirv/builder_unary_op_expression_test.cc
+++ b/src/tint/writer/spirv/builder_unary_op_expression_test.cc
@@ -28,12 +28,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ b.PushFunctionForTesting();
+ EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%3 = OpConstant %2 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%1 = OpSNegate %2 %3
)");
}
@@ -44,12 +44,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
+ b.PushFunctionForTesting();
+ EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeFloat 32
%3 = OpConstant %2 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%1 = OpFNegate %2 %3
)");
}
@@ -60,12 +60,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
+ b.PushFunctionForTesting();
+ EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeInt 32 1
%3 = OpConstant %2 1
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%1 = OpNot %2 %3
)");
}
@@ -76,12 +76,12 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.error();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
+ b.PushFunctionForTesting();
+ EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 1u) << b.Diagnostics();
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%2 = OpTypeBool
%3 = OpConstantNull %2
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%1 = OpLogicalNot %2 %3
)");
}
@@ -94,20 +94,20 @@
spirv::Builder& b = Build();
- b.push_function(Function{});
- EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.error();
- EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 6u) << b.error();
- ASSERT_FALSE(b.has_error()) << b.error();
+ b.PushFunctionForTesting();
+ EXPECT_TRUE(b.GenerateFunctionVariable(var)) << b.Diagnostics();
+ EXPECT_EQ(b.GenerateUnaryOpExpression(expr), 6u) << b.Diagnostics();
+ ASSERT_FALSE(b.has_error()) << b.Diagnostics();
- EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 32
+ EXPECT_EQ(DumpInstructions(b.Module().Types()), R"(%4 = OpTypeFloat 32
%3 = OpTypeVector %4 3
%2 = OpTypePointer Function %3
%5 = OpConstantNull %3
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().variables()),
R"(%1 = OpVariable %2 Function %5
)");
- EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
+ EXPECT_EQ(DumpInstructions(b.CurrentFunction().instructions()),
R"(%7 = OpLoad %3 %1
%6 = OpFNegate %3 %7
)");
diff --git a/src/tint/writer/spirv/function.cc b/src/tint/writer/spirv/function.cc
index 871ef3f..8f2499d 100644
--- a/src/tint/writer/spirv/function.cc
+++ b/src/tint/writer/spirv/function.cc
@@ -25,6 +25,8 @@
Function::Function(const Function& other) = default;
+Function& Function::operator=(const Function& other) = default;
+
Function::~Function() = default;
void Function::iterate(std::function<void(const Instruction&)> cb) const {
diff --git a/src/tint/writer/spirv/function.h b/src/tint/writer/spirv/function.h
index 05012f2..ef611c6 100644
--- a/src/tint/writer/spirv/function.h
+++ b/src/tint/writer/spirv/function.h
@@ -38,6 +38,11 @@
/// Copy constructor
/// @param other the function to copy
Function(const Function& other);
+ /// Copy assignment operator
+ /// @param other the function to copy
+ /// @returns the new Function
+ Function& operator=(const Function& other);
+ /// Destructor
~Function();
/// Iterates over the function call the cb on each instruction
@@ -84,6 +89,9 @@
return size;
}
+ /// @returns true if the function has a valid declaration
+ explicit operator bool() const { return declaration_.opcode() == spv::Op::OpFunction; }
+
private:
Instruction declaration_;
Operand label_op_;
diff --git a/src/tint/writer/spirv/generator.cc b/src/tint/writer/spirv/generator.cc
index 93ac6e1..de6178b 100644
--- a/src/tint/writer/spirv/generator.cc
+++ b/src/tint/writer/spirv/generator.cc
@@ -17,6 +17,10 @@
#include <utility>
#include "src/tint/writer/spirv/generator_impl.h"
+#if TINT_BUILD_IR
+#include "src/tint/ir/from_program.h" // nogncheck
+#include "src/tint/writer/spirv/generator_impl_ir.h" // nogncheck
+#endif // TINT_BUILD_IR
namespace tint::writer::spirv {
@@ -31,23 +35,41 @@
return result;
}
- // Sanitize the program.
- auto sanitized_result = Sanitize(program, options);
- if (!sanitized_result.program.IsValid()) {
- result.success = false;
- result.error = sanitized_result.program.Diagnostics().str();
- return result;
- }
-
- // Generate the SPIR-V code.
bool zero_initialize_workgroup_memory =
!options.disable_workgroup_init && options.use_zero_initialize_workgroup_memory_extension;
- auto impl = std::make_unique<GeneratorImpl>(&sanitized_result.program,
- zero_initialize_workgroup_memory);
- result.success = impl->Generate();
- result.error = impl->error();
- result.spirv = std::move(impl->result());
+#if TINT_BUILD_IR
+ if (options.use_tint_ir) {
+ // Convert the AST program to an IR module.
+ auto ir = ir::FromProgram(program);
+ if (!ir) {
+ result.error = "IR converter: " + ir.Failure();
+ return result;
+ }
+
+ // Generate the SPIR-V code.
+ auto impl = std::make_unique<GeneratorImplIr>(&ir.Get(), zero_initialize_workgroup_memory);
+ result.success = impl->Generate();
+ result.error = impl->Diagnostics().str();
+ result.spirv = std::move(impl->Result());
+ } else // NOLINT(readability/braces)
+#endif
+ {
+ // Sanitize the program.
+ auto sanitized_result = Sanitize(program, options);
+ if (!sanitized_result.program.IsValid()) {
+ result.success = false;
+ result.error = sanitized_result.program.Diagnostics().str();
+ return result;
+ }
+
+ // Generate the SPIR-V code.
+ auto impl = std::make_unique<GeneratorImpl>(&sanitized_result.program,
+ zero_initialize_workgroup_memory);
+ result.success = impl->Generate();
+ result.error = impl->Diagnostics().str();
+ result.spirv = std::move(impl->Result());
+ }
return result;
}
diff --git a/src/tint/writer/spirv/generator.h b/src/tint/writer/spirv/generator.h
index d24d938..0200426 100644
--- a/src/tint/writer/spirv/generator.h
+++ b/src/tint/writer/spirv/generator.h
@@ -60,6 +60,11 @@
/// VK_KHR_zero_initialize_workgroup_memory is enabled.
bool use_zero_initialize_workgroup_memory_extension = false;
+#if TINT_BUILD_IR
+ /// Set to `true` to generate SPIR-V via the Tint IR instead of from the AST.
+ bool use_tint_ir = false;
+#endif
+
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
TINT_REFLECT(disable_robustness,
emit_vertex_point_size,
diff --git a/src/tint/writer/spirv/generator_impl.cc b/src/tint/writer/spirv/generator_impl.cc
index 80485c9..88bd39a 100644
--- a/src/tint/writer/spirv/generator_impl.cc
+++ b/src/tint/writer/spirv/generator_impl.cc
@@ -119,7 +119,7 @@
polyfills.quantize_to_vec_f16 = true; // crbug.com/tint/1741
polyfills.workgroup_uniform_load = true;
data.Add<transform::BuiltinPolyfill::Config>(polyfills);
- manager.Add<transform::BuiltinPolyfill>();
+ manager.Add<transform::BuiltinPolyfill>(); // Must come before DirectVariableAccess
}
bool disable_workgroup_init_in_sanitizer =
@@ -175,23 +175,12 @@
bool GeneratorImpl::Generate() {
if (builder_.Build()) {
- writer_.WriteHeader(builder_.id_bound());
- writer_.WriteBuilder(&builder_);
+ auto& module = builder_.Module();
+ writer_.WriteHeader(module.IdBound());
+ writer_.WriteModule(&module);
return true;
}
return false;
}
-const std::vector<uint32_t>& GeneratorImpl::result() const {
- return writer_.result();
-}
-
-std::vector<uint32_t>& GeneratorImpl::result() {
- return writer_.result();
-}
-
-std::string GeneratorImpl::error() const {
- return builder_.error();
-}
-
} // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/generator_impl.h b/src/tint/writer/spirv/generator_impl.h
index c83f144..3fd745d 100644
--- a/src/tint/writer/spirv/generator_impl.h
+++ b/src/tint/writer/spirv/generator_impl.h
@@ -49,13 +49,10 @@
bool Generate();
/// @returns the result data
- const std::vector<uint32_t>& result() const;
+ const std::vector<uint32_t>& Result() const { return writer_.result(); }
- /// @returns the result data
- std::vector<uint32_t>& result();
-
- /// @returns the error
- std::string error() const;
+ /// @returns the list of diagnostics raised by the generator
+ diag::List Diagnostics() const { return builder_.Diagnostics(); }
private:
Builder builder_;
diff --git a/src/tint/writer/spirv/generator_impl_function_test.cc b/src/tint/writer/spirv/generator_impl_function_test.cc
new file mode 100644
index 0000000..e4cb71b
--- /dev/null
+++ b/src/tint/writer/spirv/generator_impl_function_test.cc
@@ -0,0 +1,50 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/writer/spirv/test_helper_ir.h"
+
+namespace tint::writer::spirv {
+namespace {
+
+TEST_F(SpvGeneratorImplTest, Function_Empty) {
+ auto* func = CreateFunction();
+ func->name = ir.symbols.Register("foo");
+ func->return_type = ir.types.Get<type::Void>();
+
+ generator_.EmitFunction(func);
+ EXPECT_EQ(DumpModule(generator_.Module()), R"(OpName %1 "foo"
+%2 = OpTypeVoid
+%3 = OpTypeFunction %2
+%1 = OpFunction %2 None %3
+%4 = OpLabel
+OpReturn
+OpFunctionEnd
+)");
+}
+
+// Test that we do not emit the same function type more than once.
+TEST_F(SpvGeneratorImplTest, Function_DeduplicateType) {
+ auto* func = CreateFunction();
+ func->return_type = ir.types.Get<type::Void>();
+
+ generator_.EmitFunction(func);
+ generator_.EmitFunction(func);
+ generator_.EmitFunction(func);
+ EXPECT_EQ(DumpTypes(), R"(%2 = OpTypeVoid
+%3 = OpTypeFunction %2
+)");
+}
+
+} // namespace
+} // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/generator_impl_ir.cc b/src/tint/writer/spirv/generator_impl_ir.cc
new file mode 100644
index 0000000..855662a
--- /dev/null
+++ b/src/tint/writer/spirv/generator_impl_ir.cc
@@ -0,0 +1,127 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/writer/spirv/generator_impl_ir.h"
+
+#include "spirv/unified1/spirv.h"
+#include "src/tint/ir/module.h"
+#include "src/tint/switch.h"
+#include "src/tint/type/bool.h"
+#include "src/tint/type/f16.h"
+#include "src/tint/type/f32.h"
+#include "src/tint/type/i32.h"
+#include "src/tint/type/type.h"
+#include "src/tint/type/u32.h"
+#include "src/tint/type/void.h"
+#include "src/tint/writer/spirv/module.h"
+
+namespace tint::writer::spirv {
+
+GeneratorImplIr::GeneratorImplIr(const ir::Module* module, bool zero_init_workgroup_mem)
+ : ir_(module), zero_init_workgroup_memory_(zero_init_workgroup_mem) {}
+
+bool GeneratorImplIr::Generate() {
+ // TODO(crbug.com/tint/1906): Check supported extensions.
+
+ module_.PushCapability(SpvCapabilityShader);
+ module_.PushMemoryModel(spv::Op::OpMemoryModel, {U32Operand(SpvAddressingModelLogical),
+ U32Operand(SpvMemoryModelGLSL450)});
+
+ // TODO(crbug.com/tint/1906): Emit extensions.
+
+ // TODO(crbug.com/tint/1906): Emit variables.
+ (void)zero_init_workgroup_memory_;
+
+ // Emit functions.
+ for (auto* func : ir_->functions) {
+ EmitFunction(func);
+ }
+
+ // Serialize the module into binary SPIR-V.
+ writer_.WriteHeader(module_.IdBound());
+ writer_.WriteModule(&module_);
+
+ return true;
+}
+
+uint32_t GeneratorImplIr::Type(const type::Type* ty) {
+ return types_.GetOrCreate(ty, [&]() {
+ auto id = module_.NextId();
+ Switch(
+ ty, //
+ [&](const type::Void*) { module_.PushType(spv::Op::OpTypeVoid, {id}); },
+ [&](const type::Bool*) { module_.PushType(spv::Op::OpTypeBool, {id}); },
+ [&](const type::I32*) {
+ module_.PushType(spv::Op::OpTypeInt, {id, 32u, 1u});
+ },
+ [&](const type::U32*) {
+ module_.PushType(spv::Op::OpTypeInt, {id, 32u, 0u});
+ },
+ [&](const type::F32*) {
+ module_.PushType(spv::Op::OpTypeFloat, {id, 32u});
+ },
+ [&](const type::F16*) {
+ module_.PushType(spv::Op::OpTypeFloat, {id, 16u});
+ },
+ [&](Default) {
+ TINT_ICE(Writer, diagnostics_) << "unhandled type: " << ty->FriendlyName();
+ });
+ return id;
+ });
+}
+
+void GeneratorImplIr::EmitFunction(const ir::Function* func) {
+ // Make an ID for the function.
+ auto id = module_.NextId();
+
+ // Emit the function name.
+ module_.PushDebug(spv::Op::OpName, {id, Operand(func->name.Name())});
+
+ // TODO(jrprice): Emit OpEntryPoint and OpExecutionMode declarations if needed.
+
+ // Get the ID for the return type.
+ auto return_type_id = Type(func->return_type);
+
+ // Get the ID for the function type (creating it if needed).
+ // TODO(jrprice): Add the parameter types when they are supported in the IR.
+ FunctionType function_type{return_type_id, {}};
+ auto function_type_id = function_types_.GetOrCreate(function_type, [&]() {
+ auto func_ty_id = module_.NextId();
+ OperandList operands = {func_ty_id, return_type_id};
+ operands.insert(operands.end(), function_type.param_type_ids.begin(),
+ function_type.param_type_ids.end());
+ module_.PushType(spv::Op::OpTypeFunction, operands);
+ return func_ty_id;
+ });
+
+ // Declare the function.
+ auto decl =
+ Instruction{spv::Op::OpFunction,
+ {return_type_id, id, U32Operand(SpvFunctionControlMaskNone), function_type_id}};
+
+ // Create a function that we will add instructions to.
+ // TODO(jrprice): Add the parameter declarations when they are supported in the IR.
+ auto entry_block = module_.NextId();
+ Function current_function_(decl, entry_block, {});
+
+ // TODO(jrprice): Emit the body of the function.
+
+ // TODO(jrprice): Remove this when we start emitting OpReturn for branches to the terminator.
+ current_function_.push_inst(spv::Op::OpReturn, {});
+
+ // Add the function to the module.
+ module_.PushFunction(current_function_);
+}
+
+} // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/generator_impl_ir.h b/src/tint/writer/spirv/generator_impl_ir.h
new file mode 100644
index 0000000..d9aab3c
--- /dev/null
+++ b/src/tint/writer/spirv/generator_impl_ir.h
@@ -0,0 +1,109 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_WRITER_SPIRV_GENERATOR_IMPL_IR_H_
+#define SRC_TINT_WRITER_SPIRV_GENERATOR_IMPL_IR_H_
+
+#include <vector>
+
+#include "src/tint/diagnostic/diagnostic.h"
+#include "src/tint/utils/hashmap.h"
+#include "src/tint/utils/vector.h"
+#include "src/tint/writer/spirv/binary_writer.h"
+#include "src/tint/writer/spirv/module.h"
+
+// Forward declarations
+namespace tint::ir {
+class Function;
+class Module;
+} // namespace tint::ir
+namespace tint::type {
+class Type;
+} // namespace tint::type
+
+namespace tint::writer::spirv {
+
+/// Implementation class for SPIR-V generator
+class GeneratorImplIr {
+ public:
+ /// Constructor
+ /// @param module the Tint IR module to generate
+ /// @param zero_init_workgroup_memory `true` to initialize all the variables in the Workgroup
+ /// storage class with OpConstantNull
+ GeneratorImplIr(const ir::Module* module, bool zero_init_workgroup_memory);
+
+ /// @returns true on successful generation; false otherwise
+ bool Generate();
+
+ /// @returns the module that this generator has produced
+ spirv::Module& Module() { return module_; }
+
+ /// @returns the generated SPIR-V binary data
+ const std::vector<uint32_t>& Result() const { return writer_.result(); }
+
+ /// @returns the list of diagnostics raised by the generator
+ diag::List Diagnostics() const { return diagnostics_; }
+
+ /// Get the result ID of the type `ty`, emitting a type declaration instruction if necessary.
+ /// @param ty the type to get the ID for
+ /// @returns the result ID of the type
+ uint32_t Type(const type::Type* ty);
+
+ /// Emit a function.
+ /// @param func the function to emit
+ void EmitFunction(const ir::Function* func);
+
+ private:
+ const ir::Module* ir_;
+ spirv::Module module_;
+ BinaryWriter writer_;
+ diag::List diagnostics_;
+
+ /// A function type used for an OpTypeFunction declaration.
+ struct FunctionType {
+ uint32_t return_type_id;
+ utils::Vector<uint32_t, 4> param_type_ids;
+
+ /// Hasher provides a hash function for the FunctionType.
+ struct Hasher {
+ /// @param ft the FunctionType to create a hash for
+ /// @return the hash value
+ inline std::size_t operator()(const FunctionType& ft) const {
+ size_t hash = utils::Hash(ft.return_type_id);
+ for (auto& p : ft.param_type_ids) {
+ hash = utils::HashCombine(hash, p);
+ }
+ return hash;
+ }
+ };
+
+ /// Equality operator for FunctionType.
+ bool operator==(const FunctionType& other) const {
+ return (param_type_ids == other.param_type_ids) &&
+ (return_type_id == other.return_type_id);
+ }
+ };
+
+ /// The map of types to their result IDs.
+ utils::Hashmap<const type::Type*, uint32_t, 8> types_;
+
+ /// The map of function types to their result IDs.
+ utils::Hashmap<FunctionType, uint32_t, 8, FunctionType::Hasher> function_types_;
+
+ bool zero_init_workgroup_memory_ = false;
+};
+
+} // namespace tint::writer::spirv
+
+#endif // SRC_TINT_WRITER_SPIRV_GENERATOR_IMPL_IR_H_
diff --git a/src/tint/writer/spirv/generator_impl_ir_test.cc b/src/tint/writer/spirv/generator_impl_ir_test.cc
new file mode 100644
index 0000000..a202eea
--- /dev/null
+++ b/src/tint/writer/spirv/generator_impl_ir_test.cc
@@ -0,0 +1,29 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/writer/spirv/test_helper_ir.h"
+
+namespace tint::writer::spirv {
+namespace {
+
+TEST_F(SpvGeneratorImplTest, ModuleHeader) {
+ ASSERT_TRUE(generator_.Generate()) << generator_.Diagnostics().str();
+ auto got = Disassemble(generator_.Result());
+ EXPECT_EQ(got, R"(OpCapability Shader
+OpMemoryModel Logical GLSL450
+)");
+}
+
+} // namespace
+} // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/generator_impl_type_test.cc b/src/tint/writer/spirv/generator_impl_type_test.cc
new file mode 100644
index 0000000..c8a2e8e
--- /dev/null
+++ b/src/tint/writer/spirv/generator_impl_type_test.cc
@@ -0,0 +1,87 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/type/bool.h"
+#include "src/tint/type/f16.h"
+#include "src/tint/type/f32.h"
+#include "src/tint/type/i32.h"
+#include "src/tint/type/type.h"
+#include "src/tint/type/u32.h"
+#include "src/tint/type/void.h"
+#include "src/tint/writer/spirv/test_helper_ir.h"
+
+namespace tint::writer::spirv {
+namespace {
+
+TEST_F(SpvGeneratorImplTest, Type_Void) {
+ auto id = generator_.Type(ir.types.Get<type::Void>());
+ EXPECT_EQ(id, 1u);
+ EXPECT_EQ(DumpTypes(), "%1 = OpTypeVoid\n");
+}
+
+TEST_F(SpvGeneratorImplTest, Type_Bool) {
+ auto id = generator_.Type(ir.types.Get<type::Bool>());
+ EXPECT_EQ(id, 1u);
+ EXPECT_EQ(DumpTypes(), "%1 = OpTypeBool\n");
+}
+
+TEST_F(SpvGeneratorImplTest, Type_I32) {
+ auto id = generator_.Type(ir.types.Get<type::I32>());
+ EXPECT_EQ(id, 1u);
+ EXPECT_EQ(DumpTypes(), "%1 = OpTypeInt 32 1\n");
+}
+
+TEST_F(SpvGeneratorImplTest, Type_U32) {
+ auto id = generator_.Type(ir.types.Get<type::U32>());
+ EXPECT_EQ(id, 1u);
+ EXPECT_EQ(DumpTypes(), "%1 = OpTypeInt 32 0\n");
+}
+
+TEST_F(SpvGeneratorImplTest, Type_F32) {
+ auto id = generator_.Type(ir.types.Get<type::F32>());
+ EXPECT_EQ(id, 1u);
+ EXPECT_EQ(DumpTypes(), "%1 = OpTypeFloat 32\n");
+}
+
+TEST_F(SpvGeneratorImplTest, Type_F16) {
+ auto id = generator_.Type(ir.types.Get<type::F16>());
+ EXPECT_EQ(id, 1u);
+ EXPECT_EQ(DumpTypes(), "%1 = OpTypeFloat 16\n");
+}
+
+// Test that we do can emit multiple types.
+// Includes types with the same opcode but different parameters.
+TEST_F(SpvGeneratorImplTest, Type_Multiple) {
+ EXPECT_EQ(generator_.Type(ir.types.Get<type::I32>()), 1u);
+ EXPECT_EQ(generator_.Type(ir.types.Get<type::U32>()), 2u);
+ EXPECT_EQ(generator_.Type(ir.types.Get<type::F32>()), 3u);
+ EXPECT_EQ(generator_.Type(ir.types.Get<type::F16>()), 4u);
+ EXPECT_EQ(DumpTypes(), R"(%1 = OpTypeInt 32 1
+%2 = OpTypeInt 32 0
+%3 = OpTypeFloat 32
+%4 = OpTypeFloat 16
+)");
+}
+
+// Test that we do not emit the same type more than once.
+TEST_F(SpvGeneratorImplTest, Type_Deduplicate) {
+ auto* i32 = ir.types.Get<type::I32>();
+ EXPECT_EQ(generator_.Type(i32), 1u);
+ EXPECT_EQ(generator_.Type(i32), 1u);
+ EXPECT_EQ(generator_.Type(i32), 1u);
+ EXPECT_EQ(DumpTypes(), "%1 = OpTypeInt 32 1\n");
+}
+
+} // namespace
+} // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/instruction.cc b/src/tint/writer/spirv/instruction.cc
index 8b883c1..e2caac6 100644
--- a/src/tint/writer/spirv/instruction.cc
+++ b/src/tint/writer/spirv/instruction.cc
@@ -23,6 +23,8 @@
Instruction::Instruction(const Instruction&) = default;
+Instruction& Instruction::operator=(const Instruction&) = default;
+
Instruction::~Instruction() = default;
uint32_t Instruction::word_length() const {
diff --git a/src/tint/writer/spirv/instruction.h b/src/tint/writer/spirv/instruction.h
index 2beae59..3664335 100644
--- a/src/tint/writer/spirv/instruction.h
+++ b/src/tint/writer/spirv/instruction.h
@@ -31,6 +31,11 @@
Instruction(spv::Op op, OperandList operands);
/// Copy Constructor
Instruction(const Instruction&);
+ /// Copy assignment operator
+ /// @param other the instruction to copy
+ /// @returns the new Instruction
+ Instruction& operator=(const Instruction& other);
+ /// Destructor
~Instruction();
/// @returns the instructions op
diff --git a/src/tint/writer/spirv/module.cc b/src/tint/writer/spirv/module.cc
new file mode 100644
index 0000000..3084c79
--- /dev/null
+++ b/src/tint/writer/spirv/module.cc
@@ -0,0 +1,101 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/writer/spirv/module.h"
+
+namespace tint::writer::spirv {
+namespace {
+
+/// Helper to return the size in words of an instruction list when serialized.
+/// @param instructions the instruction list
+/// @returns the number of words needed to serialize the list
+uint32_t SizeOf(const InstructionList& instructions) {
+ uint32_t size = 0;
+ for (const auto& inst : instructions) {
+ size += inst.word_length();
+ }
+ return size;
+}
+
+} // namespace
+
+Module::Module() {}
+
+Module::~Module() = default;
+
+uint32_t Module::TotalSize() const {
+ // The 5 covers the magic, version, generator, id bound and reserved.
+ uint32_t size = 5;
+
+ size += SizeOf(capabilities_);
+ size += SizeOf(extensions_);
+ size += SizeOf(ext_imports_);
+ size += SizeOf(memory_model_);
+ size += SizeOf(entry_points_);
+ size += SizeOf(execution_modes_);
+ size += SizeOf(debug_);
+ size += SizeOf(annotations_);
+ size += SizeOf(types_);
+ for (const auto& func : functions_) {
+ size += func.word_length();
+ }
+
+ return size;
+}
+
+void Module::Iterate(std::function<void(const Instruction&)> cb) const {
+ for (const auto& inst : capabilities_) {
+ cb(inst);
+ }
+ for (const auto& inst : extensions_) {
+ cb(inst);
+ }
+ for (const auto& inst : ext_imports_) {
+ cb(inst);
+ }
+ for (const auto& inst : memory_model_) {
+ cb(inst);
+ }
+ for (const auto& inst : entry_points_) {
+ cb(inst);
+ }
+ for (const auto& inst : execution_modes_) {
+ cb(inst);
+ }
+ for (const auto& inst : debug_) {
+ cb(inst);
+ }
+ for (const auto& inst : annotations_) {
+ cb(inst);
+ }
+ for (const auto& inst : types_) {
+ cb(inst);
+ }
+ for (const auto& func : functions_) {
+ func.iterate(cb);
+ }
+}
+
+void Module::PushCapability(uint32_t cap) {
+ if (capability_set_.count(cap) == 0) {
+ capability_set_.insert(cap);
+ capabilities_.push_back(Instruction{spv::Op::OpCapability, {Operand(cap)}});
+ }
+}
+
+void Module::PushExtension(const char* extension) {
+ extensions_.push_back(Instruction{spv::Op::OpExtension, {Operand(extension)}});
+}
+
+} // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/module.h b/src/tint/writer/spirv/module.h
new file mode 100644
index 0000000..00caad8
--- /dev/null
+++ b/src/tint/writer/spirv/module.h
@@ -0,0 +1,161 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_WRITER_SPIRV_MODULE_H_
+#define SRC_TINT_WRITER_SPIRV_MODULE_H_
+
+#include <cstdint>
+#include <functional>
+#include <unordered_set>
+#include <vector>
+
+#include "src/tint/writer/spirv/function.h"
+#include "src/tint/writer/spirv/instruction.h"
+
+namespace tint::writer::spirv {
+
+/// A SPIR-V module.
+class Module {
+ public:
+ /// Constructor
+ Module();
+
+ /// Destructor
+ ~Module();
+
+ /// @returns the number of uint32_t's needed to make up the results
+ uint32_t TotalSize() const;
+
+ /// @returns the id bound for this program
+ uint32_t IdBound() const { return next_id_; }
+
+ /// @returns the next id to be used
+ uint32_t NextId() {
+ auto id = next_id_;
+ next_id_ += 1;
+ return id;
+ }
+
+ /// Iterates over all the instructions in the correct order and calls the given callback.
+ /// @param cb the callback to execute
+ void Iterate(std::function<void(const Instruction&)> cb) const;
+
+ /// Add an instruction to the list of capabilities, if the capability hasn't already been added.
+ /// @param cap the capability to set
+ void PushCapability(uint32_t cap);
+
+ /// @returns the capabilities
+ const InstructionList& Capabilities() const { return capabilities_; }
+
+ /// Add an instruction to the list of extensions.
+ /// @param extension the name of the extension
+ void PushExtension(const char* extension);
+
+ /// @returns the extensions
+ const InstructionList& Extensions() const { return extensions_; }
+
+ /// Add an instruction to the list of imported extension instructions.
+ /// @param op the op to set
+ /// @param operands the operands for the instruction
+ void PushExtImport(spv::Op op, const OperandList& operands) {
+ ext_imports_.push_back(Instruction{op, operands});
+ }
+
+ /// @returns the ext imports
+ const InstructionList& ExtImports() const { return ext_imports_; }
+
+ /// Add an instruction to the memory model.
+ /// @param op the op to set
+ /// @param operands the operands for the instruction
+ void PushMemoryModel(spv::Op op, const OperandList& operands) {
+ memory_model_.push_back(Instruction{op, operands});
+ }
+
+ /// @returns the memory model
+ const InstructionList& MemoryModel() const { return memory_model_; }
+
+ /// Add an instruction to the list pf entry points.
+ /// @param op the op to set
+ /// @param operands the operands for the instruction
+ void PushEntryPoint(spv::Op op, const OperandList& operands) {
+ entry_points_.push_back(Instruction{op, operands});
+ }
+ /// @returns the entry points
+ const InstructionList& EntryPoints() const { return entry_points_; }
+
+ /// Add an instruction to the execution mode declarations.
+ /// @param op the op to set
+ /// @param operands the operands for the instruction
+ void PushExecutionMode(spv::Op op, const OperandList& operands) {
+ execution_modes_.push_back(Instruction{op, operands});
+ }
+
+ /// @returns the execution modes
+ const InstructionList& ExecutionModes() const { return execution_modes_; }
+
+ /// Add an instruction to the debug declarations.
+ /// @param op the op to set
+ /// @param operands the operands for the instruction
+ void PushDebug(spv::Op op, const OperandList& operands) {
+ debug_.push_back(Instruction{op, operands});
+ }
+
+ /// @returns the debug instructions
+ const InstructionList& Debug() const { return debug_; }
+
+ /// Add an instruction to the type declarations.
+ /// @param op the op to set
+ /// @param operands the operands for the instruction
+ void PushType(spv::Op op, const OperandList& operands) {
+ types_.push_back(Instruction{op, operands});
+ }
+
+ /// @returns the type instructions
+ const InstructionList& Types() const { return types_; }
+
+ /// Add an instruction to the annotations.
+ /// @param op the op to set
+ /// @param operands the operands for the instruction
+ void PushAnnot(spv::Op op, const OperandList& operands) {
+ annotations_.push_back(Instruction{op, operands});
+ }
+
+ /// @returns the annotations
+ const InstructionList& Annots() const { return annotations_; }
+
+ /// Add a function to the module.
+ /// @param func the function to add
+ void PushFunction(const Function& func) { functions_.push_back(func); }
+
+ /// @returns the functions
+ const std::vector<Function>& Functions() const { return functions_; }
+
+ private:
+ uint32_t next_id_ = 1;
+ InstructionList capabilities_;
+ InstructionList extensions_;
+ InstructionList ext_imports_;
+ InstructionList memory_model_;
+ InstructionList entry_points_;
+ InstructionList execution_modes_;
+ InstructionList debug_;
+ InstructionList types_;
+ InstructionList annotations_;
+ std::vector<Function> functions_;
+ std::unordered_set<uint32_t> capability_set_;
+};
+
+} // namespace tint::writer::spirv
+
+#endif // SRC_TINT_WRITER_SPIRV_MODULE_H_
diff --git a/src/tint/writer/spirv/module_test.cc b/src/tint/writer/spirv/module_test.cc
new file mode 100644
index 0000000..07fef6d
--- /dev/null
+++ b/src/tint/writer/spirv/module_test.cc
@@ -0,0 +1,52 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/writer/spirv/spv_dump.h"
+#include "src/tint/writer/spirv/test_helper.h"
+
+namespace tint::writer::spirv {
+namespace {
+
+using SpvModuleTest = TestHelper;
+
+TEST_F(SpvModuleTest, TracksIdBounds) {
+ spirv::Module m;
+
+ for (size_t i = 0; i < 5; i++) {
+ EXPECT_EQ(m.NextId(), i + 1);
+ }
+
+ EXPECT_EQ(6u, m.IdBound());
+}
+
+TEST_F(SpvModuleTest, Capabilities_Dedup) {
+ spirv::Module m;
+
+ m.PushCapability(SpvCapabilityShader);
+ m.PushCapability(SpvCapabilityShader);
+ m.PushCapability(SpvCapabilityShader);
+
+ EXPECT_EQ(DumpInstructions(m.Capabilities()), "OpCapability Shader\n");
+}
+
+TEST_F(SpvModuleTest, DeclareExtension) {
+ spirv::Module m;
+
+ m.PushExtension("SPV_KHR_integer_dot_product");
+
+ EXPECT_EQ(DumpInstructions(m.Extensions()), "OpExtension \"SPV_KHR_integer_dot_product\"\n");
+}
+
+} // namespace
+} // namespace tint::writer::spirv
diff --git a/src/tint/writer/spirv/spv_dump.cc b/src/tint/writer/spirv/spv_dump.cc
index 0f95efe..9a63786 100644
--- a/src/tint/writer/spirv/spv_dump.cc
+++ b/src/tint/writer/spirv/spv_dump.cc
@@ -18,7 +18,6 @@
#include "src/tint/writer/spirv/binary_writer.h"
namespace tint::writer::spirv {
-namespace {
std::string Disassemble(const std::vector<uint32_t>& data) {
std::string spv_errors;
@@ -56,12 +55,14 @@
return result;
}
-} // namespace
-
std::string DumpBuilder(Builder& builder) {
+ return DumpModule(builder.Module());
+}
+
+std::string DumpModule(Module& module) {
BinaryWriter writer;
- writer.WriteHeader(builder.id_bound());
- writer.WriteBuilder(&builder);
+ writer.WriteHeader(module.IdBound());
+ writer.WriteModule(&module);
return Disassemble(writer.result());
}
diff --git a/src/tint/writer/spirv/spv_dump.h b/src/tint/writer/spirv/spv_dump.h
index 2147d1d..359f0cb 100644
--- a/src/tint/writer/spirv/spv_dump.h
+++ b/src/tint/writer/spirv/spv_dump.h
@@ -22,11 +22,21 @@
namespace tint::writer::spirv {
+/// Disassembles SPIR-V binary data into its textual form.
+/// @param data the SPIR-V binary data
+/// @returns the disassembled SPIR-V string
+std::string Disassemble(const std::vector<uint32_t>& data);
+
/// Dumps the given builder to a SPIR-V disassembly string
/// @param builder the builder to convert
/// @returns the builder as a SPIR-V disassembly string
std::string DumpBuilder(Builder& builder);
+/// Dumps the given module to a SPIR-V disassembly string
+/// @param module the module to convert
+/// @returns the module as a SPIR-V disassembly string
+std::string DumpModule(Module& module);
+
/// Dumps the given instruction to a SPIR-V disassembly string
/// @param inst the instruction to dump
/// @returns the instruction as a SPIR-V disassembly string
diff --git a/src/tint/writer/spirv/test_helper.h b/src/tint/writer/spirv/test_helper.h
index 028d363..b9a90be 100644
--- a/src/tint/writer/spirv/test_helper.h
+++ b/src/tint/writer/spirv/test_helper.h
@@ -94,8 +94,8 @@
/// @param b the spirv::Builder containing the built SPIR-V module
void Validate(spirv::Builder& b) {
BinaryWriter writer;
- writer.WriteHeader(b.id_bound());
- writer.WriteBuilder(&b);
+ writer.WriteHeader(b.Module().IdBound());
+ writer.WriteModule(&b.Module());
auto binary = writer.result();
std::string spv_errors;
diff --git a/src/tint/writer/spirv/test_helper_ir.h b/src/tint/writer/spirv/test_helper_ir.h
new file mode 100644
index 0000000..6de6f48
--- /dev/null
+++ b/src/tint/writer/spirv/test_helper_ir.h
@@ -0,0 +1,48 @@
+// Copyright 2023 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_WRITER_SPIRV_TEST_HELPER_IR_H_
+#define SRC_TINT_WRITER_SPIRV_TEST_HELPER_IR_H_
+
+#include <string>
+
+#include "gtest/gtest.h"
+#include "src/tint/ir/builder.h"
+#include "src/tint/writer/spirv/generator_impl_ir.h"
+#include "src/tint/writer/spirv/spv_dump.h"
+
+namespace tint::writer::spirv {
+
+/// Base helper class for testing the SPIR-V generator implementation.
+template <typename BASE>
+class SpvGeneratorTestHelperBase : public ir::Builder, public BASE {
+ public:
+ SpvGeneratorTestHelperBase() : generator_(&ir, false) {}
+
+ protected:
+ /// The SPIR-V generator.
+ GeneratorImplIr generator_;
+
+ /// @returns the disassembled types from the generated module.
+ std::string DumpTypes() { return DumpInstructions(generator_.Module().Types()); }
+};
+
+using SpvGeneratorImplTest = SpvGeneratorTestHelperBase<testing::Test>;
+
+template <typename T>
+using SpvGeneratorImplTestWithParam = SpvGeneratorTestHelperBase<testing::TestWithParam<T>>;
+
+} // namespace tint::writer::spirv
+
+#endif // SRC_TINT_WRITER_SPIRV_TEST_HELPER_IR_H_