Update spirv-reader tests to be valid for WebGPU

- each vertex shader must have builtin-position output.
- when testing non-vertex shader features, change to fragment shaders,
  to avoid the need to have a builtin position output.
- Fix ordering of entry point declaration vs. OpName

Bug: tint:1043
Change-Id: Ic66383d42419a1ef893835ae71729ae27fc6e539
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/59482
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: James Price <jrprice@google.com>
Auto-Submit: David Neto <dneto@google.com>
This commit is contained in:
David Neto 2021-07-26 16:59:51 +00:00 committed by Tint LUCI CQ
parent dd2e2ba4e2
commit d77c00f419
11 changed files with 456 additions and 66 deletions

View File

@ -60,7 +60,8 @@ std::string SimplePreamble() {
return R"( return R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "main" OpEntryPoint Fragment %100 "main"
OpExecutionMode %100 OriginUpperLeft
)" + CommonTypes(); )" + CommonTypes();
} }

View File

@ -29,7 +29,8 @@ std::string Preamble() {
return R"( return R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "x_100" OpEntryPoint Fragment %100 "x_100"
OpExecutionMode %100 OriginUpperLeft
)"; )";
} }
@ -68,7 +69,7 @@ TEST_F(SpvParserTest, EmitStatement_VoidCallNoParams) {
Return{} Return{}
} }
Function $3 -> __void Function $3 -> __void
StageDecoration{vertex} StageDecoration{fragment}
() ()
{ {
Call[not set]{ Call[not set]{
@ -286,7 +287,7 @@ TEST_F(SpvParserTest, EmitStatement_CallWithParams) {
Return{} Return{}
} }
Function x_100 -> __void Function x_100 -> __void
StageDecoration{vertex} StageDecoration{fragment}
() ()
{ {
Call[not set]{ Call[not set]{

View File

@ -469,7 +469,8 @@ TEST_F(SpvParserTest_CompositeExtract, Struct_DifferOnlyInMemberName) {
const std::string assembly = R"( const std::string assembly = R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "main" OpEntryPoint Fragment %100 "main"
OpExecutionMode %100 OriginUpperLeft
OpMemberName %s0 0 "algo" OpMemberName %s0 0 "algo"
OpMemberName %s1 0 "rithm" OpMemberName %s1 0 "rithm"
@ -927,7 +928,8 @@ TEST_F(SpvParserTest_CompositeInsert, Struct_DifferOnlyInMemberName) {
const std::string assembly = R"( const std::string assembly = R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "main" OpEntryPoint Fragment %100 "main"
OpExecutionMode %100 OriginUpperLeft
OpName %var0 "var0" OpName %var0 "var0"
OpName %var1 "var1" OpName %var1 "var1"

View File

@ -29,7 +29,8 @@ std::string Preamble() {
return R"( return R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "main" OpEntryPoint Fragment %100 "main"
OpExecutionMode %100 OriginUpperLeft
%void = OpTypeVoid %void = OpTypeVoid
%voidfn = OpTypeFunction %void %voidfn = OpTypeFunction %void

View File

@ -28,7 +28,8 @@ std::string Preamble() {
return R"( return R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "x_100" OpEntryPoint Fragment %100 "x_100"
OpExecutionMode %100 OriginUpperLeft
)"; )";
} }

View File

@ -28,7 +28,8 @@ std::string Preamble() {
return R"( return R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "main" OpEntryPoint Fragment %100 "main"
OpExecutionMode %100 OriginUpperLeft
%void = OpTypeVoid %void = OpTypeVoid
%voidfn = OpTypeFunction %void %voidfn = OpTypeFunction %void

View File

@ -31,7 +31,8 @@ std::string Preamble() {
return R"( return R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "main" OpEntryPoint Fragment %100 "main"
OpExecutionMode %100 OriginUpperLeft
)"; )";
} }
@ -340,7 +341,7 @@ TEST_F(SpvParserMemoryTest, EmitStatement_AccessChain_NoOperands) {
OpReturn OpReturn
)"); )");
EXPECT_THAT(err, EXPECT_THAT(err,
Eq("15:5: Expected operand, found next instruction instead.")); Eq("16:5: Expected operand, found next instruction instead."));
} }
TEST_F(SpvParserMemoryTest, EmitStatement_AccessChain_BaseIsNotPointer) { TEST_F(SpvParserMemoryTest, EmitStatement_AccessChain_BaseIsNotPointer) {
@ -889,7 +890,7 @@ TEST_F(SpvParserMemoryTest, EmitStatement_AccessChain_DereferenceBase) {
Return{} Return{}
} }
Function main -> __void Function main -> __void
StageDecoration{vertex} StageDecoration{fragment}
() ()
{ {
Call[not set]{ Call[not set]{
@ -1291,7 +1292,8 @@ std::string RuntimeArrayPreamble() {
return R"( return R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "main" OpEntryPoint Fragment %100 "main"
OpExecutionMode %100 OriginUpperLeft
OpName %myvar "myvar" OpName %myvar "myvar"
OpMemberName %struct 0 "first" OpMemberName %struct 0 "first"

View File

@ -85,7 +85,8 @@ std::string Caps(std::vector<std::string> ids = {}) {
return R"( return R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "main" OpEntryPoint Fragment %100 "main"
OpExecutionMode %100 OriginUpperLeft
)" + Names(ids); )" + Names(ids);
} }
@ -497,7 +498,8 @@ TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_ArrayInitializer_Alias) {
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "main" OpEntryPoint Fragment %100 "main"
OpExecutionMode %100 OriginUpperLeft
OpDecorate %arr2uint ArrayStride 16 OpDecorate %arr2uint ArrayStride 16
)" + CommonTypes() + R"( )" + CommonTypes() + R"(
%ptr = OpTypePointer Function %arr2uint %ptr = OpTypePointer Function %arr2uint
@ -574,7 +576,8 @@ TEST_F(SpvParserFunctionVarTest,
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "main" OpEntryPoint Fragment %100 "main"
OpExecutionMode %100 OriginUpperLeft
OpDecorate %arr2uint ArrayStride 16 OpDecorate %arr2uint ArrayStride 16
)" + CommonTypes() + R"( )" + CommonTypes() + R"(
%ptr = OpTypePointer Function %arr2uint %ptr = OpTypePointer Function %arr2uint
@ -769,7 +772,8 @@ TEST_F(SpvParserFunctionVarTest,
auto p = parser(test::Assemble(R"( auto p = parser(test::Assemble(R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %100 "main" OpEntryPoint Fragment %100 "main"
OpExecutionMode %100 OriginUpperLeft
OpName %_struct_5 "S" OpName %_struct_5 "S"
OpName %_struct_6 "S" OpName %_struct_6 "S"
OpMemberName %_struct_5 0 "algo" OpMemberName %_struct_5 0 "algo"

View File

@ -27,7 +27,8 @@ std::string Preamble() {
return R"( return R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %main "x_100" OpEntryPoint Fragment %main "x_100"
OpExecutionMode %main OriginUpperLeft
)"; )";
} }
@ -75,7 +76,8 @@ TEST_F(SpvParserTest, ConvertType_IdExistsButIsNotAType) {
OpCapability Shader OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450" %1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %main "x_100" OpEntryPoint Fragment %main "x_100"
OpExecutionMode %main OriginUpperLeft
)" + MainBody(); )" + MainBody();
auto p = parser(test::Assemble(assembly)); auto p = parser(test::Assemble(assembly));
EXPECT_TRUE(p->BuildInternalModule()); EXPECT_TRUE(p->BuildInternalModule());

View File

@ -32,7 +32,8 @@ std::string Caps() {
std::string Preamble() { std::string Preamble() {
return Caps() + R"( return Caps() + R"(
OpEntryPoint Vertex %main "x_100" OpEntryPoint Fragment %main "x_100"
OpExecutionMode %main OriginUpperLeft
)"; )";
} }
@ -62,10 +63,22 @@ std::string CommonTypes() {
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%int = OpTypeInt 32 1 %int = OpTypeInt 32 1
%float_0 = OpConstant %float 0.0
)"; )";
} }
std::string BuiltinPosition() {
return R"(OpDecorate %position BuiltIn Position
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%ptr = OpTypePointer Output %v4float
%position = OpVariable %ptr Output
%void = OpTypeVoid
%voidfn = OpTypeFunction %void
%uint = OpTypeInt 32 0
%int = OpTypeInt 32 1
)";
}
TEST_F(SpvParserTest, EmitFunctions_NoFunctions) { TEST_F(SpvParserTest, EmitFunctions_NoFunctions) {
auto p = parser(test::Assemble( auto p = parser(test::Assemble(
R"( R"(
@ -95,8 +108,10 @@ TEST_F(SpvParserTest, EmitFunctions_FunctionWithoutBody) {
} }
TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_Vertex) { TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_Vertex) {
std::string input = Caps() + R"(OpEntryPoint Vertex %main "main" )" + std::string input = Caps() +
Names({"main"}) + CommonTypes() + R"( R"(OpEntryPoint Vertex %main "main" %position )" +
Names({"main"}) + BuiltinPosition() + R"(
%main = OpFunction %void None %voidfn %main = OpFunction %void None %voidfn
%entry = OpLabel %entry = OpLabel
OpReturn OpReturn
@ -107,9 +122,15 @@ OpFunctionEnd)";
ASSERT_TRUE(p->error().empty()) << p->error(); ASSERT_TRUE(p->error().empty()) << p->error();
Program program = p->program(); Program program = p->program();
const auto program_ast = program.to_str(false); const auto program_ast = program.to_str(false);
EXPECT_THAT(program_ast, HasSubstr(R"(
Struct $3 {
StructMember{[[ BuiltinDecoration{position}
]] $4: __vec_4__f32})"))
<< program_ast;
EXPECT_THAT(program_ast, HasSubstr(R"( EXPECT_THAT(program_ast, HasSubstr(R"(
Function )" + program.Symbols().Get("main").to_str() + Function )" + program.Symbols().Get("main").to_str() +
R"( -> __void R"( -> __type_name_$3
StageDecoration{vertex} StageDecoration{vertex}
() ()
{)")); {)"));
@ -163,8 +184,9 @@ TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_GLCompute) {
TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_MultipleEntryPoints) { TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_MultipleEntryPoints) {
std::string input = Caps() + std::string input = Caps() +
R"( R"(
OpEntryPoint Vertex %main "first_shader" OpEntryPoint Fragment %main "first_shader"
OpEntryPoint Vertex %main "second_shader" OpEntryPoint Fragment %main "second_shader"
OpExecutionMode %main OriginUpperLeft
)" + Names({"main"}) + CommonTypes() + )" + Names({"main"}) + CommonTypes() +
MainBody(); MainBody();
@ -176,23 +198,24 @@ OpEntryPoint Vertex %main "second_shader"
EXPECT_THAT(program_ast, HasSubstr(R"( EXPECT_THAT(program_ast, HasSubstr(R"(
Function )" + program.Symbols().Get("first_shader").to_str() + Function )" + program.Symbols().Get("first_shader").to_str() +
R"( -> __void R"( -> __void
StageDecoration{vertex} StageDecoration{fragment}
() ()
{)")); {)"));
EXPECT_THAT(program_ast, HasSubstr(R"( EXPECT_THAT(program_ast, HasSubstr(R"(
Function )" + program.Symbols().Get("second_shader").to_str() + Function )" + program.Symbols().Get("second_shader").to_str() +
R"( -> __void R"( -> __void
StageDecoration{vertex} StageDecoration{fragment}
() ()
{)")); {)"));
} }
TEST_F(SpvParserTest, TEST_F(SpvParserTest,
EmitFunctions_Function_EntryPoint_GLCompute_LocalSize_Only) { EmitFunctions_Function_EntryPoint_GLCompute_LocalSize_Only) {
std::string input = Caps() + Names({"main"}) + std::string input = Caps() + R"(
R"(OpEntryPoint GLCompute %main "comp_main" OpEntryPoint GLCompute %main "comp_main"
OpExecutionMode %main LocalSize 2 4 8 OpExecutionMode %main LocalSize 2 4 8
)" + CommonTypes() + R"( )" + Names({"main"}) + CommonTypes() +
R"(
%main = OpFunction %void None %voidfn %main = OpFunction %void None %voidfn
%entry = OpLabel %entry = OpLabel
OpReturn OpReturn
@ -477,6 +500,7 @@ TEST_F(SpvParserTest, EmitFunctions_CalleePrecedesCaller) {
TEST_F(SpvParserTest, EmitFunctions_NonVoidResultType) { TEST_F(SpvParserTest, EmitFunctions_NonVoidResultType) {
auto p = parser( auto p = parser(
test::Assemble(Preamble() + Names({"ret_float"}) + CommonTypes() + R"( test::Assemble(Preamble() + Names({"ret_float"}) + CommonTypes() + R"(
%float_0 = OpConstant %float 0.0
%fn_ret_float = OpTypeFunction %float %fn_ret_float = OpTypeFunction %float
%ret_float = OpFunction %float None %fn_ret_float %ret_float = OpFunction %float None %fn_ret_float

View File

@ -259,13 +259,19 @@ TEST_F(SpvModuleScopeVarParserTest, BuiltinVertexIndex) {
// See later for tests where the SPIR-V store type is signed // See later for tests where the SPIR-V store type is signed
// integer, as in GLSL. // integer, as in GLSL.
auto p = parser(test::Assemble(Preamble() + R"( auto p = parser(test::Assemble(Preamble() + R"(
OpEntryPoint Vertex %main "main" %52 OpEntryPoint Vertex %main "main" %52 %position
OpName %position "position"
OpDecorate %position BuiltIn Position
OpDecorate %52 BuiltIn VertexIndex OpDecorate %52 BuiltIn VertexIndex
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%ptr = OpTypePointer Input %uint %ptr = OpTypePointer Input %uint
%52 = OpVariable %ptr Input %52 = OpVariable %ptr Input
%void = OpTypeVoid %void = OpTypeVoid
%voidfn = OpTypeFunction %void %voidfn = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%posty = OpTypePointer Output %v4float
%position = OpVariable %posty Output
)" + MainBody())); )" + MainBody()));
EXPECT_TRUE(p->BuildAndParseInternalModule()); EXPECT_TRUE(p->BuildAndParseInternalModule());
@ -725,17 +731,22 @@ std::string LoosePointSizePreamble(std::string stage = "Vertex") {
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint )" + OpEntryPoint )" +
stage + R"( %500 "main" %1 stage + R"( %500 "main" %1
)" + (stage == "Fragment" ? "OpExecutionMode %500 OriginUpperLeft" : "") + )" + (stage == "Vertex" ? " %2 " : "") +
+(stage == "Fragment" ? "OpExecutionMode %500 OriginUpperLeft" : "") +
+(stage == "Vertex" ? " OpDecorate %2 BuiltIn Position " : "") +
R"( R"(
OpDecorate %1 BuiltIn PointSize OpDecorate %1 BuiltIn PointSize
%void = OpTypeVoid %void = OpTypeVoid
%voidfn = OpTypeFunction %void %voidfn = OpTypeFunction %void
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%uint = OpTypeInt 32 0 %uint = OpTypeInt 32 0
%uint_0 = OpConstant %uint 0 %uint_0 = OpConstant %uint 0
%uint_1 = OpConstant %uint 1 %uint_1 = OpConstant %uint 1
%11 = OpTypePointer Output %float %11 = OpTypePointer Output %float
%1 = OpVariable %11 Output %1 = OpVariable %11 Output
%12 = OpTypePointer Output %v4float
%2 = OpVariable %12 Output
)"; )";
} }
@ -755,12 +766,22 @@ TEST_F(SpvModuleScopeVarParserTest, BuiltinPointSize_Loose_Write1_IsErased) {
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
EXPECT_EQ(module_str, R"(Module{ EXPECT_EQ(module_str, R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] x_2_1: __vec_4__f32}
}
Variable{
x_2
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
() ()
{ {
@ -769,6 +790,14 @@ TEST_F(SpvModuleScopeVarParserTest, BuiltinPointSize_Loose_Write1_IsErased) {
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{x_2}
}
}
}
} }
} }
)") << module_str; )") << module_str;
@ -811,6 +840,16 @@ TEST_F(SpvModuleScopeVarParserTest,
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
EXPECT_EQ(module_str, R"(Module{ EXPECT_EQ(module_str, R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] x_2_1: __vec_4__f32}
}
Variable{
x_2
private
undefined
__vec_4__f32
}
Variable{ Variable{
x_900 x_900
private private
@ -826,7 +865,7 @@ TEST_F(SpvModuleScopeVarParserTest,
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
() ()
{ {
@ -835,6 +874,14 @@ TEST_F(SpvModuleScopeVarParserTest,
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{x_2}
}
}
}
} }
} }
)") << module_str; )") << module_str;
@ -880,12 +927,22 @@ TEST_F(SpvModuleScopeVarParserTest,
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
EXPECT_EQ(module_str, R"(Module{ EXPECT_EQ(module_str, R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] x_2_1: __vec_4__f32}
}
Variable{
x_2
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
() ()
{ {
@ -894,6 +951,14 @@ TEST_F(SpvModuleScopeVarParserTest,
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{x_2}
}
}
}
} }
} }
)") << module_str; )") << module_str;
@ -917,12 +982,22 @@ TEST_F(SpvModuleScopeVarParserTest,
EXPECT_TRUE(p->error().empty()) << p->error(); EXPECT_TRUE(p->error().empty()) << p->error();
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
EXPECT_EQ(module_str, R"(Module{ EXPECT_EQ(module_str, R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] x_2_1: __vec_4__f32}
}
Variable{
x_2
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
() ()
{ {
@ -931,6 +1006,14 @@ TEST_F(SpvModuleScopeVarParserTest,
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{x_2}
}
}
}
} }
} }
)") << module_str; )") << module_str;
@ -2479,7 +2562,7 @@ TEST_F(SpvModuleScopeVarParserTest, SampleId_I32_Load_CopyObject) {
{ {
UnaryOp[not set]{ UnaryOp[not set]{
indirection indirection
Identifier[not set]{x_11} Identifier[not set]{x_14}
} }
} }
} }
@ -3898,7 +3981,8 @@ std::string VertexIndexPreamble(std::string store_type) {
return R"( return R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %main "main" %1 OpEntryPoint Vertex %main "main" %position %1
OpDecorate %position BuiltIn Position
OpDecorate %1 BuiltIn VertexIndex OpDecorate %1 BuiltIn VertexIndex
%void = OpTypeVoid %void = OpTypeVoid
%voidfn = OpTypeFunction %void %voidfn = OpTypeFunction %void
@ -3908,6 +3992,9 @@ std::string VertexIndexPreamble(std::string store_type) {
%ptr_ty = OpTypePointer Input )" + %ptr_ty = OpTypePointer Input )" +
store_type + R"( store_type + R"(
%1 = OpVariable %ptr_ty Input %1 = OpVariable %ptr_ty Input
%v4float = OpTypeVector %float 4
%posty = OpTypePointer Output %v4float
%position = OpVariable %posty Output
)"; )";
} }
@ -3924,12 +4011,22 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_Direct) {
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] x_4_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__i32 __i32
} }
Variable{
x_4
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
@ -3946,7 +4043,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_Direct) {
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -3971,6 +4068,14 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_Direct) {
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{x_4}
}
}
}
} }
} }
)"; )";
@ -3991,18 +4096,28 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_CopyObject) {
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] x_4_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__i32 __i32
} }
Variable{
x_4
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
VariableDeclStatement{ VariableDeclStatement{
VariableConst{ VariableConst{
x_11 x_14
none none
undefined undefined
__ptr_none__i32 __ptr_none__i32
@ -4023,14 +4138,14 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_CopyObject) {
{ {
UnaryOp[not set]{ UnaryOp[not set]{
indirection indirection
Identifier[not set]{x_11} Identifier[not set]{x_14}
} }
} }
} }
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -4055,6 +4170,14 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_CopyObject) {
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{x_4}
}
}
}
} }
} }
)"; )";
@ -4075,12 +4198,22 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_AccessChain) {
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] x_4_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__i32 __i32
} }
Variable{
x_4
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
@ -4097,7 +4230,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_AccessChain) {
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -4122,6 +4255,14 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_I32_Load_AccessChain) {
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{x_4}
}
}
}
} }
} }
)"; )";
@ -4141,12 +4282,22 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_Direct) {
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] x_4_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__u32 __u32
} }
Variable{
x_4
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
@ -4163,7 +4314,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_Direct) {
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -4186,6 +4337,14 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_Direct) {
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{x_4}
}
}
}
} }
} }
)"; )";
@ -4206,18 +4365,28 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_CopyObject) {
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] x_4_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__u32 __u32
} }
Variable{
x_4
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
VariableDeclStatement{ VariableDeclStatement{
VariableConst{ VariableConst{
x_11 x_14
none none
undefined undefined
__ptr_none__u32 __ptr_none__u32
@ -4238,14 +4407,14 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_CopyObject) {
{ {
UnaryOp[not set]{ UnaryOp[not set]{
indirection indirection
Identifier[not set]{x_11} Identifier[not set]{x_14}
} }
} }
} }
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -4268,6 +4437,14 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_CopyObject) {
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{x_4}
}
}
}
} }
} }
)"; )";
@ -4288,12 +4465,22 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_AccessChain) {
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] x_4_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__u32 __u32
} }
Variable{
x_4
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
@ -4310,7 +4497,7 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_AccessChain) {
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -4333,6 +4520,14 @@ TEST_F(SpvModuleScopeVarParserTest, VertexIndex_U32_Load_AccessChain) {
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{x_4}
}
}
}
} }
} }
)"; )";
@ -4370,7 +4565,9 @@ std::string InstanceIndexPreamble(std::string store_type) {
return R"( return R"(
OpCapability Shader OpCapability Shader
OpMemoryModel Logical Simple OpMemoryModel Logical Simple
OpEntryPoint Vertex %main "main" %1 OpEntryPoint Vertex %main "main" %position %1
OpName %position "position"
OpDecorate %position BuiltIn Position
OpDecorate %1 BuiltIn InstanceIndex OpDecorate %1 BuiltIn InstanceIndex
%void = OpTypeVoid %void = OpTypeVoid
%voidfn = OpTypeFunction %void %voidfn = OpTypeFunction %void
@ -4380,6 +4577,9 @@ std::string InstanceIndexPreamble(std::string store_type) {
%ptr_ty = OpTypePointer Input )" + %ptr_ty = OpTypePointer Input )" +
store_type + R"( store_type + R"(
%1 = OpVariable %ptr_ty Input %1 = OpVariable %ptr_ty Input
%v4float = OpTypeVector %float 4
%posty = OpTypePointer Output %v4float
%position = OpVariable %posty Output
)"; )";
} }
@ -4396,12 +4596,22 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_Direct) {
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] position_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__i32 __i32
} }
Variable{
position
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
@ -4418,7 +4628,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_Direct) {
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -4443,6 +4653,14 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_Direct) {
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{position}
}
}
}
} }
} }
)"; )";
@ -4463,18 +4681,28 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_CopyObject) {
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] position_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__i32 __i32
} }
Variable{
position
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
VariableDeclStatement{ VariableDeclStatement{
VariableConst{ VariableConst{
x_11 x_14
none none
undefined undefined
__ptr_none__i32 __ptr_none__i32
@ -4495,14 +4723,14 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_CopyObject) {
{ {
UnaryOp[not set]{ UnaryOp[not set]{
indirection indirection
Identifier[not set]{x_11} Identifier[not set]{x_14}
} }
} }
} }
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -4527,6 +4755,14 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_CopyObject) {
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{position}
}
}
}
} }
} }
)"; )";
@ -4547,12 +4783,22 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_AccessChain) {
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] position_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__i32 __i32
} }
Variable{
position
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
@ -4569,7 +4815,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_AccessChain) {
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -4594,6 +4840,14 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_I32_Load_AccessChain) {
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{position}
}
}
}
} }
} }
)"; )";
@ -4637,12 +4891,22 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_Direct) {
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] position_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__u32 __u32
} }
Variable{
position
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
@ -4659,7 +4923,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_Direct) {
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -4682,6 +4946,14 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_Direct) {
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{position}
}
}
}
} }
} }
)"; )";
@ -4702,18 +4974,28 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_CopyObject) {
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] position_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__u32 __u32
} }
Variable{
position
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
VariableDeclStatement{ VariableDeclStatement{
VariableConst{ VariableConst{
x_11 x_14
none none
undefined undefined
__ptr_none__u32 __ptr_none__u32
@ -4734,14 +5016,14 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_CopyObject) {
{ {
UnaryOp[not set]{ UnaryOp[not set]{
indirection indirection
Identifier[not set]{x_11} Identifier[not set]{x_14}
} }
} }
} }
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -4764,6 +5046,14 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_CopyObject) {
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{position}
}
}
}
} }
} }
)"; )";
@ -4784,12 +5074,22 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_AccessChain) {
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto module_str = p->program().to_str(); const auto module_str = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] position_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__u32 __u32
} }
Variable{
position
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
@ -4806,7 +5106,7 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_AccessChain) {
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -4829,6 +5129,14 @@ TEST_F(SpvModuleScopeVarParserTest, InstanceIndex_U32_Load_AccessChain) {
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{position}
}
}
}
} }
} }
)"; )";
@ -5523,7 +5831,8 @@ TEST_F(SpvModuleScopeVarParserTest, Builtin_Input_OppositeSignednessAsWGSL) {
TEST_F(SpvModuleScopeVarParserTest, EntryPointWrapping_IOLocations) { TEST_F(SpvModuleScopeVarParserTest, EntryPointWrapping_IOLocations) {
const auto assembly = CommonCapabilities() + R"( const auto assembly = CommonCapabilities() + R"(
OpEntryPoint Vertex %main "main" %1 %2 %3 %4 OpEntryPoint Fragment %main "main" %1 %2 %3 %4
OpExecutionMode %main OriginUpperLeft
OpDecorate %1 Location 0 OpDecorate %1 Location 0
OpDecorate %2 Location 0 OpDecorate %2 Location 0
OpDecorate %3 Location 30 OpDecorate %3 Location 30
@ -5585,7 +5894,7 @@ TEST_F(SpvModuleScopeVarParserTest, EntryPointWrapping_IOLocations) {
Return{} Return{}
} }
Function main -> __type_name_main_out Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{fragment}
( (
VariableConst{ VariableConst{
Decorations{ Decorations{
@ -5640,12 +5949,15 @@ TEST_F(SpvModuleScopeVarParserTest,
// instance_index is u32 in WGSL. Use uint in SPIR-V. // instance_index is u32 in WGSL. Use uint in SPIR-V.
// No bitcasts are used for parameter formation or return value. // No bitcasts are used for parameter formation or return value.
const auto assembly = CommonCapabilities() + R"( const auto assembly = CommonCapabilities() + R"(
OpEntryPoint Vertex %main "main" %1 OpEntryPoint Vertex %main "main" %1 %position
OpDecorate %position BuiltIn Position
OpDecorate %1 BuiltIn InstanceIndex OpDecorate %1 BuiltIn InstanceIndex
)" + CommonTypes() + )" + CommonTypes() +
R"( R"(
%ptr_in_uint = OpTypePointer Input %uint %ptr_in_uint = OpTypePointer Input %uint
%1 = OpVariable %ptr_in_uint Input %1 = OpVariable %ptr_in_uint Input
%posty = OpTypePointer Output %v4float
%position = OpVariable %posty Output
%main = OpFunction %void None %voidfn %main = OpFunction %void None %voidfn
%entry = OpLabel %entry = OpLabel
@ -5660,12 +5972,22 @@ TEST_F(SpvModuleScopeVarParserTest,
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto got = p->program().to_str(); const auto got = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] x_4_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__u32 __u32
} }
Variable{
x_4
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
@ -5682,7 +6004,7 @@ TEST_F(SpvModuleScopeVarParserTest,
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -5705,6 +6027,14 @@ TEST_F(SpvModuleScopeVarParserTest,
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{x_4}
}
}
}
} }
} }
)"; )";
@ -5715,12 +6045,15 @@ TEST_F(SpvModuleScopeVarParserTest,
EntryPointWrapping_BuiltinVar_Input_OppositeSignedness) { EntryPointWrapping_BuiltinVar_Input_OppositeSignedness) {
// instance_index is u32 in WGSL. Use int in SPIR-V. // instance_index is u32 in WGSL. Use int in SPIR-V.
const auto assembly = CommonCapabilities() + R"( const auto assembly = CommonCapabilities() + R"(
OpEntryPoint Vertex %main "main" %1 OpEntryPoint Vertex %main "main" %position %1
OpDecorate %position BuiltIn Position
OpDecorate %1 BuiltIn InstanceIndex OpDecorate %1 BuiltIn InstanceIndex
)" + CommonTypes() + )" + CommonTypes() +
R"( R"(
%ptr_in_int = OpTypePointer Input %int %ptr_in_int = OpTypePointer Input %int
%1 = OpVariable %ptr_in_int Input %1 = OpVariable %ptr_in_int Input
%posty = OpTypePointer Output %v4float
%position = OpVariable %posty Output
%main = OpFunction %void None %voidfn %main = OpFunction %void None %voidfn
%entry = OpLabel %entry = OpLabel
@ -5735,12 +6068,22 @@ TEST_F(SpvModuleScopeVarParserTest,
EXPECT_TRUE(p->error().empty()); EXPECT_TRUE(p->error().empty());
const auto got = p->program().to_str(); const auto got = p->program().to_str();
const std::string expected = R"(Module{ const std::string expected = R"(Module{
Struct main_out {
StructMember{[[ BuiltinDecoration{position}
]] x_4_1: __vec_4__f32}
}
Variable{ Variable{
x_1 x_1
private private
undefined undefined
__i32 __i32
} }
Variable{
x_4
private
undefined
__vec_4__f32
}
Function main_1 -> __void Function main_1 -> __void
() ()
{ {
@ -5757,7 +6100,7 @@ TEST_F(SpvModuleScopeVarParserTest,
} }
Return{} Return{}
} }
Function main -> __void Function main -> __type_name_main_out
StageDecoration{vertex} StageDecoration{vertex}
( (
VariableConst{ VariableConst{
@ -5782,6 +6125,14 @@ TEST_F(SpvModuleScopeVarParserTest,
( (
) )
} }
Return{
{
TypeConstructor[not set]{
__type_name_main_out
Identifier[not set]{x_4}
}
}
}
} }
} }
)"; )";