authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-07 22:02:42+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-16 16:37:07+02:00
logf5041caa2e9d1e891bd93aa2721a4a283123f0d9
treed54ecc828fd0f04431939c31a5019c3820e14f78
parent4c0c9b07555bb69d05142dfe038a7cad79068ba9
signature Commit is signed but in an unrecognized format.

translate-c: more binaryoperator chagnes, blocks and unary type expressions


2 files changed, 156 insertions(+), 197 deletions(-)

src/translate_c.zig+98-175
......@@ -68,16 +68,15 @@ const Scope = struct {
6868 }
6969 };
7070
71 /// Represents an in-progress ast.Node.Block. This struct is stack-allocated.
72 /// When it is deinitialized, it produces an ast.Node.Block which is allocated
71 /// Represents an in-progress Node.Block. This struct is stack-allocated.
72 /// When it is deinitialized, it produces an Node.Block which is allocated
7373 /// into the main arena.
7474 const Block = struct {
7575 base: Scope,
76 statements: std.ArrayList(*ast.Node),
76 statements: std.ArrayList(Node),
7777 variables: AliasList,
78 label: ?ast.TokenIndex,
7978 mangle_count: u32 = 0,
80 lbrace: ast.TokenIndex,
79 label: ?[]const u8 = null,
8180
8281 /// When the block corresponds to a function, keep track of the return type
8382 /// so that the return expression can be cast, if necessary
......@@ -89,14 +88,11 @@ const Scope = struct {
8988 .id = .Block,
9089 .parent = parent,
9190 },
92 .statements = std.ArrayList(*ast.Node).init(c.gpa),
91 .statements = std.ArrayList(Node).init(c.gpa),
9392 .variables = AliasList.init(c.gpa),
94 .label = null,
95 .lbrace = try appendToken(c, .LBrace, "{"),
9693 };
9794 if (labeled) {
98 blk.label = try appendIdentifier(c, try blk.makeMangledName(c, "blk"));
99 _ = try appendToken(c, .Colon, ":");
95 blk.label = try blk.makeMangledName(c, "blk");
10096 }
10197 return blk;
10298 }
......@@ -107,31 +103,16 @@ const Scope = struct {
107103 self.* = undefined;
108104 }
109105
110 fn complete(self: *Block, c: *Context) !*ast.Node {
106 fn complete(self: *Block, c: *Context) !Node {
111107 // We reserve 1 extra statement if the parent is a Loop. This is in case of
112108 // do while, we want to put `if (cond) break;` at the end.
113109 const alloc_len = self.statements.items.len + @boolToInt(self.base.parent.?.id == .Loop);
114 const rbrace = try appendToken(c, .RBrace, "}");
115 if (self.label) |label| {
116 const node = try ast.Node.LabeledBlock.alloc(c.arena, alloc_len);
117 node.* = .{
118 .statements_len = self.statements.items.len,
119 .lbrace = self.lbrace,
120 .rbrace = rbrace,
121 .label = label,
122 };
123 mem.copy(*ast.Node, node.statements(), self.statements.items);
124 return &node.base;
125 } else {
126 const node = try ast.Node.Block.alloc(c.arena, alloc_len);
127 node.* = .{
128 .statements_len = self.statements.items.len,
129 .lbrace = self.lbrace,
130 .rbrace = rbrace,
131 };
132 mem.copy(*ast.Node, node.statements(), self.statements.items);
133 return &node.base;
134 }
110 const stmts = try c.arena.alloc(Node, alloc_len);
111 mem.copy(Node, stmts, self.statements.items);
112 return Node.block.create(c.arena, .{
113 .lable = self.label,
114 .stmts = stmts,
115 });
135116 }
136117
137118 /// Given the desired name, return a name that does not shadow anything from outer scopes.
......@@ -1390,7 +1371,7 @@ fn transBinaryOperator(
13901371 // signed integer division uses @divTrunc
13911372 const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value);
13921373 const rhs = try transExpr(c, scope, stmt.getRHS(), .used, .r_value);
1393 const div_trunc = try Node.div_trunc.create(c.arena, .{ .lhs = lhs, .rhs = rhs});
1374 const div_trunc = try Node.div_trunc.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
13941375 return maybeSuppressResult(c, scope, result_used, div_trunc);
13951376 }
13961377 },
......@@ -1399,7 +1380,7 @@ fn transBinaryOperator(
13991380 // signed integer division uses @rem
14001381 const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value);
14011382 const rhs = try transExpr(c, scope, stmt.getRHS(), .used, .r_value);
1402 const rem = try Node.rem.create(c.arena, .{ .lhs = lhs, .rhs = rhs});
1383 const rem = try Node.rem.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
14031384 return maybeSuppressResult(c, scope, result_used, rem);
14041385 }
14051386 },
......@@ -1411,6 +1392,12 @@ fn transBinaryOperator(
14111392 const node = try transCreateNodeShiftOp(c, scope, stmt, .shr);
14121393 return maybeSuppressResult(c, scope, result_used, node);
14131394 },
1395 .LAnd => {
1396 return transCreateNodeBoolInfixOp(c, scope, stmt, .bool_and, result_used, true);
1397 },
1398 .LOr => {
1399 return transCreateNodeBoolInfixOp(c, scope, stmt, .bool_or, result_used, true);
1400 },
14141401 else => {},
14151402 }
14161403 var op_id: Node.Tag = undefined;
......@@ -1471,17 +1458,19 @@ fn transBinaryOperator(
14711458 .Or => {
14721459 op_id = .bit_or;
14731460 },
1474 .LAnd => {
1475 op_id = .@"and";
1476 },
1477 .LOr => {
1478 op_id = .@"or";
1479 },
14801461 else => unreachable,
14811462 }
14821463
1483 const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value);
1484 const rhs = try transExpr(c, scope, stmt.getRHS(), .used, .r_value);
1464 const lhs_uncasted = try transExpr(c, scope, stmt.getLHS(), .used, .l_value);
1465 const rhs_uncasted = try transExpr(c, scope, stmt.getRHS(), .used, .r_value);
1466
1467 const lhs = if (isBoolRes(lhs_uncasted))
1468 try Node.bool_to_int.create(c.arena, lhs_uncasted)
1469 else lhs_uncasted;
1470
1471 const rhs = if (isBoolRes(rhs_uncasted))
1472 try Node.bool_to_int.create(c.arena, rhs_uncasted)
1473 else rhs_uncasted;
14851474
14861475 const payload = try c.arena.create(ast.Payload.BinOp);
14871476 payload.* = .{
......@@ -1495,7 +1484,7 @@ fn transBinaryOperator(
14951484}
14961485
14971486fn transCompoundStmtInline(
1498 rp: RestorePoint,
1487 c: *Context,
14991488 parent_scope: *Scope,
15001489 stmt: *const clang.CompoundStmt,
15011490 block: *Scope.Block,
......@@ -1503,16 +1492,16 @@ fn transCompoundStmtInline(
15031492 var it = stmt.body_begin();
15041493 const end_it = stmt.body_end();
15051494 while (it != end_it) : (it += 1) {
1506 const result = try transStmt(rp, parent_scope, it[0], .unused, .r_value);
1495 const result = try transStmt(c, parent_scope, it[0], .unused, .r_value);
15071496 try block.statements.append(result);
15081497 }
15091498}
15101499
1511fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const clang.CompoundStmt) TransError!*ast.Node {
1512 var block_scope = try Scope.Block.init(rp.c, scope, false);
1500fn transCompoundStmt(c: *Context, scope: *Scope, stmt: *const clang.CompoundStmt) TransError!Node {
1501 var block_scope = try Scope.Block.init(c, scope, false);
15131502 defer block_scope.deinit();
1514 try transCompoundStmtInline(rp, &block_scope.base, stmt, &block_scope);
1515 return try block_scope.complete(rp.c);
1503 try transCompoundStmtInline(c, &block_scope.base, stmt, &block_scope);
1504 return try block_scope.complete(c);
15161505}
15171506
15181507fn transCStyleCastExprClass(
......@@ -3233,22 +3222,18 @@ fn qualTypeGetFnProto(qt: clang.QualType, is_ptr: *bool) ?ClangFunctionType {
32333222}
32343223
32353224fn transUnaryExprOrTypeTraitExpr(
3236 rp: RestorePoint,
3225 c: *Context,
32373226 scope: *Scope,
32383227 stmt: *const clang.UnaryExprOrTypeTraitExpr,
32393228 result_used: ResultUsed,
3240) TransError!*ast.Node {
3229) TransError!Node {
32413230 const loc = stmt.getBeginLoc();
3242 const type_node = try transQualType(
3243 rp,
3244 stmt.getTypeOfArgument(),
3245 loc,
3246 );
3231 const type_node = try transQualType(rp, stmt.getTypeOfArgument(), loc);
32473232
32483233 const kind = stmt.getKind();
3249 const kind_str = switch (kind) {
3250 .SizeOf => "@sizeOf",
3251 .AlignOf => "@alignOf",
3234 switch (kind) {
3235 .SizeOf => return Node.sizeof.create(c.arena, type_node),
3236 .AlignOf => return Node.alignof.create(c.arena, type_node),
32523237 .PreferredAlignOf,
32533238 .VecStep,
32543239 .OpenMPRequiredSimdAlign,
......@@ -3259,12 +3244,7 @@ fn transUnaryExprOrTypeTraitExpr(
32593244 "Unsupported type trait kind {}",
32603245 .{kind},
32613246 ),
3262 };
3263
3264 const builtin_node = try rp.c.createBuiltinCall(kind_str, 1);
3265 builtin_node.params()[0] = type_node;
3266 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
3267 return maybeSuppressResult(rp, scope, result_used, &builtin_node.base);
3247 }
32683248}
32693249
32703250fn qualTypeHasWrappingOverflow(qt: clang.QualType) bool {
......@@ -3967,8 +3947,8 @@ fn transQualTypeInitialized(
39673947 return transQualType(rp, qt, source_loc);
39683948}
39693949
3970fn transQualType(rp: RestorePoint, qt: clang.QualType, source_loc: clang.SourceLocation) TypeError!*ast.Node {
3971 return transType(rp, qt.getTypePtr(), source_loc);
3950fn transQualType(c: *Context, qt: clang.QualType, source_loc: clang.SourceLocation) TypeError!Node {
3951 return transType(c, qt.getTypePtr(), source_loc);
39723952}
39733953
39743954/// Produces a Zig AST node by translating a Clang QualType, respecting the width, but modifying the signed-ness.
......@@ -4318,19 +4298,27 @@ fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []c
43184298 return &field_access_node.base;
43194299}
43204300
4321fn transCreateNodeSimplePrefixOp(
4301fn transCreateNodeBoolInfixOp(
43224302 c: *Context,
4323 comptime tag: ast.Node.Tag,
4324 op_tok_id: std.zig.Token.Id,
4325 bytes: []const u8,
4326) !*ast.Node.SimplePrefixOp {
4327 const node = try c.arena.create(ast.Node.SimplePrefixOp);
4328 node.* = .{
4329 .base = .{ .tag = tag },
4330 .op_token = try appendToken(c, op_tok_id, bytes),
4331 .rhs = undefined, // translate and set afterward
4303 scope: *Scope,
4304 stmt: *const clang.BinaryOperator,
4305 op: ast.Node.Tag,
4306 used: ResultUsed,
4307) !Node {
4308 std.debug.assert(op == .bool_and or op == .bool_or);
4309
4310 const lhs = try transBoolExpr(rp, scope, stmt.getLHS(), .used, .l_value, true);
4311 const rhs = try transBoolExpr(rp, scope, stmt.getRHS(), .used, .r_value, true);
4312
4313 const payload = try c.arena.create(ast.Payload.BinOp);
4314 payload.* = .{
4315 .base = .{ .tag = op },
4316 .data = .{
4317 .lhs = lhs,
4318 .rhs = rhs,
4319 },
43324320 };
4333 return node;
4321 return maybeSuppressResult(c, scope, used, &payload.base);
43344322}
43354323
43364324fn transCreateNodePtrType(
......@@ -4784,30 +4772,30 @@ fn transCreateNodeArrayAccess(c: *Context, lhs: *ast.Node) !*ast.Node.ArrayAcces
47844772 return node;
47854773}
47864774
4787fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocation) TypeError!Type {
4775fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocation) TypeError!Node {
47884776 switch (ty.getTypeClass()) {
47894777 .Builtin => {
47904778 const builtin_ty = @ptrCast(*const clang.BuiltinType, ty);
4791 return Type.initTag(switch (builtin_ty.getKind()) {
4792 .Void => .c_void,
4793 .Bool => .bool,
4794 .Char_U, .UChar, .Char_S, .Char8 => .u8,
4795 .SChar => .i8,
4796 .UShort => .c_ushort,
4797 .UInt => .c_uint,
4798 .ULong => .c_ulong,
4799 .ULongLong => .c_ulonglong,
4800 .Short => .c_short,
4801 .Int => .c_int,
4802 .Long => .c_long,
4803 .LongLong => .c_longlong,
4804 .UInt128 => .u128,
4805 .Int128 => .i128,
4806 .Float => .f32,
4807 .Double => .f64,
4808 .Float128 => .f128,
4809 .Float16 => .f16,
4810 .LongDouble => .c_longdouble,
4779 return Node.type.create(c.arena, switch (builtin_ty.getKind()) {
4780 .Void => "c_void",
4781 .Bool => "bool",
4782 .Char_U, .UChar, .Char_S, .Char8 => "u8",
4783 .SChar => "i8",
4784 .UShort => "c_ushort",
4785 .UInt => "c_uint",
4786 .ULong => "c_ulong",
4787 .ULongLong => "c_ulonglong",
4788 .Short => "c_short",
4789 .Int => "c_int",
4790 .Long => "c_long",
4791 .LongLong => "c_longlong",
4792 .UInt128 => "u128",
4793 .Int128 => "i128",
4794 .Float => "f32",
4795 .Double => "f64",
4796 .Float128 => "f128",
4797 .Float16 => "f16",
4798 .LongDouble => "c_longdouble",
48114799 else => return fail(c, error.UnsupportedType, source_loc, "unsupported builtin type", .{}),
48124800 });
48134801 },
......@@ -4826,61 +4814,25 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio
48264814 .Pointer => {
48274815 const child_qt = ty.getPointeeType();
48284816 if (qualTypeChildIsFnProto(child_qt)) {
4829 return Type.optional_single_mut_pointer.create(c.arena, try transQualType(c, child_qt, source_loc));
4817 return Node.optional_type.create(c.arena, try transQualType(c, child_qt, source_loc));
48304818 }
48314819 const is_const = child_qt.isConstQualified();
48324820 const is_volatile = child_qt.isVolatileQualified();
48334821 const elem_type = try transQualType(c, child_qt, source_loc);
4834 if (elem_type.zigTypeTag() == .Opaque) {
4835 if (!is_volatile) {
4836 if (is_const) {
4837 return Type.optional_single_const_pointer.create(c.arena, elem_type);
4838 } else {
4839 return Type.optional_single_mut_pointer.create(c.arena, elem_type);
4840 }
4841 }
4842
4843 return Type.pointer.create(c.arena, .{
4844 .pointee_type = elem_type,
4845 .sentinel = null,
4846 .@"align" = 0,
4847 .bit_offset = 0,
4848 .host_size = 0,
4849 .@"allowzero" = false,
4850 .mutable = !is_const,
4851 .@"volatile" = true,
4852 .size = .Single,
4853 });
4822 if (typeIsOpaque(rp.c, child_qt.getTypePtr(), source_loc) or qualTypeWasDemotedToOpaque(rp.c, child_qt)) {
4823 return Node.single_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
48544824 }
48554825
4856 if (!is_volatile) {
4857 if (is_const) {
4858 return Type.c_const_pointer.create(c.arena, elem_type);
4859 } else {
4860 return Type.c_mut_pointer.create(c.arena, elem_type);
4861 }
4862 }
4863
4864 return Type.pointer.create(c.arena, .{
4865 .pointee_type = elem_type,
4866 .sentinel = null,
4867 .@"align" = 0,
4868 .bit_offset = 0,
4869 .host_size = 0,
4870 .@"allowzero" = false,
4871 .mutable = !is_const,
4872 .@"volatile" = true,
4873 .size = .C,
4874 });
4826 return Node.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
48754827 },
48764828 .ConstantArray => {
48774829 const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, ty);
48784830
48794831 const size_ap_int = const_arr_ty.getSize();
48804832 const size = size_ap_int.getLimitedValue(math.maxInt(usize));
4881 const elem_type = try transType1(c, const_arr_ty.getElementType().getTypePtr(), source_loc);
4882
4883 return Type.array.create(c.arena, .{ .len = size, .elem_type = elem_type });
4833 const elem_type = try transType(c, const_arr_ty.getElementType().getTypePtr(), source_loc);
4834
4835 return Node.array_type.create(c.arena, .{ .len = size, .elem_type = elem_type });
48844836 },
48854837 .IncompleteArray => {
48864838 const incomplete_array_ty = @ptrCast(*const clang.IncompleteArrayType, ty);
......@@ -4890,25 +4842,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio
48904842 const is_volatile = child_qt.isVolatileQualified();
48914843 const elem_type = try transQualType(c, child_qt, source_loc);
48924844
4893 if (!is_volatile) {
4894 if (is_const) {
4895 return Type.c_const_pointer.create(c.arena, elem_type);
4896 } else {
4897 return Type.c_mut_pointer.create(c.arena, elem_type);
4898 }
4899 }
4900
4901 return Type.pointer.create(c.arena, .{
4902 .pointee_type = elem_type,
4903 .sentinel = null,
4904 .@"align" = 0,
4905 .bit_offset = 0,
4906 .host_size = 0,
4907 .@"allowzero" = false,
4908 .mutable = !is_const,
4909 .@"volatile" = true,
4910 .size = .C,
4911 });
4845 return Node.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
49124846 },
49134847 .Typedef => {
49144848 const typedef_ty = @ptrCast(*const clang.TypedefType, ty);
......@@ -5233,25 +5167,14 @@ fn finishTransFnProto(
52335167 return fn_proto;
52345168}
52355169
5236fn revertAndWarn(
5237 rp: RestorePoint,
5238 err: anytype,
5239 source_loc: clang.SourceLocation,
5240 comptime format: []const u8,
5241 args: anytype,
5242) (@TypeOf(err) || error{OutOfMemory}) {
5243 rp.activate();
5244 try emitWarning(rp.c, source_loc, format, args);
5245 return err;
5246}
5247
5248fn emitWarning(c: *Context, loc: clang.SourceLocation, comptime format: []const u8, args: anytype) !void {
5170fn warn(c: *Context, scope: *Scope, loc: clang.SourceLocation, comptime format: []const u8, args: anytype) !void {
52495171 const args_prefix = .{c.locStr(loc)};
5250 _ = try appendTokenFmt(c, .LineComment, "// {s}: warning: " ++ format, args_prefix ++ args);
5172 const value = std.fmt.allocPrint(c.arena, "// {s}: warning: " ++ format, args_prefix ++ args);
5173 try scope.appendNode(c.gpa, try Node.warning.create(c.arena, value));
52515174}
52525175
52535176fn fail(
5254 rp: RestorePoint,
5177 c: *Context,
52555178 err: anytype,
52565179 source_loc: clang.SourceLocation,
52575180 comptime format: []const u8,
src/translate_c/ast.zig+58-22
......@@ -107,6 +107,25 @@ pub const Node = extern union {
107107 rem,
108108 /// @divTrunc(lhs, rhs)
109109 div_trunc,
110 /// @boolToInt(lhs, rhs)
111 bool_to_int,
112
113 negate,
114 negate_wrap,
115 bit_not,
116 not,
117
118 block,
119 @"break",
120
121 sizeof,
122 alignof,
123 type,
124
125 optional_type,
126 c_pointer,
127 single_pointer,
128 array_type,
110129
111130 pub const last_no_payload_tag = Tag.false_literal;
112131 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
......@@ -127,6 +146,14 @@ pub const Node = extern union {
127146 .@"return",
128147 .discard,
129148 .std_math_Log2Int,
149 .negate,
150 .negate_wrap,
151 .bit_not,
152 .not,
153 .optional_type,
154 .c_pointer,
155 .single_pointer,
156 .array_type,
130157 => Payload.UnOp,
131158
132159 .add,
......@@ -180,6 +207,7 @@ pub const Node = extern union {
180207 .div_trunc,
181208 .rem,
182209 .int_cast,
210 .bool_to_int,
183211 => Payload.BinOp,
184212
185213 .int,
......@@ -191,6 +219,9 @@ pub const Node = extern union {
191219 .field_access_arrow,
192220 .warning,
193221 .failed_decl,
222 .sizeof,
223 .alignof,
224 .type,
194225 => Payload.Value,
195226 .@"if" => Payload.If,
196227 .@"while" => Payload.While,
......@@ -234,8 +265,8 @@ pub const Payload = struct {
234265 pub const Infix = struct {
235266 base: Node,
236267 data: struct {
237 lhs: *Node,
238 rhs: *Node,
268 lhs: Node,
269 rhs: Node,
239270 },
240271 };
241272
......@@ -246,44 +277,44 @@ pub const Payload = struct {
246277
247278 pub const UnOp = struct {
248279 base: Node,
249 data: *Node,
280 data: Node,
250281 };
251282
252283 pub const BinOp = struct {
253284 base: Node,
254285 data: struct {
255 lhs: *Node,
256 rhs: *Node,
286 lhs: Node,
287 rhs: Node,
257288 },
258289 };
259290
260291 pub const If = struct {
261292 base: Node = .{ .tag = .@"if" },
262293 data: struct {
263 cond: *Node,
264 then: *Node,
265 @"else": ?*Node,
294 cond: Node,
295 then: Node,
296 @"else": ?Node,
266297 },
267298 };
268299
269300 pub const While = struct {
270301 base: Node = .{ .tag = .@"while" },
271302 data: struct {
272 cond: *Node,
273 body: *Node,
303 cond: Node,
304 body: Node,
274305 },
275306 };
276307
277308 pub const Switch = struct {
278309 base: Node = .{ .tag = .@"switch" },
279310 data: struct {
280 cond: *Node,
311 cond: Node,
281312 cases: []Prong,
282313 default: ?[]const u8,
283314
284315 pub const Prong = struct {
285 lhs: *Node,
286 rhs: ?*Node,
316 lhs: Node,
317 rhs: ?Node,
287318 label: []const u8,
288319 };
289320 },
......@@ -293,15 +324,15 @@ pub const Payload = struct {
293324 base: Node = .{ .tag = .@"break" },
294325 data: struct {
295326 label: ?[]const u8,
296 rhs: ?*Node,
327 rhs: ?Node,
297328 },
298329 };
299330
300331 pub const Call = struct {
301332 base: Node = .{.call},
302333 data: struct {
303 lhs: *Node,
304 args: []*Node,
334 lhs: Node,
335 args: []Node,
305336 },
306337 };
307338
......@@ -314,7 +345,7 @@ pub const Payload = struct {
314345 @"export": bool,
315346 name: []const u8,
316347 type: Type,
317 init: *Node,
348 init: Node,
318349 },
319350 };
320351
......@@ -328,7 +359,7 @@ pub const Payload = struct {
328359 cc: std.builtin.CallingConvention,
329360 params: []Param,
330361 return_type: Type,
331 body: ?*Node,
362 body: ?Node,
332363
333364 pub const Param = struct {
334365 @"noalias": bool,
......@@ -368,7 +399,7 @@ pub const Payload = struct {
368399
369400 pub const ArrayInit = struct {
370401 base: Node = .{ .tag = .array_init },
371 data: []*Node,
402 data: []Node,
372403 };
373404
374405 pub const ContainerInit = struct {
......@@ -377,17 +408,22 @@ pub const Payload = struct {
377408
378409 pub const Initializer = struct {
379410 name: []const u8,
380 value: *Node,
411 value: Node,
381412 };
382413 };
383414
384415 pub const Block = struct {
385 base: Node = .{ .tag = .block },
416 base: Node,
386417 data: struct {
387418 label: ?[]const u8,
388 stmts: []*Node,
419 stmts: []Node
389420 },
390421 };
422
423 pub const Break = struct {
424 base: Node = .{ .tag = .@"break" },
425 data: *Block
426 };
391427};
392428
393429/// Converts the nodes into a Zig ast and then renders it.