authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-12 11:23:15+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-16 16:40:06+02:00
log2a74a1ebaace8b5de1796b1756f65e421eb479a4
tree94967e6c0d2016ccb370c29845e04a4150a1cd76
parent66bbd75a8346b8a292f0d95d4b60a5d7d11b73b2
signature Commit is signed but in an unrecognized format.

translate-c: bunch of small fixes to get it compiling


3 files changed, 647 insertions(+), 655 deletions(-)

src/translate_c.zig+582-608
......@@ -10,12 +10,13 @@ const mem = std.mem;
1010const math = std.math;
1111const ast = @import("translate_c/ast.zig");
1212const Node = ast.Node;
13const Tag = Node.Tag;
1314
1415const CallingConvention = std.builtin.CallingConvention;
1516
1617pub const ClangErrMsg = clang.Stage2ErrorMsg;
1718
18pub const Error = error{OutOfMemory};
19pub const Error = std.mem.Allocator.Error;
1920const TypeError = Error || error{UnsupportedType};
2021const TransError = TypeError || error{UnsupportedTranslation};
2122
......@@ -30,11 +31,11 @@ const Scope = struct {
3031 parent: ?*Scope,
3132
3233 const Id = enum {
33 Switch,
34 Block,
35 Root,
36 Condition,
37 Loop,
34 @"switch",
35 block,
36 root,
37 condition,
38 loop,
3839 };
3940
4041 /// Represents an in-progress Node.Switch. This struct is stack-allocated.
......@@ -44,7 +45,6 @@ const Scope = struct {
4445 base: Scope,
4546 pending_block: Block,
4647 cases: std.ArrayList(Node),
47 case_index: usize,
4848 switch_label: ?[]const u8,
4949 default_label: ?[]const u8,
5050 };
......@@ -84,7 +84,7 @@ const Scope = struct {
8484 fn init(c: *Context, parent: *Scope, labeled: bool) !Block {
8585 var blk = Block{
8686 .base = .{
87 .id = .Block,
87 .id = .block,
8888 .parent = parent,
8989 },
9090 .statements = std.ArrayList(Node).init(c.gpa),
......@@ -105,12 +105,12 @@ const Scope = struct {
105105 fn complete(self: *Block, c: *Context) !Node {
106106 // We reserve 1 extra statement if the parent is a Loop. This is in case of
107107 // do while, we want to put `if (cond) break;` at the end.
108 const alloc_len = self.statements.items.len + @boolToInt(self.base.parent.?.id == .Loop);
109 const stmts = try c.arena.alloc(Node, alloc_len);
108 const alloc_len = self.statements.items.len + @boolToInt(self.base.parent.?.id == .loop);
109 var stmts = try c.arena.alloc(Node, alloc_len);
110110 stmts.len -= 1;
111111 mem.copy(Node, stmts, self.statements.items);
112 return Node.block.create(c.arena, .{
113 .lable = self.label,
112 return Tag.block.create(c.arena, .{
113 .label = self.label,
114114 .stmts = stmts,
115115 });
116116 }
......@@ -161,7 +161,7 @@ const Scope = struct {
161161 fn init(c: *Context) Root {
162162 return .{
163163 .base = .{
164 .id = .Root,
164 .id = .root,
165165 .parent = null,
166166 },
167167 .sym_table = SymbolTable.init(c.gpa),
......@@ -195,9 +195,9 @@ const Scope = struct {
195195 var scope = inner;
196196 while (true) {
197197 switch (scope.id) {
198 .Root => unreachable,
199 .Block => return @fieldParentPtr(Block, "base", scope),
200 .Condition => return @fieldParentPtr(Condition, "base", scope).getBlockScope(c),
198 .root => unreachable,
199 .block => return @fieldParentPtr(Block, "base", scope),
200 .condition => return @fieldParentPtr(Condition, "base", scope).getBlockScope(c),
201201 else => scope = scope.parent.?,
202202 }
203203 }
......@@ -207,8 +207,8 @@ const Scope = struct {
207207 var scope = inner;
208208 while (true) {
209209 switch (scope.id) {
210 .Root => unreachable,
211 .Block => {
210 .root => unreachable,
211 .block => {
212212 const block = @fieldParentPtr(Block, "base", scope);
213213 if (block.return_type) |qt| return qt;
214214 scope = scope.parent.?;
......@@ -220,17 +220,17 @@ const Scope = struct {
220220
221221 fn getAlias(scope: *Scope, name: []const u8) []const u8 {
222222 return switch (scope.id) {
223 .Root => return name,
224 .Block => @fieldParentPtr(Block, "base", scope).getAlias(name),
225 .Switch, .Loop, .Condition => scope.parent.?.getAlias(name),
223 .root => return name,
224 .block => @fieldParentPtr(Block, "base", scope).getAlias(name),
225 .@"switch", .loop, .condition => scope.parent.?.getAlias(name),
226226 };
227227 }
228228
229229 fn contains(scope: *Scope, name: []const u8) bool {
230230 return switch (scope.id) {
231 .Root => @fieldParentPtr(Root, "base", scope).contains(name),
232 .Block => @fieldParentPtr(Block, "base", scope).contains(name),
233 .Switch, .Loop, .Condition => scope.parent.?.contains(name),
231 .root => @fieldParentPtr(Root, "base", scope).contains(name),
232 .block => @fieldParentPtr(Block, "base", scope).contains(name),
233 .@"switch", .loop, .condition => scope.parent.?.contains(name),
234234 };
235235 }
236236
......@@ -238,9 +238,9 @@ const Scope = struct {
238238 var scope = inner;
239239 while (true) {
240240 switch (scope.id) {
241 .Root => unreachable,
242 .Switch => return scope,
243 .Loop => return scope,
241 .root => unreachable,
242 .@"switch" => return scope,
243 .loop => return scope,
244244 else => scope = scope.parent.?,
245245 }
246246 }
......@@ -250,24 +250,24 @@ const Scope = struct {
250250 var scope = inner;
251251 while (true) {
252252 switch (scope.id) {
253 .Root => unreachable,
254 .Switch => return @fieldParentPtr(Switch, "base", scope),
253 .root => unreachable,
254 .@"switch" => return @fieldParentPtr(Switch, "base", scope),
255255 else => scope = scope.parent.?,
256256 }
257257 }
258258 }
259259
260260 /// Appends a node to the first block scope if inside a function, or to the root tree if not.
261 fn appendNode(scope: *Scope, node: Node) !void {
261 fn appendNode(inner: *Scope, node: Node) !void {
262262 var scope = inner;
263263 while (true) {
264264 switch (scope.id) {
265 .Root => {
266 const root = @fieldParentPtr(Root, "base", scope).contains(name);
265 .root => {
266 const root = @fieldParentPtr(Root, "base", scope);
267267 return root.nodes.append(node);
268268 },
269 .Block => {
270 const block = @fieldParentPtr(Block, "base", scope).contains(name);
269 .block => {
270 const block = @fieldParentPtr(Block, "base", scope);
271271 return block.statements.append(node);
272272 },
273273 else => scope = scope.parent.?,
......@@ -321,7 +321,7 @@ pub fn translate(
321321 args_end: [*]?[*]const u8,
322322 errors: *[]ClangErrMsg,
323323 resources_path: [*:0]const u8,
324) !ast.Tree {
324) !std.zig.ast.Tree {
325325 const ast_unit = clang.LoadFromCommandLine(
326326 args_begin,
327327 args_end,
......@@ -339,14 +339,6 @@ pub fn translate(
339339 var arena = std.heap.ArenaAllocator.init(gpa);
340340 errdefer arena.deinit();
341341
342 if (true) {
343 var x = false;
344 if (x) {
345 return error.OutOfMemory;
346 }
347 @panic("TODO update translate-c");
348 }
349
350342 var context = Context{
351343 .gpa = gpa,
352344 .arena = &arena.allocator,
......@@ -361,15 +353,15 @@ pub fn translate(
361353 context.alias_list.deinit();
362354 context.global_names.deinit(gpa);
363355 context.opaque_demotes.deinit(gpa);
364 context.global_scope.deini();
356 context.global_scope.deinit();
365357 }
366358
367 try context.global_scope.nodes.append(try Node.usingnamespace_builtins.init());
359 try context.global_scope.nodes.append(Tag.usingnamespace_builtins.init());
368360
369361 try prepopulateGlobalNameTable(ast_unit, &context);
370362
371363 if (!ast_unit.visitLocalTopLevelDecls(&context, declVisitorC)) {
372 return context.err;
364 return error.OutOfMemory;
373365 }
374366
375367 try transPreprocessorEntities(&context, ast_unit);
......@@ -377,16 +369,17 @@ pub fn translate(
377369 try addMacros(&context);
378370 for (context.alias_list.items) |alias| {
379371 if (!context.global_scope.sym_table.contains(alias.alias)) {
380 try createAlias(&context, alias);
372 const node = try Tag.alias.create(context.arena, .{ .actual = alias.alias, .mangled = alias.name });
373 try addTopLevelDecl(&context, alias.alias, node);
381374 }
382375 }
383376
384 return ast.render(context.global_scope.nodes.items);
377 return ast.render(gpa, context.global_scope.nodes.items);
385378}
386379
387380fn prepopulateGlobalNameTable(ast_unit: *clang.ASTUnit, c: *Context) !void {
388381 if (!ast_unit.visitLocalTopLevelDecls(c, declVisitorNamesOnlyC)) {
389 return c.err;
382 return error.OutOfMemory;
390383 }
391384
392385 // TODO if we see #undef, delete it from the table
......@@ -409,19 +402,13 @@ fn prepopulateGlobalNameTable(ast_unit: *clang.ASTUnit, c: *Context) !void {
409402
410403fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const clang.Decl) callconv(.C) bool {
411404 const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context));
412 declVisitorNamesOnly(c, decl) catch |err| {
413 c.err = err;
414 return false;
415 };
405 declVisitorNamesOnly(c, decl) catch return false;
416406 return true;
417407}
418408
419409fn declVisitorC(context: ?*c_void, decl: *const clang.Decl) callconv(.C) bool {
420410 const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context));
421 declVisitor(c, decl) catch |err| {
422 c.err = err;
423 return false;
424 };
411 declVisitor(c, decl) catch return false;
425412 return true;
426413}
427414
......@@ -454,7 +441,7 @@ fn declVisitor(c: *Context, decl: *const clang.Decl) Error!void {
454441 },
455442 else => {
456443 const decl_name = try c.str(decl.getDeclKindName());
457 try warn(c, decl.getLocation(), "ignoring {s} declaration", .{decl_name});
444 try warn(c, &c.global_scope.base, decl.getLocation(), "ignoring {s} declaration", .{decl_name});
458445 },
459446 }
460447}
......@@ -513,7 +500,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void {
513500 decl_ctx.has_body = false;
514501 decl_ctx.storage_class = .Extern;
515502 decl_ctx.is_export = false;
516 try warn(c, fn_decl_loc, "TODO unable to translate variadic function, demoted to declaration", .{});
503 try warn(c, &c.global_scope.base, fn_decl_loc, "TODO unable to translate variadic function, demoted to declaration", .{});
517504 }
518505 break :blk transFnProto(c, fn_decl, fn_proto_type, fn_decl_loc, decl_ctx, true) catch |err| switch (err) {
519506 error.UnsupportedType => {
......@@ -535,7 +522,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void {
535522 };
536523
537524 if (!decl_ctx.has_body) {
538 return addTopLevelDecl(c, fn_name, &proto_node.base);
525 return addTopLevelDecl(c, fn_name, Node.initPayload(&proto_node.base));
539526 }
540527
541528 // actual function definition with body
......@@ -547,10 +534,8 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void {
547534 var scope = &block_scope.base;
548535
549536 var param_id: c_uint = 0;
550 for (proto_node.params()) |*param, i| {
551 const param_name = if (param.name_token) |name_tok|
552 tokenSlice(c, name_tok)
553 else
537 for (proto_node.data.params) |*param, i| {
538 const param_name = param.name orelse
554539 return failDecl(c, fn_decl_loc, fn_name, "function {s} parameter has no name", .{fn_name});
555540
556541 const c_param = fn_decl.getParamDecl(param_id);
......@@ -565,7 +550,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void {
565550 const arg_name = try block_scope.makeMangledName(c, bare_arg_name);
566551 param.name = arg_name;
567552
568 const redecl_node = try Node.arg_redecl.create(c.arena, .{ .actual = mangled_param_name, .mangled = arg_name });
553 const redecl_node = try Tag.arg_redecl.create(c.arena, .{ .actual = mangled_param_name, .mangled = arg_name });
569554 try block_scope.statements.append(redecl_node);
570555 }
571556
......@@ -607,12 +592,12 @@ fn visitFnDecl(c: *Context, fn_decl: *const clang.FunctionDecl) Error!void {
607592 error.UnsupportedType,
608593 => return failDecl(c, fn_decl_loc, fn_name, "unable to create a return value for function", .{}),
609594 };
610 const ret = try Node.@"return".create(c.arena, rhs);
595 const ret = try Tag.@"return".create(c.arena, rhs);
611596 try block_scope.statements.append(ret);
612597 }
613598
614 proto_node.body = try block_scope.complete(c);
615 return addTopLevelDecl(c, fn_name, &proto_node.base);
599 proto_node.data.body = try block_scope.complete(c);
600 return addTopLevelDecl(c, fn_name, Node.initPayload(&proto_node.base));
616601}
617602
618603fn transQualTypeMaybeInitialized(c: *Context, qt: clang.QualType, decl_init: ?*const clang.Expr, loc: clang.SourceLocation) TransError!Node {
......@@ -668,7 +653,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
668653 const node_or_error = if (expr.getStmtClass() == .StringLiteralClass)
669654 transStringLiteralAsArray(c, scope, @ptrCast(*const clang.StringLiteral, expr), zigArraySize(c, type_node) catch 0)
670655 else
671 transExprCoercing(c, scope, expr, .used, .r_value);
656 transExprCoercing(c, scope, expr, .used);
672657 init_node = node_or_error catch |err| switch (err) {
673658 error.UnsupportedTranslation,
674659 error.UnsupportedType,
......@@ -677,18 +662,18 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
677662 },
678663 error.OutOfMemory => |e| return e,
679664 };
680 if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) {
681 init_node = try Node.bool_to_int.create(c.arena, init_node);
665 if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node.?)) {
666 init_node = try Tag.bool_to_int.create(c.arena, init_node.?);
682667 }
683668 } else {
684 init_node = Node.undefined_literal.init();
669 init_node = Tag.undefined_literal.init();
685670 }
686671 } else if (storage_class != .Extern) {
687672 // The C language specification states that variables with static or threadlocal
688673 // storage without an initializer are initialized to a zero value.
689674
690675 // @import("std").mem.zeroes(T)
691 init_node = try Node.std_mem_zeroes.create(c.arena, type_node);
676 init_node = try Tag.std_mem_zeroes.create(c.arena, type_node);
692677 }
693678
694679 const linksection_string = blk: {
......@@ -708,7 +693,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
708693 break :blk null;
709694 };
710695
711 const node = try Node.var_decl.create(c.arena, .{
696 const node = try Tag.var_decl.create(c.arena, .{
712697 .is_pub = is_pub,
713698 .is_const = is_const,
714699 .is_extern = is_extern,
......@@ -719,12 +704,12 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
719704 .type = type_node,
720705 .init = init_node,
721706 });
722 return addTopLevelDecl(c, checked_name, &node.base);
707 return addTopLevelDecl(c, checked_name, node);
723708}
724709
725710fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const clang.TypedefNameDecl, builtin_name: []const u8) !Node {
726711 _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), builtin_name);
727 return Node.identifier.create(c.arena, builtin_name);
712 return Tag.identifier.create(c.arena, builtin_name);
728713}
729714
730715const builtin_typedef_map = std.ComptimeStringMap([]const u8, .{
......@@ -744,7 +729,7 @@ const builtin_typedef_map = std.ComptimeStringMap([]const u8, .{
744729
745730fn transTypeDef(c: *Context, typedef_decl: *const clang.TypedefNameDecl, top_level_visit: bool) Error!?Node {
746731 if (c.decl_table.get(@ptrToInt(typedef_decl.getCanonicalDecl()))) |name|
747 return transCreateNodeIdentifier(c, name); // Avoid processing this decl twice
732 return try Tag.identifier.create(c.arena, name); // Avoid processing this decl twice
748733
749734 const typedef_name = try c.str(@ptrCast(*const clang.NamedDecl, typedef_decl).getName_bytes_begin());
750735
......@@ -753,17 +738,17 @@ fn transTypeDef(c: *Context, typedef_decl: *const clang.TypedefNameDecl, top_lev
753738 const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.arena, "{s}_{d}", .{ typedef_name, c.getMangle() }) else typedef_name;
754739 if (builtin_typedef_map.get(checked_name)) |builtin| {
755740 _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), builtin);
756 return Node.identifier.create(c.arena, builtin);
741 return try Tag.identifier.create(c.arena, builtin);
757742 }
758743
759744 if (!top_level_visit) {
760 return transCreateNodeIdentifier(c, checked_name);
745 return try Tag.identifier.create(c.arena, checked_name);
761746 }
762747
763748 _ = try c.decl_table.put(c.gpa, @ptrToInt(typedef_decl.getCanonicalDecl()), checked_name);
764749 const node = (try transCreateNodeTypedef(c, typedef_decl, true, checked_name)) orelse return null;
765750 try addTopLevelDecl(c, checked_name, node);
766 return transCreateNodeIdentifier(c, checked_name);
751 return try Tag.identifier.create(c.arena, checked_name);
767752}
768753
769754fn transCreateNodeTypedef(
......@@ -782,9 +767,9 @@ fn transCreateNodeTypedef(
782767 error.OutOfMemory => |e| return e,
783768 };
784769
785 const payload = try c.arena.create(ast.Payload.Typedef);
770 const payload = try c.arena.create(ast.Payload.SimpleVarDecl);
786771 payload.* = .{
787 .base = .{ .tag = ([2]ast.Node.Tag{ .typedef, .pub_typedef })[@boolToInt(toplevel)] },
772 .base = .{ .tag = ([2]Tag{ .typedef, .pub_typedef })[@boolToInt(toplevel)] },
788773 .data = .{
789774 .name = checked_name,
790775 .init = init_node,
......@@ -795,7 +780,7 @@ fn transCreateNodeTypedef(
795780
796781fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Node {
797782 if (c.decl_table.get(@ptrToInt(record_decl.getCanonicalDecl()))) |name|
798 return try transCreateNodeIdentifier(c, name); // Avoid processing this decl twice
783 return try Tag.identifier.create(c.arena, name); // Avoid processing this decl twice
799784 const record_loc = record_decl.getLocation();
800785
801786 var bare_name = try c.str(@ptrCast(*const clang.NamedDecl, record_decl).getName_bytes_begin());
......@@ -815,7 +800,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod
815800 } else if (record_decl.isStruct()) {
816801 container_kind_name = "struct";
817802 } else {
818 try warn(c, record_loc, "record {s} is not a struct or union", .{bare_name});
803 try warn(c, &c.global_scope.base, record_loc, "record {s} is not a struct or union", .{bare_name});
819804 return null;
820805 }
821806
......@@ -826,7 +811,7 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod
826811 const init_node = blk: {
827812 const record_def = record_decl.getDefinition() orelse {
828813 _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
829 break :blk Node.opaque_literal.init();
814 break :blk Tag.opaque_literal.init();
830815 };
831816
832817 const is_packed = record_decl.getPackedAttribute();
......@@ -843,14 +828,14 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod
843828
844829 if (field_decl.isBitField()) {
845830 _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
846 try warn(c, field_loc, "{s} demoted to opaque type - has bitfield", .{container_kind_name});
847 break :blk Node.opaque_literal.init();
831 try warn(c, &c.global_scope.base, field_loc, "{s} demoted to opaque type - has bitfield", .{container_kind_name});
832 break :blk Tag.opaque_literal.init();
848833 }
849834
850835 if (qualTypeCanon(field_qt).isIncompleteOrZeroLengthArrayType(c.clang_context)) {
851836 _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
852 try warn(c, field_loc, "{s} demoted to opaque type - has variable length array", .{container_kind_name});
853 break :blk Node.opaque_literal.init();
837 try warn(c, &c.global_scope.base, field_loc, "{s} demoted to opaque type - has variable length array", .{container_kind_name});
838 break :blk Tag.opaque_literal.init();
854839 }
855840
856841 var is_anon = false;
......@@ -864,8 +849,8 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod
864849 const field_type = transQualType(c, field_qt, field_loc) catch |err| switch (err) {
865850 error.UnsupportedType => {
866851 _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
867 try warn(c, record_loc, "{s} demoted to opaque type - unable to translate type of field {s}", .{ container_kind_name, raw_name });
868 break :blk Node.opaque_literal.init();
852 try warn(c, &c.global_scope.base, record_loc, "{s} demoted to opaque type - unable to translate type of field {s}", .{ container_kind_name, field_name });
853 break :blk Tag.opaque_literal.init();
869854 },
870855 else => |e| return e,
871856 };
......@@ -890,20 +875,20 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod
890875 });
891876 }
892877
893 const payload = try c.arena.create(ast.Payload.Record);
894 container_node.* = .{
895 .base = .{ .tag = ([2]ast.Node.Tag{ .@"struct", .@"union" })[@boolToInt(is_union)] },
878 const record_payload = try c.arena.create(ast.Payload.Record);
879 record_payload.* = .{
880 .base = .{ .tag = ([2]Tag{ .@"struct", .@"union" })[@boolToInt(is_union)] },
896881 .data = .{
897882 .is_packed = is_packed,
898883 .fields = try c.arena.dupe(ast.Payload.Record.Field, fields.items),
899884 },
900885 };
901 break :blk Node.initPayload(&container_node.base);
886 break :blk Node.initPayload(&record_payload.base);
902887 };
903888
904889 const payload = try c.arena.create(ast.Payload.SimpleVarDecl);
905890 payload.* = .{
906 .base = .{ .tag = ([2]ast.Node.Tag{ .var_simple, .pub_var_simple })[@boolToInt(is_pub)] },
891 .base = .{ .tag = ([2]Tag{ .var_simple, .pub_var_simple })[@boolToInt(is_pub)] },
907892 .data = .{
908893 .name = name,
909894 .init = init_node,
......@@ -913,12 +898,12 @@ fn transRecordDecl(c: *Context, record_decl: *const clang.RecordDecl) Error!?Nod
913898 try addTopLevelDecl(c, name, Node.initPayload(&payload.base));
914899 if (!is_unnamed)
915900 try c.alias_list.append(.{ .alias = bare_name, .name = name });
916 return Node.identifier.create(c.arena, name);
901 return try Tag.identifier.create(c.arena, name);
917902}
918903
919904fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node {
920905 if (c.decl_table.get(@ptrToInt(enum_decl.getCanonicalDecl()))) |name|
921 return try transCreateNodeIdentifier(c, name); // Avoid processing this decl twice
906 return try Tag.identifier.create(c.arena, name); // Avoid processing this decl twice
922907 const enum_loc = enum_decl.getLocation();
923908
924909 var bare_name = try c.str(@ptrCast(*const clang.NamedDecl, enum_decl).getName_bytes_begin());
......@@ -965,7 +950,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node {
965950 else => |e| return e,
966951 }
967952 else
968 try Node.type.create(c.arena, "c_int");
953 try Tag.type.create(c.arena, "c_int");
969954
970955 it = enum_def.enumerator_begin();
971956 end_it = enum_def.enumerator_end();
......@@ -983,29 +968,29 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node {
983968 else
984969 null;
985970
986 try fields_and_decls.append(.{
971 try fields.append(.{
987972 .name = field_name,
988973 .value = int_node,
989974 });
990975
991976 // In C each enum value is in the global namespace. So we put them there too.
992977 // At this point we can rely on the enum emitting successfully.
993 try addTopLevelDecl(c, field_name, try Node.enum_redecl.create(c.arena, .{
978 try addTopLevelDecl(c, field_name, try Tag.enum_redecl.create(c.arena, .{
994979 .enum_val_name = enum_val_name,
995980 .field_name = field_name,
996981 .enum_name = name,
997982 }));
998983 }
999984
1000 break :blk try Node.@"enum".create(c.arena, try c.arena.dupe(ast.Payload.Enum.Field, fields.items));
985 break :blk try Tag.@"enum".create(c.arena, try c.arena.dupe(ast.Payload.Enum.Field, fields.items));
1001986 } else blk: {
1002987 _ = try c.opaque_demotes.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), {});
1003 break :blk Node.opaque_literal.init();
988 break :blk Tag.opaque_literal.init();
1004989 };
1005990
1006991 const payload = try c.arena.create(ast.Payload.SimpleVarDecl);
1007992 payload.* = .{
1008 .base = .{ .tag = ([2]ast.Node.Tag{ .var_simple, .pub_var_simple })[@boolToInt(is_pub)] },
993 .base = .{ .tag = ([2]Tag{ .var_simple, .pub_var_simple })[@boolToInt(is_pub)] },
1009994 .data = .{
1010995 .name = name,
1011996 .init = init_node,
......@@ -1015,7 +1000,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const clang.EnumDecl) Error!?Node {
10151000 try addTopLevelDecl(c, name, Node.initPayload(&payload.base));
10161001 if (!is_unnamed)
10171002 try c.alias_list.append(.{ .alias = bare_name, .name = name });
1018 return transCreateNodeIdentifier(c, name);
1003 return try Tag.identifier.create(c.arena, name);
10191004}
10201005
10211006const ResultUsed = enum {
......@@ -1023,31 +1008,25 @@ const ResultUsed = enum {
10231008 unused,
10241009};
10251010
1026const LRValue = enum {
1027 l_value,
1028 r_value,
1029};
1030
10311011fn transStmt(
10321012 c: *Context,
10331013 scope: *Scope,
10341014 stmt: *const clang.Stmt,
10351015 result_used: ResultUsed,
1036 lrvalue: LRValue,
10371016) TransError!Node {
10381017 const sc = stmt.getStmtClass();
10391018 switch (sc) {
10401019 .BinaryOperatorClass => return transBinaryOperator(c, scope, @ptrCast(*const clang.BinaryOperator, stmt), result_used),
10411020 .CompoundStmtClass => return transCompoundStmt(c, scope, @ptrCast(*const clang.CompoundStmt, stmt)),
1042 .CStyleCastExprClass => return transCStyleCastExprClass(c, scope, @ptrCast(*const clang.CStyleCastExpr, stmt), result_used, lrvalue),
1021 .CStyleCastExprClass => return transCStyleCastExprClass(c, scope, @ptrCast(*const clang.CStyleCastExpr, stmt), result_used),
10431022 .DeclStmtClass => return transDeclStmt(c, scope, @ptrCast(*const clang.DeclStmt, stmt)),
1044 .DeclRefExprClass => return transDeclRefExpr(c, scope, @ptrCast(*const clang.DeclRefExpr, stmt), lrvalue),
1023 .DeclRefExprClass => return transDeclRefExpr(c, scope, @ptrCast(*const clang.DeclRefExpr, stmt)),
10451024 .ImplicitCastExprClass => return transImplicitCastExpr(c, scope, @ptrCast(*const clang.ImplicitCastExpr, stmt), result_used),
10461025 .IntegerLiteralClass => return transIntegerLiteral(c, scope, @ptrCast(*const clang.IntegerLiteral, stmt), result_used, .with_as),
10471026 .ReturnStmtClass => return transReturnStmt(c, scope, @ptrCast(*const clang.ReturnStmt, stmt)),
10481027 .StringLiteralClass => return transStringLiteral(c, scope, @ptrCast(*const clang.StringLiteral, stmt), result_used),
10491028 .ParenExprClass => {
1050 const expr = try transExpr(c, scope, @ptrCast(*const clang.ParenExpr, stmt).getSubExpr(), .used, lrvalue);
1029 const expr = try transExpr(c, scope, @ptrCast(*const clang.ParenExpr, stmt).getSubExpr(), .used);
10511030 return maybeSuppressResult(c, scope, result_used, expr);
10521031 },
10531032 .InitListExprClass => return transInitListExpr(c, scope, @ptrCast(*const clang.InitListExpr, stmt), result_used),
......@@ -1056,9 +1035,9 @@ fn transStmt(
10561035 .WhileStmtClass => return transWhileLoop(c, scope, @ptrCast(*const clang.WhileStmt, stmt)),
10571036 .DoStmtClass => return transDoWhileLoop(c, scope, @ptrCast(*const clang.DoStmt, stmt)),
10581037 .NullStmtClass => {
1059 return Node.empty_block.init();
1038 return Tag.empty_block.init();
10601039 },
1061 .ContinueStmtClass => return try transCreateNodeContinue(c),
1040 .ContinueStmtClass => return Tag.@"continue".init(),
10621041 .BreakStmtClass => return transBreak(c, scope),
10631042 .ForStmtClass => return transForLoop(c, scope, @ptrCast(*const clang.ForStmt, stmt)),
10641043 .FloatingLiteralClass => return transFloatingLiteral(c, scope, @ptrCast(*const clang.FloatingLiteral, stmt), result_used),
......@@ -1083,12 +1062,12 @@ fn transStmt(
10831062 .CompoundAssignOperatorClass => return transCompoundAssignOperator(c, scope, @ptrCast(*const clang.CompoundAssignOperator, stmt), result_used),
10841063 .OpaqueValueExprClass => {
10851064 const source_expr = @ptrCast(*const clang.OpaqueValueExpr, stmt).getSourceExpr().?;
1086 const expr = try transExpr(c, scope, source_expr, .used, lrvalue);
1065 const expr = try transExpr(c, scope, source_expr, .used);
10871066 return maybeSuppressResult(c, scope, result_used, expr);
10881067 },
10891068 else => {
10901069 return fail(
1091 rp,
1070 c,
10921071 error.UnsupportedTranslation,
10931072 stmt.getBeginLoc(),
10941073 "TODO implement translation of stmt class {s}",
......@@ -1109,37 +1088,36 @@ fn transBinaryOperator(
11091088 switch (op) {
11101089 .Assign => return try transCreateNodeAssign(c, scope, result_used, stmt.getLHS(), stmt.getRHS()),
11111090 .Comma => {
1112 var block_scope = try Scope.Block.init(rp.c, scope, true);
1091 var block_scope = try Scope.Block.init(c, scope, true);
11131092 defer block_scope.deinit();
11141093
1115
1116 const lhs = try transExpr(c, &block_scope.base, stmt.getLHS(), .unused, .r_value);
1094 const lhs = try transExpr(c, &block_scope.base, stmt.getLHS(), .unused);
11171095 try block_scope.statements.append(lhs);
11181096
1119 const rhs = try transExpr(rp, &block_scope.base, stmt.getRHS(), .used, .r_value);
1120 const break_node = try Node.break_val.create(c.arena, .{
1097 const rhs = try transExpr(c, &block_scope.base, stmt.getRHS(), .used);
1098 const break_node = try Tag.break_val.create(c.arena, .{
11211099 .label = block_scope.label,
11221100 .val = rhs,
11231101 });
11241102 try block_scope.statements.append(break_node);
1125 const block_node = try block_scope.complete(rp.c);
1126 return maybeSuppressResult(rp, scope, result_used, block_node);
1103 const block_node = try block_scope.complete(c);
1104 return maybeSuppressResult(c, scope, result_used, block_node);
11271105 },
11281106 .Div => {
11291107 if (cIsSignedInteger(qt)) {
11301108 // signed integer division uses @divTrunc
1131 const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value);
1132 const rhs = try transExpr(c, scope, stmt.getRHS(), .used, .r_value);
1133 const div_trunc = try Node.div_trunc.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
1109 const lhs = try transExpr(c, scope, stmt.getLHS(), .used);
1110 const rhs = try transExpr(c, scope, stmt.getRHS(), .used);
1111 const div_trunc = try Tag.div_trunc.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
11341112 return maybeSuppressResult(c, scope, result_used, div_trunc);
11351113 }
11361114 },
11371115 .Rem => {
11381116 if (cIsSignedInteger(qt)) {
11391117 // signed integer division uses @rem
1140 const lhs = try transExpr(c, scope, stmt.getLHS(), .used, .l_value);
1141 const rhs = try transExpr(c, scope, stmt.getRHS(), .used, .r_value);
1142 const rem = try Node.rem.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
1118 const lhs = try transExpr(c, scope, stmt.getLHS(), .used);
1119 const rhs = try transExpr(c, scope, stmt.getRHS(), .used);
1120 const rem = try Tag.rem.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
11431121 return maybeSuppressResult(c, scope, result_used, rem);
11441122 }
11451123 },
......@@ -1150,14 +1128,14 @@ fn transBinaryOperator(
11501128 return transCreateNodeShiftOp(c, scope, stmt, .shr, result_used);
11511129 },
11521130 .LAnd => {
1153 return transCreateNodeBoolInfixOp(c, scope, stmt, .bool_and, result_used);
1131 return transCreateNodeBoolInfixOp(c, scope, stmt, .@"and", result_used);
11541132 },
11551133 .LOr => {
1156 return transCreateNodeBoolInfixOp(c, scope, stmt, .bool_or, result_used);
1134 return transCreateNodeBoolInfixOp(c, scope, stmt, .@"or", result_used);
11571135 },
11581136 else => {},
11591137 }
1160 var op_id: Node.Tag = undefined;
1138 var op_id: Tag = undefined;
11611139 switch (op) {
11621140 .Add => {
11631141 if (cIsUnsignedInteger(qt)) {
......@@ -1218,20 +1196,20 @@ fn transBinaryOperator(
12181196 else => unreachable,
12191197 }
12201198
1221 const lhs_uncasted = try transExpr(c, scope, stmt.getLHS(), .used, .l_value);
1222 const rhs_uncasted = try transExpr(c, scope, stmt.getRHS(), .used, .r_value);
1199 const lhs_uncasted = try transExpr(c, scope, stmt.getLHS(), .used);
1200 const rhs_uncasted = try transExpr(c, scope, stmt.getRHS(), .used);
12231201
12241202 const lhs = if (isBoolRes(lhs_uncasted))
1225 try Node.bool_to_int.create(c.arena, lhs_uncasted)
1203 try Tag.bool_to_int.create(c.arena, lhs_uncasted)
12261204 else
12271205 lhs_uncasted;
12281206
12291207 const rhs = if (isBoolRes(rhs_uncasted))
1230 try Node.bool_to_int.create(c.arena, rhs_uncasted)
1208 try Tag.bool_to_int.create(c.arena, rhs_uncasted)
12311209 else
12321210 rhs_uncasted;
12331211
1234 return transCreateNodeInfixOp(c, scope, op_id, lhs, rhs, used);
1212 return transCreateNodeInfixOp(c, scope, op_id, lhs, rhs, result_used);
12351213}
12361214
12371215fn transCompoundStmtInline(
......@@ -1243,7 +1221,7 @@ fn transCompoundStmtInline(
12431221 var it = stmt.body_begin();
12441222 const end_it = stmt.body_end();
12451223 while (it != end_it) : (it += 1) {
1246 const result = try transStmt(c, parent_scope, it[0], .unused, .r_value);
1224 const result = try transStmt(c, parent_scope, it[0], .unused);
12471225 try block.statements.append(result);
12481226 }
12491227}
......@@ -1260,7 +1238,6 @@ fn transCStyleCastExprClass(
12601238 scope: *Scope,
12611239 stmt: *const clang.CStyleCastExpr,
12621240 result_used: ResultUsed,
1263 lrvalue: LRValue,
12641241) TransError!Node {
12651242 const sub_expr = stmt.getSubExpr();
12661243 const cast_node = (try transCCast(
......@@ -1269,7 +1246,7 @@ fn transCStyleCastExprClass(
12691246 stmt.getBeginLoc(),
12701247 stmt.getType(),
12711248 sub_expr.getType(),
1272 try transExpr(c, scope, sub_expr, .used, lrvalue),
1249 try transExpr(c, scope, sub_expr, .used),
12731250 ));
12741251 return maybeSuppressResult(c, scope, result_used, cast_node);
12751252}
......@@ -1294,7 +1271,7 @@ fn transDeclStmtOne(
12941271 // This is actually a global variable, put it in the global scope and reference it.
12951272 // `_ = mangled_name;`
12961273 try visitVarDecl(c, var_decl, mangled_name);
1297 return try maybeSuppressResult(c, scope, .unused, try Node.identifier.create(c.arena, mangled_name));
1274 return try maybeSuppressResult(c, scope, .unused, try Tag.identifier.create(c.arena, mangled_name));
12981275 },
12991276 else => {},
13001277 }
......@@ -1308,13 +1285,13 @@ fn transDeclStmtOne(
13081285 if (expr.getStmtClass() == .StringLiteralClass)
13091286 try transStringLiteralAsArray(c, scope, @ptrCast(*const clang.StringLiteral, expr), try zigArraySize(c, type_node))
13101287 else
1311 try transExprCoercing(c, scope, expr, .used, .r_value)
1288 try transExprCoercing(c, scope, expr, .used)
13121289 else
1313 try transCreateNodeUndefinedLiteral(c);
1290 Tag.undefined_literal.init();
13141291 if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) {
1315 init_node = try Node.bool_to_int.create(c.arena, init_node);
1292 init_node = try Tag.bool_to_int.create(c.arena, init_node);
13161293 }
1317 return Node.var_decl.create(c.arena, .{
1294 return Tag.var_decl.create(c.arena, .{
13181295 .is_pub = false,
13191296 .is_const = is_const,
13201297 .is_extern = false,
......@@ -1339,7 +1316,7 @@ fn transDeclStmtOne(
13391316 return node;
13401317 },
13411318 else => |kind| return fail(
1342 rp,
1319 c,
13431320 error.UnsupportedTranslation,
13441321 decl.getLocation(),
13451322 "TODO implement translation of DeclStmt kind {s}",
......@@ -1370,12 +1347,11 @@ fn transDeclRefExpr(
13701347 c: *Context,
13711348 scope: *Scope,
13721349 expr: *const clang.DeclRefExpr,
1373 lrvalue: LRValue,
13741350) TransError!Node {
13751351 const value_decl = expr.getDecl();
13761352 const name = try c.str(@ptrCast(*const clang.NamedDecl, value_decl).getName_bytes_begin());
13771353 const mangled_name = scope.getAlias(name);
1378 return Node.identifier.create(c.arena, mangled_name);
1354 return Tag.identifier.create(c.arena, mangled_name);
13791355}
13801356
13811357fn transImplicitCastExpr(
......@@ -1389,49 +1365,49 @@ fn transImplicitCastExpr(
13891365 const src_type = getExprQualType(c, sub_expr);
13901366 switch (expr.getCastKind()) {
13911367 .BitCast, .FloatingCast, .FloatingToIntegral, .IntegralToFloating, .IntegralCast, .PointerToIntegral, .IntegralToPointer => {
1392 const sub_expr_node = try transExpr(c, scope, sub_expr, .used, .r_value);
1368 const sub_expr_node = try transExpr(c, scope, sub_expr, .used);
13931369 const casted = try transCCast(c, scope, expr.getBeginLoc(), dest_type, src_type, sub_expr_node);
13941370 return maybeSuppressResult(c, scope, result_used, casted);
13951371 },
13961372 .LValueToRValue, .NoOp, .FunctionToPointerDecay => {
1397 const sub_expr_node = try transExpr(c, scope, sub_expr, .used, .r_value);
1373 const sub_expr_node = try transExpr(c, scope, sub_expr, .used);
13981374 return maybeSuppressResult(c, scope, result_used, sub_expr_node);
13991375 },
14001376 .ArrayToPointerDecay => {
14011377 if (exprIsNarrowStringLiteral(sub_expr)) {
1402 const sub_expr_node = try transExpr(c, scope, sub_expr, .used, .r_value);
1378 const sub_expr_node = try transExpr(c, scope, sub_expr, .used);
14031379 return maybeSuppressResult(c, scope, result_used, sub_expr_node);
14041380 }
14051381
1406 const addr = try Node.address_of.create(c.arena, try transExpr(c, scope, sub_expr, .used, .r_value));
1382 const addr = try Tag.address_of.create(c.arena, try transExpr(c, scope, sub_expr, .used));
14071383 return maybeSuppressResult(c, scope, result_used, addr);
14081384 },
14091385 .NullToPointer => {
1410 return Node.null_literal.init();
1386 return Tag.null_literal.init();
14111387 },
14121388 .PointerToBoolean => {
14131389 // @ptrToInt(val) != 0
1414 const ptr_to_int = try Node.ptr_to_int.create(c.arena, try transExpr(c, scope, sub_expr, .used, .r_value));
1390 const ptr_to_int = try Tag.ptr_to_int.create(c.arena, try transExpr(c, scope, sub_expr, .used));
14151391
1416 const ne = try Node.not_equal.create(c.arena, .{ .lhs = ptr_to_int, .rhs = Node.zero_literal.init() });
1392 const ne = try Tag.not_equal.create(c.arena, .{ .lhs = ptr_to_int, .rhs = Tag.zero_literal.init() });
14171393 return maybeSuppressResult(c, scope, result_used, ne);
14181394 },
14191395 .IntegralToBoolean => {
1420 const sub_expr_node = try transExpr(c, scope, sub_expr, .used, .r_value);
1396 const sub_expr_node = try transExpr(c, scope, sub_expr, .used);
14211397
14221398 // The expression is already a boolean one, return it as-is
14231399 if (isBoolRes(sub_expr_node))
14241400 return maybeSuppressResult(c, scope, result_used, sub_expr_node);
14251401
14261402 // val != 0
1427 const ne = try Node.not_equal.create(c.arena, .{ .lhs = sub_expr_node, .rhs = Node.zero_literal.init() });
1403 const ne = try Tag.not_equal.create(c.arena, .{ .lhs = sub_expr_node, .rhs = Tag.zero_literal.init() });
14281404 return maybeSuppressResult(c, scope, result_used, ne);
14291405 },
14301406 .BuiltinFnToFnPtr => {
1431 return transExpr(rp, scope, sub_expr, result_used, .r_value);
1407 return transExpr(c, scope, sub_expr, result_used);
14321408 },
14331409 else => |kind| return fail(
1434 rp,
1410 c,
14351411 error.UnsupportedTranslation,
14361412 @ptrCast(*const clang.Stmt, expr).getBeginLoc(),
14371413 "TODO implement translation of CastKind {s}",
......@@ -1445,17 +1421,16 @@ fn transBoolExpr(
14451421 scope: *Scope,
14461422 expr: *const clang.Expr,
14471423 used: ResultUsed,
1448 lrvalue: LRValue,
14491424) TransError!Node {
14501425 if (@ptrCast(*const clang.Stmt, expr).getStmtClass() == .IntegerLiteralClass) {
14511426 var is_zero: bool = undefined;
14521427 if (!(@ptrCast(*const clang.IntegerLiteral, expr).isZero(&is_zero, c.clang_context))) {
14531428 return fail(c, error.UnsupportedTranslation, expr.getBeginLoc(), "invalid integer literal", .{});
14541429 }
1455 return Node{ .tag = ([2]ast.Node.Tag{ .true_literal, .false_literal })[@boolToInt(is_zero)] };
1430 return Node{ .tag_if_small_enough = @enumToInt(([2]Tag{ .true_literal, .false_literal })[@boolToInt(is_zero)]) };
14561431 }
14571432
1458 var res = try transExpr(c, scope, expr, used, lrvalue);
1433 var res = try transExpr(c, scope, expr, used);
14591434 if (isBoolRes(res)) {
14601435 return maybeSuppressResult(c, scope, used, res);
14611436 }
......@@ -1494,7 +1469,7 @@ fn isBoolRes(res: Node) bool {
14941469 .@"or",
14951470 .@"and",
14961471 .equal,
1497 .note_equal,
1472 .not_equal,
14981473 .less_than,
14991474 .less_than_equal,
15001475 .greater_than,
......@@ -1547,18 +1522,18 @@ fn finishBoolExpr(
15471522 .Float16,
15481523 => {
15491524 // node != 0
1550 return Node.not_equal.create(c.arena, .{ .lhs = node, .rhs = Node.zero_literal.init() });
1525 return Tag.not_equal.create(c.arena, .{ .lhs = node, .rhs = Tag.zero_literal.init() });
15511526 },
15521527 .NullPtr => {
15531528 // node == null
1554 return Node.equal.create(c.arena, .{ .lhs = node, .rhs = Node.null_literal.init() });
1529 return Tag.equal.create(c.arena, .{ .lhs = node, .rhs = Tag.null_literal.init() });
15551530 },
15561531 else => {},
15571532 }
15581533 },
15591534 .Pointer => {
15601535 // node == null
1561 return Node.equal.create(c.arena, .{ .lhs = node, .rhs = Node.null_literal.init() });
1536 return Tag.equal.create(c.arena, .{ .lhs = node, .rhs = Tag.null_literal.init() });
15621537 },
15631538 .Typedef => {
15641539 const typedef_ty = @ptrCast(*const clang.TypedefType, ty);
......@@ -1568,8 +1543,7 @@ fn finishBoolExpr(
15681543 },
15691544 .Enum => {
15701545 // node != 0
1571 return Node.not_equal.create(c.arena, .{ .lhs = node, .rhs = Node.zero_literal.init() });
1572 const op_token = try appendToken(c, .BangEqual, "!=");
1546 return Tag.not_equal.create(c.arena, .{ .lhs = node, .rhs = Tag.zero_literal.init() });
15731547 },
15741548 .Elaborated => {
15751549 const elaborated_ty = @ptrCast(*const clang.ElaboratedType, ty);
......@@ -1614,9 +1588,10 @@ fn transIntegerLiteral(
16141588 // But the first step is to be correct, and the next step is to make the output more elegant.
16151589
16161590 // @as(T, x)
1591 const expr_base = @ptrCast(*const clang.Expr, expr);
16171592 const ty_node = try transQualType(c, expr_base.getType(), expr_base.getBeginLoc());
16181593 const rhs = try transCreateNodeAPInt(c, eval_result.Val.getInt());
1619 const as = try Node.as.create(c.arena, .{ .lhs = ty_node, .rhs = rhs });
1594 const as = try Tag.as.create(c.arena, .{ .lhs = ty_node, .rhs = rhs });
16201595 return maybeSuppressResult(c, scope, result_used, as);
16211596}
16221597
......@@ -1624,16 +1599,16 @@ fn transReturnStmt(
16241599 c: *Context,
16251600 scope: *Scope,
16261601 expr: *const clang.ReturnStmt,
1627) TransError!*ast.Node {
1602) TransError!Node {
16281603 const val_expr = expr.getRetValue() orelse
1629 return Node.return_void.init();
1604 return Tag.return_void.init();
16301605
1631 var rhs = try transExprCoercing(c, scope, val_expr, .used, .r_value);
1606 var rhs = try transExprCoercing(c, scope, val_expr, .used);
16321607 const return_qt = scope.findBlockReturnType(c);
16331608 if (isBoolRes(rhs) and !qualTypeIsBoolean(return_qt)) {
1634 rhs = try Node.bool_to_int.create(c.arena, rhs);
1609 rhs = try Tag.bool_to_int.create(c.arena, rhs);
16351610 }
1636 return Node.@"return".create(c.arena, rhs);
1611 return Tag.@"return".create(c.arena, rhs);
16371612}
16381613
16391614fn transStringLiteral(
......@@ -1647,10 +1622,9 @@ fn transStringLiteral(
16471622 .Ascii, .UTF8 => {
16481623 var len: usize = undefined;
16491624 const bytes_ptr = stmt.getString_bytes_begin_size(&len);
1650 const str = bytes_ptr[0..len];
16511625
1652 const str = try std.fmt.allocPrint(c.arena, "\"{}\"", .{std.zig.fmtEscapes(str)});
1653 const node = try Node.string_literal.create(c.arena, str);
1626 const str = try std.fmt.allocPrint(c.arena, "\"{}\"", .{std.zig.fmtEscapes(bytes_ptr[0..len])});
1627 const node = try Tag.string_literal.create(c.arena, str);
16541628 return maybeSuppressResult(c, scope, result_used, node);
16551629 },
16561630 .UTF16, .UTF32, .Wide => {
......@@ -1658,9 +1632,9 @@ fn transStringLiteral(
16581632 const name = try std.fmt.allocPrint(c.arena, "zig.{s}_string_{d}", .{ str_type, c.getMangle() });
16591633 const lit_array = try transStringLiteralAsArray(c, scope, stmt, stmt.getLength() + 1);
16601634
1661 const decl = try Node.var_simple.create(c.arena, .{ .name = name, .init = lit_array });
1662 try scope.appendNode(name, decl);
1663 const node = try Node.identifier.create(c.arena, name);
1635 const decl = try Tag.var_simple.create(c.arena, .{ .name = name, .init = lit_array });
1636 try scope.appendNode(decl);
1637 const node = try Tag.identifier.create(c.arena, name);
16641638 return maybeSuppressResult(c, scope, result_used, node);
16651639 },
16661640 }
......@@ -1669,9 +1643,7 @@ fn transStringLiteral(
16691643/// Parse the size of an array back out from an ast Node.
16701644fn zigArraySize(c: *Context, node: Node) TransError!usize {
16711645 if (node.castTag(.array_type)) |array| {
1672 if (array.data.len.castTag(.int_literal)) |int_lit| {
1673 return std.fmt.parseUnsigned(usize, int_lit.data, 10) catch error.UnsupportedTranslation;
1674 }
1646 return array.data.len;
16751647 }
16761648 return error.UnsupportedTranslation;
16771649}
......@@ -1709,7 +1681,7 @@ fn transStringLiteralAsArray(
17091681 init_list[i] = try transCreateNodeNumber(c, 0);
17101682 }
17111683
1712 return Node.array_init.create(c.arena, init_list);
1684 return Tag.array_init.create(c.arena, init_list);
17131685}
17141686
17151687fn cIsEnum(qt: clang.QualType) bool {
......@@ -1747,89 +1719,77 @@ fn transCCast(
17471719 // 3. Bit-cast to correct signed-ness
17481720 const src_type_is_signed = cIsSignedInteger(src_type) or cIsEnum(src_type);
17491721 const src_int_type = if (cIsInteger(src_type)) src_type else cIntTypeForEnum(src_type);
1750 var src_int_expr = if (cIsInteger(src_type)) expr else Node.enum_to_int.create(c.arena, expr);
1722 var src_int_expr = if (cIsInteger(src_type)) expr else try Tag.enum_to_int.create(c.arena, expr);
17511723
17521724 if (isBoolRes(src_int_expr)) {
1753 src_int_expr = try Node.bool_to_int.create(c.arena, src_int_expr);
1725 src_int_expr = try Tag.bool_to_int.create(c.arena, src_int_expr);
17541726 }
17551727
17561728 switch (cIntTypeCmp(dst_type, src_int_type)) {
17571729 .lt => {
17581730 // @truncate(SameSignSmallerInt, src_int_expr)
17591731 const ty_node = try transQualTypeIntWidthOf(c, dst_type, src_type_is_signed);
1760 src_int_expr = try Node.truncate.create(c.arena, .{ .lhs = ty_node, .rhs = src_int_expr });
1732 src_int_expr = try Tag.truncate.create(c.arena, .{ .lhs = ty_node, .rhs = src_int_expr });
17611733 },
17621734 .gt => {
17631735 // @as(SameSignBiggerInt, src_int_expr)
17641736 const ty_node = try transQualTypeIntWidthOf(c, dst_type, src_type_is_signed);
1765 src_int_expr = try Node.as.create(c.arena, .{ .lhs = ty_node, .rhs = src_int_expr });
1737 src_int_expr = try Tag.as.create(c.arena, .{ .lhs = ty_node, .rhs = src_int_expr });
17661738 },
17671739 .eq => {
17681740 // src_int_expr = src_int_expr
17691741 },
17701742 }
17711743 // @bitCast(dest_type, intermediate_value)
1772 return Node.bit_cast.create(c.arena, .{ .lhs = dst_node, .rhs = src_int_expr });
1744 return Tag.bit_cast.create(c.arena, .{ .lhs = dst_node, .rhs = src_int_expr });
17731745 }
17741746 if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) {
17751747 // @intCast(dest_type, @ptrToInt(val))
1776 const ptr_to_int = try Node.ptr_to_int.create(c.arena, expr);
1777 return Node.int_cast.create(c.arena, .{ .lhs = dst_node, .rhs = ptr_to_int });
1748 const ptr_to_int = try Tag.ptr_to_int.create(c.arena, expr);
1749 return Tag.int_cast.create(c.arena, .{ .lhs = dst_node, .rhs = ptr_to_int });
17781750 }
17791751 if (cIsInteger(src_type) and qualTypeIsPtr(dst_type)) {
17801752 // @intToPtr(dest_type, val)
1781 return Node.int_to_ptr.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
1753 return Tag.int_to_ptr.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
17821754 }
17831755 if (cIsFloating(src_type) and cIsFloating(dst_type)) {
17841756 // @floatCast(dest_type, val)
1785 return Node.float_cast.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
1757 return Tag.float_cast.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
17861758 }
17871759 if (cIsFloating(src_type) and !cIsFloating(dst_type)) {
17881760 // @floatToInt(dest_type, val)
1789 return Node.float_to_int.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
1761 return Tag.float_to_int.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
17901762 }
17911763 if (!cIsFloating(src_type) and cIsFloating(dst_type)) {
17921764 // @intToFloat(dest_type, val)
1793 return Node.int_to_float.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
1765 return Tag.int_to_float.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
17941766 }
17951767 if (qualTypeIsBoolean(src_type) and !qualTypeIsBoolean(dst_type)) {
17961768 // @boolToInt returns either a comptime_int or a u1
17971769 // TODO: if dst_type is 1 bit & signed (bitfield) we need @bitCast
17981770 // instead of @as
1799 const bool_to_int = Node.bool_to_int.create(c.arena, expr);
1800 return Node.as.create(c.arena, .{ .lhs = dst_node, .rhs = bool_to_int });
1771 const bool_to_int = try Tag.bool_to_int.create(c.arena, expr);
1772 return Tag.as.create(c.arena, .{ .lhs = dst_node, .rhs = bool_to_int });
18011773 }
18021774 if (cIsEnum(dst_type)) {
18031775 // @intToEnum(dest_type, val)
1804 return Node.int_to_enum.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
1776 return Tag.int_to_enum.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
18051777 }
18061778 if (cIsEnum(src_type) and !cIsEnum(dst_type)) {
18071779 // @enumToInt(val)
1808 return Node.enum_to_int.create(c.arena, expr);
1780 return Tag.enum_to_int.create(c.arena, expr);
18091781 }
18101782 // @as(dest_type, val)
1811 return Node.as.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
1783 return Tag.as.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
18121784}
18131785
1814fn transExpr(
1815 c: *Context,
1816 scope: *Scope,
1817 expr: *const clang.Expr,
1818 used: ResultUsed,
1819 lrvalue: LRValue,
1820) TransError!Node {
1821 return transStmt(c, scope, @ptrCast(*const clang.Stmt, expr), used, lrvalue);
1786fn transExpr(c: *Context, scope: *Scope, expr: *const clang.Expr, used: ResultUsed) TransError!Node {
1787 return transStmt(c, scope, @ptrCast(*const clang.Stmt, expr), used);
18221788}
18231789
18241790/// Same as `transExpr` but with the knowledge that the operand will be type coerced, and therefore
18251791/// an `@as` would be redundant. This is used to prevent redundant `@as` in integer literals.
1826fn transExprCoercing(
1827 c: *Context,
1828 scope: *Scope,
1829 expr: *const clang.Expr,
1830 used: ResultUsed,
1831 lrvalue: LRValue,
1832) TransError!Node {
1792fn transExprCoercing(c: *Context, scope: *Scope, expr: *const clang.Expr, used: ResultUsed) TransError!Node {
18331793 switch (@ptrCast(*const clang.Stmt, expr).getStmtClass()) {
18341794 .IntegerLiteralClass => {
18351795 return transIntegerLiteral(c, scope, @ptrCast(*const clang.IntegerLiteral, expr), .used, .no_as);
......@@ -1840,12 +1800,12 @@ fn transExprCoercing(
18401800 .UnaryOperatorClass => {
18411801 const un_expr = @ptrCast(*const clang.UnaryOperator, expr);
18421802 if (un_expr.getOpcode() == .Extension) {
1843 return transExprCoercing(c, scope, un_expr.getSubExpr(), used, lrvalue);
1803 return transExprCoercing(c, scope, un_expr.getSubExpr(), used);
18441804 }
18451805 },
18461806 else => {},
18471807 }
1848 return transExpr(c, scope, expr, .used, .r_value);
1808 return transExpr(c, scope, expr, .used);
18491809}
18501810
18511811fn transInitListExprRecord(
......@@ -1896,11 +1856,11 @@ fn transInitListExprRecord(
18961856
18971857 try field_inits.append(.{
18981858 .name = raw_name,
1899 .value = try transExpr(c, scope, elem_expr, .used, .r_value),
1859 .value = try transExpr(c, scope, elem_expr, .used),
19001860 });
19011861 }
19021862
1903 return Node.container_init.create(c.arena, try c.arena.dupe(ast.Payload.ContainerInit.Initializer, field_inits.items));
1863 return Tag.container_init.create(c.arena, try c.arena.dupe(ast.Payload.ContainerInit.Initializer, field_inits.items));
19041864}
19051865
19061866fn transInitListExprArray(
......@@ -1920,18 +1880,18 @@ fn transInitListExprArray(
19201880 const leftover_count = all_count - init_count;
19211881
19221882 if (all_count == 0) {
1923 return Node.empty_array.create(c.arena, try transQualType(c, child_qt, source_loc));
1883 return Tag.empty_array.create(c.arena, try transQualType(c, child_qt, loc));
19241884 }
19251885
1926 const ty_node = try transType(ty);
1886 const ty_node = try transType(c, ty, loc);
19271887 const init_node = if (init_count != 0) blk: {
19281888 const init_list = try c.arena.alloc(Node, init_count);
19291889
19301890 for (init_list) |*init, i| {
1931 const elem_expr = expr.getInit(i);
1932 init.* = try transExpr(c, scope, elem_expr, .used, .r_value);
1891 const elem_expr = expr.getInit(@intCast(c_uint, i));
1892 init.* = try transExpr(c, scope, elem_expr, .used);
19331893 }
1934 const init_node = try Node.array_init.create(c.arena, init_list);
1894 const init_node = try Tag.array_init.create(c.arena, init_list);
19351895 if (leftover_count == 0) {
19361896 return init_node;
19371897 }
......@@ -1939,14 +1899,14 @@ fn transInitListExprArray(
19391899 } else null;
19401900
19411901 const filler_val_expr = expr.getArrayFiller();
1942 const filler_node = try Node.array_filler.create(c.arena, .{
1902 const filler_node = try Tag.array_filler.create(c.arena, .{
19431903 .type = ty_node,
1944 .filler = try transExpr(c, scope, filler_val_expr, .used, .r_value),
1904 .filler = try transExpr(c, scope, filler_val_expr, .used),
19451905 .count = leftover_count,
19461906 });
19471907
19481908 if (init_node) |some| {
1949 return Node.array_cat.create(c.arena, some, filler_node);
1909 return Tag.array_cat.create(c.arena, .{ .lhs = some, .rhs = filler_node });
19501910 } else {
19511911 return filler_node;
19521912 }
......@@ -1964,7 +1924,7 @@ fn transInitListExpr(
19641924
19651925 if (qual_type.isRecordType()) {
19661926 return maybeSuppressResult(c, scope, used, try transInitListExprRecord(
1967 rp,
1927 c,
19681928 scope,
19691929 source_loc,
19701930 expr,
......@@ -1972,7 +1932,7 @@ fn transInitListExpr(
19721932 ));
19731933 } else if (qual_type.isArrayType()) {
19741934 return maybeSuppressResult(c, scope, used, try transInitListExprArray(
1975 rp,
1935 c,
19761936 scope,
19771937 source_loc,
19781938 expr,
......@@ -1994,7 +1954,7 @@ fn transZeroInitExpr(
19941954 .Builtin => {
19951955 const builtin_ty = @ptrCast(*const clang.BuiltinType, ty);
19961956 switch (builtin_ty.getKind()) {
1997 .Bool => return Node.false_literal.init(),
1957 .Bool => return Tag.false_literal.init(),
19981958 .Char_U,
19991959 .UChar,
20001960 .Char_S,
......@@ -2015,11 +1975,11 @@ fn transZeroInitExpr(
20151975 .Float128,
20161976 .Float16,
20171977 .LongDouble,
2018 => return Node.zero_literal.init(),
1978 => return Tag.zero_literal.init(),
20191979 else => return fail(c, error.UnsupportedType, source_loc, "unsupported builtin type", .{}),
20201980 }
20211981 },
2022 .Pointer => return Node.null_literal.init(),
1982 .Pointer => return Tag.null_literal.init(),
20231983 .Typedef => {
20241984 const typedef_ty = @ptrCast(*const clang.TypedefType, ty);
20251985 const typedef_decl = typedef_ty.getDecl();
......@@ -2058,19 +2018,19 @@ fn transIfStmt(
20582018 var cond_scope = Scope.Condition{
20592019 .base = .{
20602020 .parent = scope,
2061 .id = .Condition,
2021 .id = .condition,
20622022 },
20632023 };
20642024 defer cond_scope.deinit();
20652025 const cond_expr = @ptrCast(*const clang.Expr, stmt.getCond());
2066 const cond = try transBoolExpr(c, &cond_scope.base, cond_expr, .used, .r_value);
2026 const cond = try transBoolExpr(c, &cond_scope.base, cond_expr, .used);
20672027
2068 const then_body = try transStmt(c, scope, stmt.getThen(), .unused, .r_value);
2028 const then_body = try transStmt(c, scope, stmt.getThen(), .unused);
20692029 const else_body = if (stmt.getElse()) |expr|
2070 try transStmt(c, scope, expr, .unused, .r_value)
2030 try transStmt(c, scope, expr, .unused)
20712031 else
20722032 null;
2073 return Node.@"if".create(c.arena, .{ .cond = cond, .then = then_body, .@"else" = else_body });
2033 return Tag.@"if".create(c.arena, .{ .cond = cond, .then = then_body, .@"else" = else_body });
20742034}
20752035
20762036fn transWhileLoop(
......@@ -2081,19 +2041,19 @@ fn transWhileLoop(
20812041 var cond_scope = Scope.Condition{
20822042 .base = .{
20832043 .parent = scope,
2084 .id = .Condition,
2044 .id = .condition,
20852045 },
20862046 };
20872047 defer cond_scope.deinit();
20882048 const cond_expr = @ptrCast(*const clang.Expr, stmt.getCond());
2089 const cond = try transBoolExpr(c, &cond_scope.base, cond_expr, .used, .r_value);
2049 const cond = try transBoolExpr(c, &cond_scope.base, cond_expr, .used);
20902050
20912051 var loop_scope = Scope{
20922052 .parent = scope,
2093 .id = .Loop,
2053 .id = .loop,
20942054 };
2095 const body = try transStmt(c, &loop_scope, stmt.getBody(), .unused, .r_value);
2096 return Node.@"while".create(c.arena, .{ .cond = cond, .body = body, .cont_expr = null });
2055 const body = try transStmt(c, &loop_scope, stmt.getBody(), .unused);
2056 return Tag.@"while".create(c.arena, .{ .cond = cond, .body = body, .cont_expr = null });
20972057}
20982058
20992059fn transDoWhileLoop(
......@@ -2103,20 +2063,19 @@ fn transDoWhileLoop(
21032063) TransError!Node {
21042064 var loop_scope = Scope{
21052065 .parent = scope,
2106 .id = .Loop,
2066 .id = .loop,
21072067 };
21082068
21092069 // if (!cond) break;
2110 const if_node = try transCreateNodeIf(c);
21112070 var cond_scope = Scope.Condition{
21122071 .base = .{
21132072 .parent = scope,
2114 .id = .Condition,
2073 .id = .condition,
21152074 },
21162075 };
21172076 defer cond_scope.deinit();
2118 const cond = try transBoolExpr(c, &cond_scope.base, @ptrCast(*const clang.Expr, stmt.getCond()), .used, .r_value);
2119 const if_not_break = try Node.if_not_break.create(c.arena, cond);
2077 const cond = try transBoolExpr(c, &cond_scope.base, @ptrCast(*const clang.Expr, stmt.getCond()), .used);
2078 const if_not_break = try Tag.if_not_break.create(c.arena, cond);
21202079
21212080 const body_node = if (stmt.getBody().getStmtClass() == .CompoundStmtClass) blk: {
21222081 // there's already a block in C, so we'll append our condition to it.
......@@ -2129,8 +2088,8 @@ fn transDoWhileLoop(
21292088 // zig: b;
21302089 // zig: if (!cond) break;
21312090 // zig: }
2132 const node = try transStmt(c, &loop_scope, stmt.getBody(), .unused, .r_value);
2133 const block = node.castTag(.block);
2091 const node = try transStmt(c, &loop_scope, stmt.getBody(), .unused);
2092 const block = node.castTag(.block).?;
21342093 block.data.stmts.len += 1; // This is safe since we reserve one extra space in Scope.Block.complete.
21352094 block.data.stmts[block.data.stmts.len - 1] = if_not_break;
21362095 break :blk node;
......@@ -2143,12 +2102,12 @@ fn transDoWhileLoop(
21432102 // zig: a;
21442103 // zig: if (!cond) break;
21452104 // zig: }
2146 const statements = try c.arena.create(Node, 2);
2147 statements[0] = try transStmt(c, &loop_scope, stmt.getBody(), .unused, .r_value);
2105 const statements = try c.arena.alloc(Node, 2);
2106 statements[0] = try transStmt(c, &loop_scope, stmt.getBody(), .unused);
21482107 statements[1] = if_not_break;
2149 break :blk try Node.block.create(c.arena, .{ .label = null, .stmts = statements });
2108 break :blk try Tag.block.create(c.arena, .{ .label = null, .stmts = statements });
21502109 };
2151 return Node.while_true.create(c.arena, body_node);
2110 return Tag.while_true.create(c.arena, body_node);
21522111}
21532112
21542113fn transForLoop(
......@@ -2158,7 +2117,7 @@ fn transForLoop(
21582117) TransError!Node {
21592118 var loop_scope = Scope{
21602119 .parent = scope,
2161 .id = .Loop,
2120 .id = .loop,
21622121 };
21632122
21642123 var block_scope: ?Scope.Block = null;
......@@ -2167,29 +2126,29 @@ fn transForLoop(
21672126 if (stmt.getInit()) |init| {
21682127 block_scope = try Scope.Block.init(c, scope, false);
21692128 loop_scope.parent = &block_scope.?.base;
2170 const init_node = try transStmt(c, &block_scope.?.base, init, .unused, .r_value);
2129 const init_node = try transStmt(c, &block_scope.?.base, init, .unused);
21712130 try block_scope.?.statements.append(init_node);
21722131 }
21732132 var cond_scope = Scope.Condition{
21742133 .base = .{
21752134 .parent = &loop_scope,
2176 .id = .Condition,
2135 .id = .condition,
21772136 },
21782137 };
21792138 defer cond_scope.deinit();
21802139
21812140 const cond = if (stmt.getCond()) |cond|
2182 try transBoolExpr(c, &cond_scope.base, cond, .used, .r_value)
2141 try transBoolExpr(c, &cond_scope.base, cond, .used)
21832142 else
2184 Node.true_literal.init();
2143 Tag.true_literal.init();
21852144
21862145 const cont_expr = if (stmt.getInc()) |incr|
2187 try transExpr(c, &cond_scope.base, incr, .unused, .r_value)
2146 try transExpr(c, &cond_scope.base, incr, .unused)
21882147 else
21892148 null;
21902149
2191 const body = try transStmt(c, &loop_scope, stmt.getBody(), .unused, .r_value);
2192 const while_node = try Node.@"while".create(c.arena, .{ .cond = cond, .body = body, .cont_expr = cont_expr });
2150 const body = try transStmt(c, &loop_scope, stmt.getBody(), .unused);
2151 const while_node = try Tag.@"while".create(c.arena, .{ .cond = cond, .body = body, .cont_expr = cont_expr });
21932152 if (block_scope) |*bs| {
21942153 try bs.statements.append(while_node);
21952154 return try bs.complete(c);
......@@ -2206,13 +2165,14 @@ fn transSwitch(
22062165 var cond_scope = Scope.Condition{
22072166 .base = .{
22082167 .parent = scope,
2209 .id = .Condition,
2168 .id = .condition,
22102169 },
22112170 };
22122171 defer cond_scope.deinit();
2213 const switch_expr = try transExpr(c, &cond_scope.base, stmt.getCond(), .used, .r_value);
2172 const switch_expr = try transExpr(c, &cond_scope.base, stmt.getCond(), .used);
22142173 const switch_node = try c.arena.create(ast.Payload.Switch);
22152174 switch_node.* = .{
2175 .base = .{ .tag = .@"switch" },
22162176 .data = .{
22172177 .cond = switch_expr,
22182178 .cases = undefined, // set later
......@@ -2221,7 +2181,7 @@ fn transSwitch(
22212181
22222182 var switch_scope = Scope.Switch{
22232183 .base = .{
2224 .id = .Switch,
2184 .id = .@"switch",
22252185 .parent = scope,
22262186 },
22272187 .cases = std.ArrayList(Node).init(c.gpa),
......@@ -2229,11 +2189,7 @@ fn transSwitch(
22292189 .default_label = null,
22302190 .switch_label = null,
22312191 };
2232 defer {
2233 switch_node.data.cases = try c.arena.dupe(Node, switch_scope.cases.items);
2234 switch_node.data.default = switch_scope.switch_label;
2235 switch_scope.cases.deinit();
2236 }
2192 defer switch_scope.cases.deinit();
22372193
22382194 // tmp block that all statements will go before being picked up by a case or default
22392195 var block_scope = try Scope.Block.init(c, &switch_scope.base, false);
......@@ -2246,7 +2202,7 @@ fn transSwitch(
22462202 switch_scope.pending_block = try Scope.Block.init(c, scope, false);
22472203 try switch_scope.pending_block.statements.append(Node.initPayload(&switch_node.base));
22482204
2249 const last = try transStmt(c, &block_scope.base, stmt.getBody(), .unused, .r_value);
2205 const last = try transStmt(c, &block_scope.base, stmt.getBody(), .unused);
22502206
22512207 // take all pending statements
22522208 const last_block_stmts = last.castTag(.block).?.data.stmts;
......@@ -2264,13 +2220,14 @@ fn transSwitch(
22642220 switch_scope.pending_block.label = l;
22652221 }
22662222 if (switch_scope.default_label == null) {
2267 const else_prong = try Node.switch_else.create(
2223 const else_prong = try Tag.switch_else.create(
22682224 c.arena,
2269 try Node.@"break".create(c.arena, switch_scope.switch_label.?),
2225 try Tag.@"break".create(c.arena, switch_scope.switch_label.?),
22702226 );
2271 switch_scope.cases.append(else_prong);
2227 try switch_scope.cases.append(else_prong);
22722228 }
22732229
2230 switch_node.data.cases = try c.arena.dupe(Node, switch_scope.cases.items);
22742231 const result_node = try switch_scope.pending_block.complete(c);
22752232 switch_scope.pending_block.deinit();
22762233 return result_node;
......@@ -2286,18 +2243,18 @@ fn transCase(
22862243 const label = try block_scope.makeMangledName(c, "case");
22872244
22882245 const expr = if (stmt.getRHS()) |rhs| blk: {
2289 const lhs_node = try transExpr(c, scope, stmt.getLHS(), .used, .r_value);
2290 const rhs_node = try transExpr(c, scope, rhs, .used, .r_value);
2246 const lhs_node = try transExpr(c, scope, stmt.getLHS(), .used);
2247 const rhs_node = try transExpr(c, scope, rhs, .used);
22912248
2292 break :blk Node.ellipsis3.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node });
2249 break :blk try Tag.ellipsis3.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node });
22932250 } else
2294 try transExpr(c, scope, stmt.getLHS(), .used, .r_value);
2251 try transExpr(c, scope, stmt.getLHS(), .used);
22952252
2296 const switch_prong = try Node.switch_prong.create(
2297 c.arena,
2298 try Node.@"break".create(c.arena, label),
2299 );
2300 switch_scope.cases.append(switch_prong);
2253 const switch_prong = try Tag.switch_prong.create(c.arena, .{
2254 .lhs = expr,
2255 .rhs = try Tag.@"break".create(c.arena, label),
2256 });
2257 try switch_scope.cases.append(switch_prong);
23012258
23022259 switch_scope.pending_block.label = label;
23032260
......@@ -2311,7 +2268,7 @@ fn transCase(
23112268
23122269 try switch_scope.pending_block.statements.append(pending_node);
23132270
2314 return transStmt(c, scope, stmt.getSubStmt(), .unused, .r_value);
2271 return transStmt(c, scope, stmt.getSubStmt(), .unused);
23152272}
23162273
23172274fn transDefault(
......@@ -2323,12 +2280,12 @@ fn transDefault(
23232280 const switch_scope = scope.getSwitch();
23242281 switch_scope.default_label = try block_scope.makeMangledName(c, "default");
23252282
2326 const else_prong = try Node.switch_else.create(
2283 const else_prong = try Tag.switch_else.create(
23272284 c.arena,
2328 try Node.@"break".create(c.arena, switch_scope.default_label.?),
2285 try Tag.@"break".create(c.arena, switch_scope.default_label.?),
23292286 );
2330 switch_scope.cases.append(else_prong);
2331 switch_scope.pending_block.label = try appendIdentifier(c, switch_scope.default_label.?);
2287 try switch_scope.cases.append(else_prong);
2288 switch_scope.pending_block.label = switch_scope.default_label.?;
23322289
23332290 // take all pending statements
23342291 try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items);
......@@ -2339,7 +2296,7 @@ fn transDefault(
23392296 switch_scope.pending_block = try Scope.Block.init(c, scope, false);
23402297 try switch_scope.pending_block.statements.append(pending_node);
23412298
2342 return transStmt(c, scope, stmt.getSubStmt(), .unused, .r_value);
2299 return transStmt(c, scope, stmt.getSubStmt(), .unused);
23432300}
23442301
23452302fn transConstantExpr(c: *Context, scope: *Scope, expr: *const clang.Expr, used: ResultUsed) TransError!Node {
......@@ -2352,7 +2309,7 @@ fn transConstantExpr(c: *Context, scope: *Scope, expr: *const clang.Expr, used:
23522309 // See comment in `transIntegerLiteral` for why this code is here.
23532310 // @as(T, x)
23542311 const expr_base = @ptrCast(*const clang.Expr, expr);
2355 const as_node = try Node.as.create(c.arena, .{
2312 const as_node = try Tag.as.create(c.arena, .{
23562313 .lhs = try transQualType(c, expr_base.getType(), expr_base.getBeginLoc()),
23572314 .rhs = try transCreateNodeAPInt(c, result.Val.getInt()),
23582315 });
......@@ -2369,10 +2326,10 @@ fn transPredefinedExpr(c: *Context, scope: *Scope, expr: *const clang.Predefined
23692326}
23702327
23712328fn transCreateCharLitNode(c: *Context, narrow: bool, val: u32) TransError!Node {
2372 return Node.char_literal.create(c.arena, if (narrow)
2373 try std.fmt.bufPrint(c.arena, "'{}'", .{std.zig.fmtEscapes(&.{@intCast(u8, val)})})
2329 return Tag.char_literal.create(c.arena, if (narrow)
2330 try std.fmt.allocPrint(c.arena, "'{s}'", .{std.zig.fmtEscapes(&.{@intCast(u8, val)})})
23742331 else
2375 try std.fmt.bufPrint(c.arena, "'\\u{{{x}}}'", .{val}));
2332 try std.fmt.allocPrint(c.arena, "'\\u{{{x}}}'", .{val}));
23762333}
23772334
23782335fn transCharLiteral(
......@@ -2398,7 +2355,7 @@ fn transCharLiteral(
23982355 // See comment in `transIntegerLiteral` for why this code is here.
23992356 // @as(T, x)
24002357 const expr_base = @ptrCast(*const clang.Expr, stmt);
2401 const as_node = Node.as.create(c.arena, .{
2358 const as_node = try Tag.as.create(c.arena, .{
24022359 .lhs = try transQualType(c, expr_base.getType(), expr_base.getBeginLoc()),
24032360 .rhs = int_lit_node,
24042361 });
......@@ -2416,12 +2373,12 @@ fn transStmtExpr(c: *Context, scope: *Scope, stmt: *const clang.StmtExpr, used:
24162373 var it = comp.body_begin();
24172374 const end_it = comp.body_end();
24182375 while (it != end_it - 1) : (it += 1) {
2419 const result = try transStmt(rp, &block_scope.base, it[0], .unused, .r_value);
2376 const result = try transStmt(c, &block_scope.base, it[0], .unused);
24202377 try block_scope.statements.append(result);
24212378 }
2422 const break_node = try Node.break_val.create(c.arena, .{
2423 .label = block_scope.label,
2424 .val = try transStmt(c, &block_scope.base, it[0], .used, .r_value),
2379 const break_node = try Tag.break_val.create(c.arena, .{
2380 .label = block_scope.label,
2381 .val = try transStmt(c, &block_scope.base, it[0], .used),
24252382 });
24262383 try block_scope.statements.append(break_node);
24272384 const res = try block_scope.complete(c);
......@@ -2429,10 +2386,10 @@ fn transStmtExpr(c: *Context, scope: *Scope, stmt: *const clang.StmtExpr, used:
24292386}
24302387
24312388fn transMemberExpr(c: *Context, scope: *Scope, stmt: *const clang.MemberExpr, result_used: ResultUsed) TransError!Node {
2432 var container_node = try transExpr(c, scope, stmt.getBase(), .used, .r_value);
2389 var container_node = try transExpr(c, scope, stmt.getBase(), .used);
24332390
24342391 if (stmt.isArrow()) {
2435 container_node = try Node.deref.create(c.arena, container_node);
2392 container_node = try Tag.deref.create(c.arena, container_node);
24362393 }
24372394
24382395 const member_decl = stmt.getMemberDecl();
......@@ -2450,9 +2407,9 @@ fn transMemberExpr(c: *Context, scope: *Scope, stmt: *const clang.MemberExpr, re
24502407 const decl = @ptrCast(*const clang.NamedDecl, member_decl);
24512408 break :blk try c.str(decl.getName_bytes_begin());
24522409 };
2453 const ident = try Node.identifier.create(c.arena, name);
2410 const ident = try Tag.identifier.create(c.arena, name);
24542411
2455 const node = try Node.field_access.create(c.arena, .{ .lhs = container_node, .rhs = ident});
2412 const node = try Tag.field_access.create(c.arena, .{ .lhs = container_node, .rhs = ident });
24562413 return maybeSuppressResult(c, scope, result_used, node);
24572414}
24582415
......@@ -2469,7 +2426,7 @@ fn transArrayAccess(c: *Context, scope: *Scope, stmt: *const clang.ArraySubscrip
24692426 }
24702427 }
24712428
2472 const container_node = try transExpr(c, scope, base_stmt, .used, .r_value);
2429 const container_node = try transExpr(c, scope, base_stmt, .used);
24732430
24742431 // cast if the index is long long or signed
24752432 const subscr_expr = stmt.getIdx();
......@@ -2477,14 +2434,17 @@ fn transArrayAccess(c: *Context, scope: *Scope, stmt: *const clang.ArraySubscrip
24772434 const is_longlong = cIsLongLongInteger(qt);
24782435 const is_signed = cIsSignedInteger(qt);
24792436
2480
2481 const node = try Node.array_access.create(c.arena, .{ .lhs = container_node, .rhs = if (is_longlong or is_signed) blk: {
2482 const cast_node = try c.createBuiltinCall("@intCast", 2);
2437 const rhs = if (is_longlong or is_signed) blk: {
24832438 // check if long long first so that signed long long doesn't just become unsigned long long
2484 var typeid_node = if (is_longlong) try transCreateNodeIdentifier(c, "usize") else try transQualTypeIntWidthOf(c, qt, false);
2485 break :blk try Node.int_cast.create(c.arena, .{ .lhs = typeid_node, .rhs = try transExpr(c, scope, subscr_expr, .used, .r_value)});
2439 var typeid_node = if (is_longlong) try Tag.identifier.create(c.arena, "usize") else try transQualTypeIntWidthOf(c, qt, false);
2440 break :blk try Tag.int_cast.create(c.arena, .{ .lhs = typeid_node, .rhs = try transExpr(c, scope, subscr_expr, .used) });
24862441 } else
2487 try transExpr(c, scope, subscr_expr, .used, .r_value)});
2442 try transExpr(c, scope, subscr_expr, .used);
2443
2444 const node = try Tag.array_access.create(c.arena, .{
2445 .lhs = container_node,
2446 .rhs = rhs,
2447 });
24882448 return maybeSuppressResult(c, scope, result_used, node);
24892449}
24902450
......@@ -2522,23 +2482,23 @@ fn cIsFunctionDeclRef(expr: *const clang.Expr) bool {
25222482
25232483fn transCallExpr(c: *Context, scope: *Scope, stmt: *const clang.CallExpr, result_used: ResultUsed) TransError!Node {
25242484 const callee = stmt.getCallee();
2525 var raw_fn_expr = try transExpr(c, scope, callee, .used, .r_value);
2485 var raw_fn_expr = try transExpr(c, scope, callee, .used);
25262486
25272487 var is_ptr = false;
25282488 const fn_ty = qualTypeGetFnProto(callee.getType(), &is_ptr);
25292489
25302490 const fn_expr = if (is_ptr and fn_ty != null and !cIsFunctionDeclRef(callee))
2531 try transCreateNodeUnwrapNull(rp.c, raw_fn_expr)
2491 try Tag.unwrap.create(c.arena, raw_fn_expr)
25322492 else
25332493 raw_fn_expr;
25342494
25352495 const num_args = stmt.getNumArgs();
2536 const call_params = try c.arena.alloc(Node, num_args);
2496 const args = try c.arena.alloc(Node, num_args);
25372497
2538 const args = stmt.getArgs();
2498 const c_args = stmt.getArgs();
25392499 var i: usize = 0;
25402500 while (i < num_args) : (i += 1) {
2541 var call_param = try transExpr(c, scope, args[i], .used, .r_value);
2501 var arg = try transExpr(c, scope, c_args[i], .used);
25422502
25432503 // In C the result type of a boolean expression is int. If this result is passed as
25442504 // an argument to a function whose parameter is also int, there is no cast. Therefore
......@@ -2549,17 +2509,17 @@ fn transCallExpr(c: *Context, scope: *Scope, stmt: *const clang.CallExpr, result
25492509 const param_count = fn_proto.getNumParams();
25502510 if (i < param_count) {
25512511 const param_qt = fn_proto.getParamType(@intCast(c_uint, i));
2552 if (isBoolRes(call_param) and cIsNativeInt(param_qt)) {
2553 call_param = try Node.bool_to_int.create(c.arena, call_param);
2512 if (isBoolRes(arg) and cIsNativeInt(param_qt)) {
2513 arg = try Tag.bool_to_int.create(c.arena, arg);
25542514 }
25552515 }
25562516 },
25572517 else => {},
25582518 }
25592519 }
2560 call_params[i] = call_param;
2520 args[i] = arg;
25612521 }
2562 const node = try Node.call.create(c.arena, .{ .lhs = fn_expr, .args = call_params });
2522 const node = try Tag.call.create(c.arena, .{ .lhs = fn_expr, .args = args });
25632523 if (fn_ty) |ty| {
25642524 const canon = ty.getReturnType().getCanonicalType();
25652525 const ret_ty = canon.getTypePtr();
......@@ -2609,17 +2569,17 @@ fn transUnaryExprOrTypeTraitExpr(
26092569 result_used: ResultUsed,
26102570) TransError!Node {
26112571 const loc = stmt.getBeginLoc();
2612 const type_node = try transQualType(rp, stmt.getTypeOfArgument(), loc);
2572 const type_node = try transQualType(c, stmt.getTypeOfArgument(), loc);
26132573
26142574 const kind = stmt.getKind();
26152575 switch (kind) {
2616 .SizeOf => return Node.sizeof.create(c.arena, type_node),
2617 .AlignOf => return Node.alignof.create(c.arena, type_node),
2576 .SizeOf => return Tag.sizeof.create(c.arena, type_node),
2577 .AlignOf => return Tag.alignof.create(c.arena, type_node),
26182578 .PreferredAlignOf,
26192579 .VecStep,
26202580 .OpenMPRequiredSimdAlign,
2621 => return revertAndWarn(
2622 rp,
2581 => return fail(
2582 c,
26232583 error.UnsupportedTranslation,
26242584 loc,
26252585 "Unsupported type trait kind {}",
......@@ -2642,53 +2602,54 @@ fn transUnaryOperator(c: *Context, scope: *Scope, stmt: *const clang.UnaryOperat
26422602 const op_expr = stmt.getSubExpr();
26432603 switch (stmt.getOpcode()) {
26442604 .PostInc => if (qualTypeHasWrappingOverflow(stmt.getType()))
2645 return transCreatePostCrement(c, scope, stmt, .assign_add_wrap, used)
2605 return transCreatePostCrement(c, scope, stmt, .add_wrap_assign, used)
26462606 else
2647 return transCreatePostCrement(c, scope, stmt, .assign_add, used),
2607 return transCreatePostCrement(c, scope, stmt, .add_assign, used),
26482608 .PostDec => if (qualTypeHasWrappingOverflow(stmt.getType()))
2649 return transCreatePostCrement(c, scope, stmt, .assign_sub_wrap, used)
2609 return transCreatePostCrement(c, scope, stmt, .sub_wrap_assign, used)
26502610 else
2651 return transCreatePostCrement(c, scope, stmt, .assign_sub, used),
2611 return transCreatePostCrement(c, scope, stmt, .sub_assign, used),
26522612 .PreInc => if (qualTypeHasWrappingOverflow(stmt.getType()))
2653 return transCreatePreCrement(c, scope, stmt, .assign_add_wrap, used)
2613 return transCreatePreCrement(c, scope, stmt, .add_wrap_assign, used)
26542614 else
2655 return transCreatePreCrement(c, scope, stmt, .assign_add, used),
2615 return transCreatePreCrement(c, scope, stmt, .add_assign, used),
26562616 .PreDec => if (qualTypeHasWrappingOverflow(stmt.getType()))
2657 return transCreatePreCrement(c, scope, stmt, .assign_sub_wrap, used)
2617 return transCreatePreCrement(c, scope, stmt, .sub_wrap_assign, used)
26582618 else
2659 return transCreatePreCrement(c, scope, stmt, .assign_sub, used),
2619 return transCreatePreCrement(c, scope, stmt, .sub_assign, used),
26602620 .AddrOf => {
26612621 if (cIsFunctionDeclRef(op_expr)) {
2662 return transExpr(rp, scope, op_expr, used, .r_value);
2622 return transExpr(c, scope, op_expr, used);
26632623 }
2664 return Node.address_of.create(c.arena, try transExpr(c, scope, op_expr, used, .r_value));
2624 return Tag.address_of.create(c.arena, try transExpr(c, scope, op_expr, used));
26652625 },
26662626 .Deref => {
2667 const node = try transExpr(c, scope, op_expr, used, .r_value);
2627 const node = try transExpr(c, scope, op_expr, used);
26682628 var is_ptr = false;
26692629 const fn_ty = qualTypeGetFnProto(op_expr.getType(), &is_ptr);
26702630 if (fn_ty != null and is_ptr)
26712631 return node;
2672 return Node.unwrap_deref.create(c.arena, node);
2632 const unwrapped = try Tag.unwrap.create(c.arena, node);
2633 return Tag.deref.create(c.arena, unwrapped);
26732634 },
2674 .Plus => return transExpr(c, scope, op_expr, used, .r_value),
2635 .Plus => return transExpr(c, scope, op_expr, used),
26752636 .Minus => {
26762637 if (!qualTypeHasWrappingOverflow(op_expr.getType())) {
2677 return Node.negate.create(c.arena, try transExpr(c, scope, op_expr, .used, .r_value));
2638 return Tag.negate.create(c.arena, try transExpr(c, scope, op_expr, .used));
26782639 } else if (cIsUnsignedInteger(op_expr.getType())) {
26792640 // use -% x for unsigned integers
2680 return Node.negate_wrap.create(c.arena, try transExpr(c, scope, op_expr, .used, .r_value));
2641 return Tag.negate_wrap.create(c.arena, try transExpr(c, scope, op_expr, .used));
26812642 } else
26822643 return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "C negation with non float non integer", .{});
26832644 },
26842645 .Not => {
2685 return Node.bit_not.create(c.arena, try transExpr(c, scope, op_expr, .used, .r_value));
2646 return Tag.bit_not.create(c.arena, try transExpr(c, scope, op_expr, .used));
26862647 },
26872648 .LNot => {
2688 return Node.not.create(c.arena, try transExpr(c, scope, op_expr, .used, .r_value));
2649 return Tag.not.create(c.arena, try transExpr(c, scope, op_expr, .used));
26892650 },
26902651 .Extension => {
2691 return transExpr(c, scope, stmt.getSubExpr(), used, .l_value);
2652 return transExpr(c, scope, stmt.getSubExpr(), used);
26922653 },
26932654 else => return fail(c, error.UnsupportedTranslation, stmt.getBeginLoc(), "unsupported C translation {}", .{stmt.getOpcode()}),
26942655 }
......@@ -2698,7 +2659,7 @@ fn transCreatePreCrement(
26982659 c: *Context,
26992660 scope: *Scope,
27002661 stmt: *const clang.UnaryOperator,
2701 op: Node.Tag,
2662 op: Tag,
27022663 used: ResultUsed,
27032664) TransError!Node {
27042665 const op_expr = stmt.getSubExpr();
......@@ -2707,8 +2668,8 @@ fn transCreatePreCrement(
27072668 // common case
27082669 // c: ++expr
27092670 // zig: expr += 1
2710 const lhs = try transExpr(c, scope, op_expr, .used, .r_value);
2711 const rhs = Node.one_literal.init();
2671 const lhs = try transExpr(c, scope, op_expr, .used);
2672 const rhs = Tag.one_literal.init();
27122673 return transCreateNodeInfixOp(c, scope, op, lhs, rhs, .used);
27132674 }
27142675 // worst case
......@@ -2722,17 +2683,17 @@ fn transCreatePreCrement(
27222683 defer block_scope.deinit();
27232684 const ref = try block_scope.makeMangledName(c, "ref");
27242685
2725 const expr = try transExpr(c, scope, op_expr, .used, .r_value);
2726 const addr_of = try Node.address_of.create(c.arena, expr);
2727 const ref_decl = try Node.var_simple.create(c.arena, .{ .name = ref, .init = addr_of});
2686 const expr = try transExpr(c, scope, op_expr, .used);
2687 const addr_of = try Tag.address_of.create(c.arena, expr);
2688 const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of });
27282689 try block_scope.statements.append(ref_decl);
27292690
2730 const lhs_node = try Node.identifier.create(c.arena, ref);
2731 const ref_node = try Node.deref.create(c.arena, lhs_node);
2732 const node = try transCreateNodeInfixOp(c, scope, op, ref_node, Node.one_literal.init(), .used);
2691 const lhs_node = try Tag.identifier.create(c.arena, ref);
2692 const ref_node = try Tag.deref.create(c.arena, lhs_node);
2693 const node = try transCreateNodeInfixOp(c, scope, op, ref_node, Tag.one_literal.init(), .used);
27332694 try block_scope.statements.append(node);
27342695
2735 const break_node = try Node.break_val.create(c.arena, .{
2696 const break_node = try Tag.break_val.create(c.arena, .{
27362697 .label = block_scope.label,
27372698 .val = ref_node,
27382699 });
......@@ -2744,7 +2705,7 @@ fn transCreatePostCrement(
27442705 c: *Context,
27452706 scope: *Scope,
27462707 stmt: *const clang.UnaryOperator,
2747 op: Node.Tag,
2708 op: Tag,
27482709 used: ResultUsed,
27492710) TransError!Node {
27502711 const op_expr = stmt.getSubExpr();
......@@ -2753,8 +2714,8 @@ fn transCreatePostCrement(
27532714 // common case
27542715 // c: expr++
27552716 // zig: expr += 1
2756 const lhs = try transExpr(c, scope, op_expr, .used, .r_value);
2757 const rhs = Node.one_literal.init();
2717 const lhs = try transExpr(c, scope, op_expr, .used);
2718 const rhs = Tag.one_literal.init();
27582719 return transCreateNodeInfixOp(c, scope, op, lhs, rhs, .used);
27592720 }
27602721 // worst case
......@@ -2769,24 +2730,24 @@ fn transCreatePostCrement(
27692730 defer block_scope.deinit();
27702731 const ref = try block_scope.makeMangledName(c, "ref");
27712732
2772 const expr = try transExpr(c, scope, op_expr, .used, .r_value);
2773 const addr_of = try Node.address_of.create(c.arena, expr);
2774 const ref_decl = try Node.var_simple.create(c.arena, .{ .name = ref, .init = addr_of});
2733 const expr = try transExpr(c, scope, op_expr, .used);
2734 const addr_of = try Tag.address_of.create(c.arena, expr);
2735 const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of });
27752736 try block_scope.statements.append(ref_decl);
27762737
2777 const lhs_node = try Node.identifier.create(c.arena, ref);
2778 const ref_node = try Node.deref.create(c.arena, lhs_node);
2738 const lhs_node = try Tag.identifier.create(c.arena, ref);
2739 const ref_node = try Tag.deref.create(c.arena, lhs_node);
27792740
27802741 const tmp = try block_scope.makeMangledName(c, "tmp");
2781 const tmp_decl = try Node.var_simple.create(c.arena, .{ .name = tmp, .init = ref_node});
2742 const tmp_decl = try Tag.var_simple.create(c.arena, .{ .name = tmp, .init = ref_node });
27822743 try block_scope.statements.append(tmp_decl);
27832744
2784 const node = try transCreateNodeInfixOp(c, scope, op, ref_node, Node.one_literal.init(), .used);
2745 const node = try transCreateNodeInfixOp(c, scope, op, ref_node, Tag.one_literal.init(), .used);
27852746 try block_scope.statements.append(node);
27862747
2787 const break_node = try Node.break_val.create(c.arena, .{
2748 const break_node = try Tag.break_val.create(c.arena, .{
27882749 .label = block_scope.label,
2789 .val = try Node.identifier.create(c.arena, tmp),
2750 .val = try Tag.identifier.create(c.arena, tmp),
27902751 });
27912752 try block_scope.statements.append(break_node);
27922753 return block_scope.complete(c);
......@@ -2795,26 +2756,26 @@ fn transCreatePostCrement(
27952756fn transCompoundAssignOperator(c: *Context, scope: *Scope, stmt: *const clang.CompoundAssignOperator, used: ResultUsed) TransError!Node {
27962757 switch (stmt.getOpcode()) {
27972758 .MulAssign => if (qualTypeHasWrappingOverflow(stmt.getType()))
2798 return transCreateCompoundAssign(c, scope, stmt, .assign_mul_wrap, used)
2759 return transCreateCompoundAssign(c, scope, stmt, .mul_wrap_assign, used)
27992760 else
2800 return transCreateCompoundAssign(c, scope, stmt, .assign_mul, used),
2761 return transCreateCompoundAssign(c, scope, stmt, .mul_assign, used),
28012762 .AddAssign => if (qualTypeHasWrappingOverflow(stmt.getType()))
2802 return transCreateCompoundAssign(c, scope, stmt, .assign_add_wrap, used)
2763 return transCreateCompoundAssign(c, scope, stmt, .add_wrap_assign, used)
28032764 else
2804 return transCreateCompoundAssign(c, scope, stmt, .assign_add, used),
2765 return transCreateCompoundAssign(c, scope, stmt, .add_assign, used),
28052766 .SubAssign => if (qualTypeHasWrappingOverflow(stmt.getType()))
2806 return transCreateCompoundAssign(c, scope, stmt, .assign_sub_wrap, used)
2767 return transCreateCompoundAssign(c, scope, stmt, .sub_wrap_assign, used)
28072768 else
2808 return transCreateCompoundAssign(c, scope, stmt, .assign_sub, used),
2809 .DivAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_div, used),
2810 .RemAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_mod, used),
2811 .ShlAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_shl, used),
2812 .ShrAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_shr, used),
2813 .AndAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_bit_and, used),
2814 .XorAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_bit_xor, used),
2815 .OrAssign => return transCreateCompoundAssign(c, scope, stmt, .assign_bit_or, used),
2769 return transCreateCompoundAssign(c, scope, stmt, .sub_assign, used),
2770 .DivAssign => return transCreateCompoundAssign(c, scope, stmt, .div_assign, used),
2771 .RemAssign => return transCreateCompoundAssign(c, scope, stmt, .mod_assign, used),
2772 .ShlAssign => return transCreateCompoundAssign(c, scope, stmt, .shl_assign, used),
2773 .ShrAssign => return transCreateCompoundAssign(c, scope, stmt, .shr_assign, used),
2774 .AndAssign => return transCreateCompoundAssign(c, scope, stmt, .bit_and_assign, used),
2775 .XorAssign => return transCreateCompoundAssign(c, scope, stmt, .bit_xor_assign, used),
2776 .OrAssign => return transCreateCompoundAssign(c, scope, stmt, .bit_or_assign, used),
28162777 else => return fail(
2817 rp,
2778 c,
28182779 error.UnsupportedTranslation,
28192780 stmt.getBeginLoc(),
28202781 "unsupported C translation {}",
......@@ -2827,12 +2788,12 @@ fn transCreateCompoundAssign(
28272788 c: *Context,
28282789 scope: *Scope,
28292790 stmt: *const clang.CompoundAssignOperator,
2830 op: Node.Tag,
2791 op: Tag,
28312792 used: ResultUsed,
28322793) TransError!Node {
2833 const is_shift = op == .assign_shl or op == .assign_shr;
2834 const is_div = op == .assign_div;
2835 const is_mod = op == .assign_mod;
2794 const is_shift = op == .shl_assign or op == .shr_assign;
2795 const is_div = op == .div_assign;
2796 const is_mod = op == .mod_assign;
28362797 const lhs = stmt.getLHS();
28372798 const rhs = stmt.getRHS();
28382799 const loc = stmt.getBeginLoc();
......@@ -2849,21 +2810,21 @@ fn transCreateCompoundAssign(
28492810 // c: lhs += rhs
28502811 // zig: lhs += rhs
28512812 if ((is_mod or is_div) and is_signed) {
2852 const lhs_node = try transExpr(c, scope, lhs, .used, .l_value);
2853 const rhs_node = try transExpr(c, scope, rhs, .used, .r_value);
2813 const lhs_node = try transExpr(c, scope, lhs, .used);
2814 const rhs_node = try transExpr(c, scope, rhs, .used);
28542815 const builtin = if (is_mod)
2855 try Node.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node })
2816 try Tag.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node })
28562817 else
2857 try Node.divTrunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node });
2818 try Tag.div_trunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node });
28582819
28592820 return transCreateNodeInfixOp(c, scope, .assign, lhs_node, builtin, .used);
28602821 }
28612822
2862 const lhs_node = try transExpr(c, scope, lhs, .used, .l_value);
2823 const lhs_node = try transExpr(c, scope, lhs, .used);
28632824 var rhs_node = if (is_shift or requires_int_cast)
2864 try transExprCoercing(c, scope, rhs, .used, .r_value)
2825 try transExprCoercing(c, scope, rhs, .used)
28652826 else
2866 try transExpr(c, scope, rhs, .used, .r_value);
2827 try transExpr(c, scope, rhs, .used);
28672828
28682829 if (is_shift or requires_int_cast) {
28692830 // @intCast(rhs)
......@@ -2871,11 +2832,11 @@ fn transCreateCompoundAssign(
28712832 try qualTypeToLog2IntRef(c, getExprQualType(c, rhs), loc)
28722833 else
28732834 try transQualType(c, getExprQualType(c, lhs), loc);
2874
2875 rhs_node = try Node.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node });
2835
2836 rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node });
28762837 }
28772838
2878 return transCreateNodeInfixOp(c, scope, assign_op, lhs_node, rhs_node, .used);
2839 return transCreateNodeInfixOp(c, scope, op, lhs_node, rhs_node, .used);
28792840 }
28802841 // worst case
28812842 // c: lhs += rhs
......@@ -2888,25 +2849,25 @@ fn transCreateCompoundAssign(
28882849 defer block_scope.deinit();
28892850 const ref = try block_scope.makeMangledName(c, "ref");
28902851
2891 const expr = try transExpr(c, scope, op_expr, .used, .r_value);
2892 const addr_of = try Node.address_of.create(c.arena, expr);
2893 const ref_decl = try Node.var_simple.create(c.arena, .{ .name = ref, .init = addr_of});
2852 const expr = try transExpr(c, scope, lhs, .used);
2853 const addr_of = try Tag.address_of.create(c.arena, expr);
2854 const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = ref, .init = addr_of });
28942855 try block_scope.statements.append(ref_decl);
28952856
2896 const lhs_node = try Node.identifier.create(c.arena, ref);
2897 const ref_node = try Node.deref.create(c.arena, lhs_node);
2857 const lhs_node = try Tag.identifier.create(c.arena, ref);
2858 const ref_node = try Tag.deref.create(c.arena, lhs_node);
28982859
28992860 if ((is_mod or is_div) and is_signed) {
2900 const rhs_node = try transExpr(c, scope, rhs, .used, .r_value);
2861 const rhs_node = try transExpr(c, scope, rhs, .used);
29012862 const builtin = if (is_mod)
2902 try Node.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node })
2863 try Tag.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node })
29032864 else
2904 try Node.divTrunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node });
2865 try Tag.div_trunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node });
29052866
29062867 const assign = try transCreateNodeInfixOp(c, scope, .assign, lhs_node, builtin, .used);
29072868 try block_scope.statements.append(assign);
29082869 } else {
2909 var rhs_node = try transExpr(c, scope, rhs, .used, .r_value);
2870 var rhs_node = try transExpr(c, scope, rhs, .used);
29102871
29112872 if (is_shift or requires_int_cast) {
29122873 // @intCast(rhs)
......@@ -2914,15 +2875,15 @@ fn transCreateCompoundAssign(
29142875 try qualTypeToLog2IntRef(c, getExprQualType(c, rhs), loc)
29152876 else
29162877 try transQualType(c, getExprQualType(c, lhs), loc);
2917
2918 rhs_node = try Node.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node });
2878
2879 rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node });
29192880 }
29202881
29212882 const assign = try transCreateNodeInfixOp(c, scope, op, ref_node, rhs_node, .used);
29222883 try block_scope.statements.append(assign);
29232884 }
29242885
2925 const break_node = try Node.break_val.create(c.arena, .{
2886 const break_node = try Tag.break_val.create(c.arena, .{
29262887 .label = block_scope.label,
29272888 .val = ref_node,
29282889 });
......@@ -2941,7 +2902,7 @@ fn transCPtrCast(
29412902 const child_type = ty.getPointeeType();
29422903 const src_ty = src_type.getTypePtr();
29432904 const src_child_type = src_ty.getPointeeType();
2944 const dst_type = try transType(c, ty, loc);
2905 const dst_type_node = try transType(c, ty, loc);
29452906
29462907 if ((src_child_type.isConstQualified() and
29472908 !child_type.isConstQualified()) or
......@@ -2949,8 +2910,8 @@ fn transCPtrCast(
29492910 !child_type.isVolatileQualified()))
29502911 {
29512912 // Casting away const or volatile requires us to use @intToPtr
2952 const ptr_to_int = try Node.ptr_to_int.create(c.arena, expr);
2953 const int_to_ptr = try Node.int_to_ptr.create(c.arena, .{ .lhs = dst_type, .rhs = ptr_to_int });
2913 const ptr_to_int = try Tag.ptr_to_int.create(c.arena, expr);
2914 const int_to_ptr = try Tag.int_to_ptr.create(c.arena, .{ .lhs = dst_type_node, .rhs = ptr_to_int });
29542915 return int_to_ptr;
29552916 } else {
29562917 // Implicit downcasting from higher to lower alignment values is forbidden,
......@@ -2963,17 +2924,17 @@ fn transCPtrCast(
29632924 expr
29642925 else blk: {
29652926 const child_type_node = try transQualType(c, child_type, loc);
2966 const alignof = try Node.alignof.create(c.arena, child_type_node);
2967 const align_cast = try Node.align_cast.create(c.arena, .{ .lhs = alignof, .rhs = expr });
2927 const alignof = try Tag.alignof.create(c.arena, child_type_node);
2928 const align_cast = try Tag.align_cast.create(c.arena, .{ .lhs = alignof, .rhs = expr });
29682929 break :blk align_cast;
29692930 };
2970 return Node.ptr_cast.create(c.arena, .{ .lhs = dst_type, .rhs = rhs });
2931 return Tag.ptr_cast.create(c.arena, .{ .lhs = dst_type_node, .rhs = rhs });
29712932 }
29722933}
29732934
29742935fn transBreak(c: *Context, scope: *Scope) TransError!Node {
29752936 const break_scope = scope.getBreakableScope();
2976 const label_text: ?[]const u8 = if (break_scope.id == .Switch) blk: {
2937 const label_text: ?[]const u8 = if (break_scope.id == .@"switch") blk: {
29772938 const swtch = @fieldParentPtr(Scope.Switch, "base", break_scope);
29782939 const block_scope = try scope.findBlockScope(c);
29792940 swtch.switch_label = try block_scope.makeMangledName(c, "switch");
......@@ -2981,20 +2942,20 @@ fn transBreak(c: *Context, scope: *Scope) TransError!Node {
29812942 } else
29822943 null;
29832944
2984 return Node.@"break".create(c.arena, label_text);
2945 return Tag.@"break".create(c.arena, label_text);
29852946}
29862947
29872948fn transFloatingLiteral(c: *Context, scope: *Scope, stmt: *const clang.FloatingLiteral, used: ResultUsed) TransError!Node {
29882949 // TODO use something more accurate
29892950 const dbl = stmt.getValueAsApproximateDouble();
29902951 const node = try transCreateNodeNumber(c, dbl);
2991 return maybeSuppressResult(c, scope, used, &node.base);
2952 return maybeSuppressResult(c, scope, used, node);
29922953}
29932954
29942955fn transBinaryConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang.BinaryConditionalOperator, used: ResultUsed) TransError!Node {
29952956 // GNU extension of the ternary operator where the middle expression is
29962957 // omitted, the conditition itself is returned if it evaluates to true
2997 const qt = @ptrCast(*const clang.Stmt, stmt).getType();
2958 const qt = @ptrCast(*const clang.Expr, stmt).getType();
29982959 const res_is_bool = qualTypeIsBoolean(qt);
29992960 const casted_stmt = @ptrCast(*const clang.AbstractConditionalOperator, stmt);
30002961 const cond_expr = casted_stmt.getCond();
......@@ -3010,26 +2971,33 @@ fn transBinaryConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang
30102971 defer block_scope.deinit();
30112972
30122973 const mangled_name = try block_scope.makeMangledName(c, "cond_temp");
3013 const init_node = try transExpr(c, &block_scope.base, cond_expr, .used, .r_value);
3014 const ref_decl = try Node.var_simple.create(c.arena, .{ .name = mangled_name, .init = init_node});
2974 const init_node = try transExpr(c, &block_scope.base, cond_expr, .used);
2975 const ref_decl = try Tag.var_simple.create(c.arena, .{ .name = mangled_name, .init = init_node });
30152976 try block_scope.statements.append(ref_decl);
30162977
2978 var cond_scope = Scope.Condition{
2979 .base = .{
2980 .parent = &block_scope.base,
2981 .id = .condition,
2982 },
2983 };
2984 defer cond_scope.deinit();
30172985 const cond_node = try transBoolExpr(c, &cond_scope.base, cond_expr, .used);
3018 var then_body = try Node.identifier.create(c.arena, mangled_name);
2986 var then_body = try Tag.identifier.create(c.arena, mangled_name);
30192987 if (!res_is_bool and isBoolRes(init_node)) {
3020 then_body = try Node.bool_to_int.create(c.arena, then_body);
2988 then_body = try Tag.bool_to_int.create(c.arena, then_body);
30212989 }
30222990
3023 var else_body = try transExpr(c, &block_scope.base, false_expr, .used, .r_value);
2991 var else_body = try transExpr(c, &block_scope.base, false_expr, .used);
30242992 if (!res_is_bool and isBoolRes(else_body)) {
3025 else_body = try Node.bool_to_int.create(c.arena, else_body);
2993 else_body = try Tag.bool_to_int.create(c.arena, else_body);
30262994 }
3027 const if_node = try Node.@"if".create(c.arena, .{
3028 .cond = cond,
2995 const if_node = try Tag.@"if".create(c.arena, .{
2996 .cond = cond_node,
30292997 .then = then_body,
30302998 .@"else" = else_body,
30312999 });
3032 const break_node = try Node.break_val.create(c.arena, .{
3000 const break_node = try Tag.break_val.create(c.arena, .{
30333001 .label = block_scope.label,
30343002 .val = if_node,
30353003 });
......@@ -3042,31 +3010,31 @@ fn transConditionalOperator(c: *Context, scope: *Scope, stmt: *const clang.Condi
30423010 var cond_scope = Scope.Condition{
30433011 .base = .{
30443012 .parent = scope,
3045 .id = .Condition,
3013 .id = .condition,
30463014 },
30473015 };
30483016 defer cond_scope.deinit();
30493017
3050 const qt = @ptrCast(*const clang.Stmt, stmt).getType();
3018 const qt = @ptrCast(*const clang.Expr, stmt).getType();
30513019 const res_is_bool = qualTypeIsBoolean(qt);
30523020 const casted_stmt = @ptrCast(*const clang.AbstractConditionalOperator, stmt);
30533021 const cond_expr = casted_stmt.getCond();
30543022 const true_expr = casted_stmt.getTrueExpr();
30553023 const false_expr = casted_stmt.getFalseExpr();
30563024
3057 const cond = try transBoolExpr(c, &cond_scope.base, cond_expr, .used, .r_value);
3025 const cond = try transBoolExpr(c, &cond_scope.base, cond_expr, .used);
30583026
3059 var then_body = try transExpr(c, scope, true_expr, .used, .r_value);
3027 var then_body = try transExpr(c, scope, true_expr, .used);
30603028 if (!res_is_bool and isBoolRes(then_body)) {
3061 then_body = try Node.bool_to_int.create(c.arena, then_body);
3029 then_body = try Tag.bool_to_int.create(c.arena, then_body);
30623030 }
30633031
3064 var else_body = try transExpr(c, scope, false_expr, .used, .r_value);
3032 var else_body = try transExpr(c, scope, false_expr, .used);
30653033 if (!res_is_bool and isBoolRes(else_body)) {
3066 else_body = try Node.bool_to_int.create(c.arena, else_body);
3034 else_body = try Tag.bool_to_int.create(c.arena, else_body);
30673035 }
30683036
3069 const if_node = try Node.@"if".create(c.arena, .{
3037 const if_node = try Tag.@"if".create(c.arena, .{
30703038 .cond = cond,
30713039 .then = then_body,
30723040 .@"else" = else_body,
......@@ -3081,7 +3049,7 @@ fn maybeSuppressResult(
30813049 result: Node,
30823050) TransError!Node {
30833051 if (used == .used) return result;
3084 return Node.ignore.create(c.arena, result);
3052 return Tag.ignore.create(c.arena, result);
30853053}
30863054
30873055fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: Node) !void {
......@@ -3100,19 +3068,19 @@ fn transQualTypeInitialized(
31003068 const ty = qt.getTypePtr();
31013069 if (ty.getTypeClass() == .IncompleteArray) {
31023070 const incomplete_array_ty = @ptrCast(*const clang.IncompleteArrayType, ty);
3103 const elem_ty = incomplete_array_ty.getElementType().getTypePtr();
3071 const elem_ty = try transType(c, incomplete_array_ty.getElementType().getTypePtr(), source_loc);
31043072
31053073 switch (decl_init.getStmtClass()) {
31063074 .StringLiteralClass => {
31073075 const string_lit = @ptrCast(*const clang.StringLiteral, decl_init);
31083076 const string_lit_size = string_lit.getLength() + 1; // +1 for null terminator
31093077 const array_size = @intCast(usize, string_lit_size);
3110 return Node.array_type.create(c.arena, .{ .len = array_size, .elem_type = elem_ty });
3078 return Tag.array_type.create(c.arena, .{ .len = array_size, .elem_type = elem_ty });
31113079 },
31123080 .InitListExprClass => {
31133081 const init_expr = @ptrCast(*const clang.InitListExpr, decl_init);
31143082 const size = init_expr.getNumInits();
3115 return Node.array_type.create(c.arena, .{ .len = size, .elem_type = elem_ty });
3083 return Tag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_ty });
31163084 },
31173085 else => {},
31183086 }
......@@ -3135,7 +3103,7 @@ fn transQualTypeIntWidthOf(c: *Context, ty: clang.QualType, is_signed: bool) Typ
31353103fn transTypeIntWidthOf(c: *Context, ty: *const clang.Type, is_signed: bool) TypeError!Node {
31363104 assert(ty.getTypeClass() == .Builtin);
31373105 const builtin_ty = @ptrCast(*const clang.BuiltinType, ty);
3138 return Node.type.create(c.arena, switch (builtin_ty.getKind()) {
3106 return Tag.type.create(c.arena, switch (builtin_ty.getKind()) {
31393107 .Char_U, .Char_S, .UChar, .SChar, .Char8 => if (is_signed) "i8" else "u8",
31403108 .UShort, .Short => if (is_signed) "c_short" else "c_ushort",
31413109 .UInt, .Int => if (is_signed) "c_int" else "c_uint",
......@@ -3214,11 +3182,11 @@ fn qualTypeToLog2IntRef(c: *Context, qt: clang.QualType, source_loc: clang.Sourc
32143182 if (int_bit_width != 0) {
32153183 // we can perform the log2 now.
32163184 const cast_bit_width = math.log2_int(u64, int_bit_width);
3217 return Node.log2_int_type.create(c.arena, cast_bit_width);
3185 return Tag.log2_int_type.create(c.arena, cast_bit_width);
32183186 }
32193187
32203188 const zig_type = try transQualType(c, qt, source_loc);
3221 return Node.std_math_Log2Int.create(c.arena, zig_type);
3189 return Tag.std_math_Log2Int.create(c.arena, zig_type);
32223190}
32233191
32243192fn qualTypeChildIsFnProto(qt: clang.QualType) bool {
......@@ -3392,10 +3360,10 @@ fn transCreateNodeAssign(
33923360 // c: lhs = rhs
33933361 // zig: lhs = rhs
33943362 if (result_used == .unused) {
3395 const lhs_node = try transExpr(c, scope, lhs, .used, .l_value);
3396 var rhs_node = try transExprCoercing(c, scope, rhs, .used, .r_value);
3363 const lhs_node = try transExpr(c, scope, lhs, .used);
3364 var rhs_node = try transExprCoercing(c, scope, rhs, .used);
33973365 if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {
3398 rhs_node = try Node.bool_to_int.create(c.arena, rhs_node);
3366 rhs_node = try Tag.bool_to_int.create(c.arena, rhs_node);
33993367 }
34003368 return transCreateNodeInfixOp(c, scope, .assign, lhs_node, rhs_node, .used);
34013369 }
......@@ -3411,17 +3379,16 @@ fn transCreateNodeAssign(
34113379 defer block_scope.deinit();
34123380
34133381 const tmp = try block_scope.makeMangledName(c, "tmp");
3414 const rhs = try transExpr(c, scope, op_expr, .used, .r_value);
3415 const tmp_decl = try Node.var_simple.create(c.arena, .{ .name = tmp, .init = rhs});
3382 const rhs_node = try transExpr(c, scope, rhs, .used);
3383 const tmp_decl = try Tag.var_simple.create(c.arena, .{ .name = tmp, .init = rhs_node });
34163384 try block_scope.statements.append(tmp_decl);
34173385
3418
3419 const lhs = try transExpr(c, &block_scope.base, lhs, .used, .l_value);
3420 const tmp_ident = try Node.identifier.create(c.arena, tmp);
3421 const assign = try transCreateNodeInfixOp(c, &block_scope.base, .assign, lhs, tmp_iden, .used);
3386 const lhs_node = try transExpr(c, &block_scope.base, lhs, .used);
3387 const tmp_ident = try Tag.identifier.create(c.arena, tmp);
3388 const assign = try transCreateNodeInfixOp(c, &block_scope.base, .assign, lhs_node, tmp_ident, .used);
34223389 try block_scope.statements.append(assign);
34233390
3424 const break_node = try Node.break_val.create(c.arena, .{
3391 const break_node = try Tag.break_val.create(c.arena, .{
34253392 .label = block_scope.label,
34263393 .val = tmp_ident,
34273394 });
......@@ -3432,7 +3399,7 @@ fn transCreateNodeAssign(
34323399fn transCreateNodeInfixOp(
34333400 c: *Context,
34343401 scope: *Scope,
3435 op: ast.Node.Tag,
3402 op: Tag,
34363403 lhs: Node,
34373404 rhs: Node,
34383405 used: ResultUsed,
......@@ -3452,13 +3419,13 @@ fn transCreateNodeBoolInfixOp(
34523419 c: *Context,
34533420 scope: *Scope,
34543421 stmt: *const clang.BinaryOperator,
3455 op: ast.Node.Tag,
3422 op: Tag,
34563423 used: ResultUsed,
34573424) !Node {
3458 std.debug.assert(op == .bool_and or op == .bool_or);
3425 std.debug.assert(op == .@"and" or op == .@"or");
34593426
3460 const lhs = try transBoolExpr(rp, scope, stmt.getLHS(), .used, .l_value);
3461 const rhs = try transBoolExpr(rp, scope, stmt.getRHS(), .used, .r_value);
3427 const lhs = try transBoolExpr(c, scope, stmt.getLHS(), .used);
3428 const rhs = try transBoolExpr(c, scope, stmt.getRHS(), .used);
34623429
34633430 return transCreateNodeInfixOp(c, scope, op, lhs, rhs, used);
34643431}
......@@ -3503,22 +3470,22 @@ fn transCreateNodeAPInt(c: *Context, int: *const clang.APSInt) !Node {
35033470 const str = big.toStringAlloc(c.arena, 10, false) catch |err| switch (err) {
35043471 error.OutOfMemory => return error.OutOfMemory,
35053472 };
3506 return Node.int_literal.create(c.arena, str);
3473 return Tag.number_literal.create(c.arena, str);
35073474}
35083475
35093476fn transCreateNodeNumber(c: *Context, int: anytype) !Node {
35103477 const fmt_s = if (comptime std.meta.trait.isNumber(@TypeOf(int))) "{d}" else "{s}";
35113478 const str = try std.fmt.allocPrint(c.arena, fmt_s, .{int});
3512 return Node.int_literal.create(c.arena, str);
3479 return Tag.number_literal.create(c.arena, str);
35133480}
35143481
35153482fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: Node, proto_alias: *ast.Payload.Func) !Node {
35163483 const scope = &c.global_scope.base;
35173484
3518 var fn_params = std.ArrayList(Node).init(c.gpa);
3485 var fn_params = std.ArrayList(ast.Payload.Param).init(c.gpa);
35193486 defer fn_params.deinit();
35203487
3521 for (proto_alias.params()) |param, i| {
3488 for (proto_alias.data.params) |param, i| {
35223489 const param_name = param.name orelse
35233490 try std.fmt.allocPrint(c.arena, "arg_{d}", .{c.getMangle()});
35243491
......@@ -3529,29 +3496,29 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: Node, proto_alias:
35293496 });
35303497 }
35313498
3532 const init = if (value.castTag(.var_decl)) |v|
3533 v.data.init
3534 else if (value.castTag(.var_simple) orelse value.castTag(.pub_var_simple)) |v|
3499 const init = if (ref.castTag(.var_decl)) |v|
3500 v.data.init.?
3501 else if (ref.castTag(.var_simple) orelse ref.castTag(.pub_var_simple)) |v|
35353502 v.data.init
35363503 else
35373504 unreachable;
35383505
3539 const unwrap_expr = try Node.unwrap.create(c.arena, init);
3540 const call_params = try c.arena.alloc(Node, fn_params.items.len);
3506 const unwrap_expr = try Tag.unwrap.create(c.arena, init);
3507 const args = try c.arena.alloc(Node, fn_params.items.len);
35413508 for (fn_params.items) |param, i| {
3542 call_params[i] = try Node.identifier.create(c.arena, param.name);
3509 args[i] = try Tag.identifier.create(c.arena, param.name.?);
35433510 }
3544 const call_expr = try Node.call.create(c.arean, .{
3511 const call_expr = try Tag.call.create(c.arena, .{
35453512 .lhs = unwrap_expr,
3546 .args = call_params,
3513 .args = args,
35473514 });
3548 const return_expr = try Node.@"return".create(c.arean, call_expr);
3549 const block = try Node.block_single.create(c.arean, return_expr);
3515 const return_expr = try Tag.@"return".create(c.arena, call_expr);
3516 const block = try Tag.block_single.create(c.arena, return_expr);
35503517
3551 return Node.pub_inline_fn.create(c.arena, .{
3518 return Tag.pub_inline_fn.create(c.arena, .{
35523519 .name = name,
3553 .params = try c.arena.dupe(ast.Node.Param, fn_params.items),
3554 .return_type = proto_alias.return_type,
3520 .params = try c.arena.dupe(ast.Payload.Param, fn_params.items),
3521 .return_type = proto_alias.data.return_type,
35553522 .body = block,
35563523 });
35573524}
......@@ -3560,7 +3527,7 @@ fn transCreateNodeShiftOp(
35603527 c: *Context,
35613528 scope: *Scope,
35623529 stmt: *const clang.BinaryOperator,
3563 op: Node.Tag,
3530 op: Tag,
35643531 used: ResultUsed,
35653532) !Node {
35663533 std.debug.assert(op == .shl or op == .shr);
......@@ -3570,11 +3537,11 @@ fn transCreateNodeShiftOp(
35703537 const rhs_location = rhs_expr.getBeginLoc();
35713538 // lhs >> @as(u5, rh)
35723539
3573 const lhs = try transExpr(c, scope, lhs_expr, .used, .l_value);
3540 const lhs = try transExpr(c, scope, lhs_expr, .used);
35743541
35753542 const rhs_type = try qualTypeToLog2IntRef(c, stmt.getType(), rhs_location);
3576 const rhs = try transExprCoercing(c, scope, rhs_expr, .used, .r_value);
3577 const rhs_casted = try Node.int_cast.create(c.arena, .{ .lhs = rhs_type, .rhs = rhs_type });
3543 const rhs = try transExprCoercing(c, scope, rhs_expr, .used);
3544 const rhs_casted = try Tag.int_cast.create(c.arena, .{ .lhs = rhs_type, .rhs = rhs_type });
35783545
35793546 return transCreateNodeInfixOp(c, scope, op, lhs, rhs_casted, used);
35803547}
......@@ -3583,7 +3550,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio
35833550 switch (ty.getTypeClass()) {
35843551 .Builtin => {
35853552 const builtin_ty = @ptrCast(*const clang.BuiltinType, ty);
3586 return Node.type.create(c.arena, switch (builtin_ty.getKind()) {
3553 return Tag.type.create(c.arena, switch (builtin_ty.getKind()) {
35873554 .Void => "c_void",
35883555 .Bool => "bool",
35893556 .Char_U, .UChar, .Char_S, .Char8 => "u8",
......@@ -3608,11 +3575,13 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio
36083575 },
36093576 .FunctionProto => {
36103577 const fn_proto_ty = @ptrCast(*const clang.FunctionProtoType, ty);
3611 return transFnProto(c, null, fn_proto_ty, source_loc, null, false);
3578 const fn_proto = try transFnProto(c, null, fn_proto_ty, source_loc, null, false);
3579 return Node.initPayload(&fn_proto.base);
36123580 },
36133581 .FunctionNoProto => {
36143582 const fn_no_proto_ty = @ptrCast(*const clang.FunctionType, ty);
3615 return transFnNoProto(c, fn_no_proto_ty, source_loc, null, false);
3583 const fn_proto = try transFnNoProto(c, fn_no_proto_ty, source_loc, null, false);
3584 return Node.initPayload(&fn_proto.base);
36163585 },
36173586 .Paren => {
36183587 const paren_ty = @ptrCast(*const clang.ParenType, ty);
......@@ -3621,16 +3590,16 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio
36213590 .Pointer => {
36223591 const child_qt = ty.getPointeeType();
36233592 if (qualTypeChildIsFnProto(child_qt)) {
3624 return Node.optional_type.create(c.arena, try transQualType(c, child_qt, source_loc));
3593 return Tag.optional_type.create(c.arena, try transQualType(c, child_qt, source_loc));
36253594 }
36263595 const is_const = child_qt.isConstQualified();
36273596 const is_volatile = child_qt.isVolatileQualified();
36283597 const elem_type = try transQualType(c, child_qt, source_loc);
3629 if (typeIsOpaque(rp.c, child_qt.getTypePtr(), source_loc) or qualTypeWasDemotedToOpaque(rp.c, child_qt)) {
3630 return Node.single_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
3598 if (typeIsOpaque(c, child_qt.getTypePtr(), source_loc) or qualTypeWasDemotedToOpaque(c, child_qt)) {
3599 return Tag.single_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
36313600 }
36323601
3633 return Node.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
3602 return Tag.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
36343603 },
36353604 .ConstantArray => {
36363605 const const_arr_ty = @ptrCast(*const clang.ConstantArrayType, ty);
......@@ -3639,7 +3608,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio
36393608 const size = size_ap_int.getLimitedValue(math.maxInt(usize));
36403609 const elem_type = try transType(c, const_arr_ty.getElementType().getTypePtr(), source_loc);
36413610
3642 return Node.array_type.create(c.arena, .{ .len = size, .elem_type = elem_type });
3611 return Tag.array_type.create(c.arena, .{ .len = size, .elem_type = elem_type });
36433612 },
36443613 .IncompleteArray => {
36453614 const incomplete_array_ty = @ptrCast(*const clang.IncompleteArrayType, ty);
......@@ -3649,7 +3618,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio
36493618 const is_volatile = child_qt.isVolatileQualified();
36503619 const elem_type = try transQualType(c, child_qt, source_loc);
36513620
3652 return Node.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
3621 return Tag.c_pointer.create(c.arena, .{ .is_const = is_const, .is_volatile = is_volatile, .elem_type = elem_type });
36533622 },
36543623 .Typedef => {
36553624 const typedef_ty = @ptrCast(*const clang.TypedefType, ty);
......@@ -3690,7 +3659,7 @@ fn transType(c: *Context, ty: *const clang.Type, source_loc: clang.SourceLocatio
36903659 },
36913660 else => {
36923661 const type_name = c.str(ty.getTypeClassName());
3693 return fail(c, error.UnsupportedType, source_loc, "unsupported type: '{}'", .{type_name});
3662 return fail(c, error.UnsupportedType, source_loc, "unsupported type: '{s}'", .{type_name});
36943663 },
36953664 }
36963665}
......@@ -3770,7 +3739,7 @@ fn transCC(
37703739 .AAPCS => return CallingConvention.AAPCS,
37713740 .AAPCS_VFP => return CallingConvention.AAPCSVFP,
37723741 else => return fail(
3773 rp,
3742 c,
37743743 error.UnsupportedType,
37753744 source_loc,
37763745 "unsupported calling convention: {s}",
......@@ -3786,7 +3755,7 @@ fn transFnProto(
37863755 source_loc: clang.SourceLocation,
37873756 fn_decl_context: ?FnDeclContext,
37883757 is_pub: bool,
3789) !Node.FnProto {
3758) !*ast.Payload.Func {
37903759 const fn_ty = @ptrCast(*const clang.FunctionType, fn_proto_ty);
37913760 const cc = try transCC(c, fn_ty, source_loc);
37923761 const is_var_args = fn_proto_ty.isVariadic();
......@@ -3799,7 +3768,7 @@ fn transFnNoProto(
37993768 source_loc: clang.SourceLocation,
38003769 fn_decl_context: ?FnDeclContext,
38013770 is_pub: bool,
3802) !Node.FnProto {
3771) !*ast.Payload.Func {
38033772 const cc = try transCC(c, fn_ty, source_loc);
38043773 const is_var_args = if (fn_decl_context) |ctx| (!ctx.is_export and ctx.storage_class != .Static) else true;
38053774 return finishTransFnProto(c, null, null, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub);
......@@ -3822,7 +3791,7 @@ fn finishTransFnProto(
38223791 // TODO check for always_inline attribute
38233792 // TODO check for align attribute
38243793
3825 var fn_params = std.ArrayList(ast.Payload.Func.Param).init(c.gpa);
3794 var fn_params = std.ArrayList(ast.Payload.Param).init(c.gpa);
38263795 defer fn_params.deinit();
38273796 const param_count: usize = if (fn_proto_ty != null) fn_proto_ty.?.getNumParams() else 0;
38283797 try fn_params.ensureCapacity(param_count);
......@@ -3861,7 +3830,7 @@ fn finishTransFnProto(
38613830 break :blk null;
38623831 };
38633832
3864 const alignment: c_uint = blk: {
3833 const alignment = blk: {
38653834 if (fn_decl) |decl| {
38663835 const alignment = decl.getAlignedAttribute(c.clang_context);
38673836 if (alignment != 0) {
......@@ -3876,16 +3845,16 @@ fn finishTransFnProto(
38763845
38773846 const return_type_node = blk: {
38783847 if (fn_ty.getNoReturnAttr()) {
3879 break :blk Node.noreturn_type.init();
3848 break :blk Tag.noreturn_type.init();
38803849 } else {
38813850 const return_qt = fn_ty.getReturnType();
38823851 if (isCVoid(return_qt)) {
38833852 // convert primitive c_void to actual void (only for return type)
3884 break :blk Node.void_type.init();
3853 break :blk Tag.void_type.init();
38853854 } else {
38863855 break :blk transQualType(c, return_qt, source_loc) catch |err| switch (err) {
38873856 error.UnsupportedType => {
3888 try warn(c, source_loc, "unsupported function proto return type", .{});
3857 try warn(c, &c.global_scope.base, source_loc, "unsupported function proto return type", .{});
38893858 return err;
38903859 },
38913860 error.OutOfMemory => |e| return e,
......@@ -3893,26 +3862,31 @@ fn finishTransFnProto(
38933862 }
38943863 }
38953864 };
3896
3897 return Node.func.create(c.arena, .{
3898 .is_pub = is_pub,
3899 .is_extern = is_extern,
3900 .is_export = is_export,
3901 .is_var_args = is_var_args,
3902 .name = name,
3903 .linksection_string = linksection_string,
3904 .explicit_callconv = explicit_callconv,
3905 .params = try c.arena.dupe(ast.Payload.Func.Param, fn_params.items),
3906 .return_type = return_node,
3907 .body = null,
3908 .alignment = alignment,
3909 });
3865 const name: ?[]const u8 = if (fn_decl_context) |ctx| ctx.fn_name else null;
3866 const payload = try c.arena.create(ast.Payload.Func);
3867 payload.* = .{
3868 .base = .{ .tag = .func },
3869 .data = .{
3870 .is_pub = is_pub,
3871 .is_extern = is_extern,
3872 .is_export = is_export,
3873 .is_var_args = is_var_args,
3874 .name = name,
3875 .linksection_string = linksection_string,
3876 .explicit_callconv = explicit_callconv,
3877 .params = try c.arena.dupe(ast.Payload.Param, fn_params.items),
3878 .return_type = return_type_node,
3879 .body = null,
3880 .alignment = alignment,
3881 },
3882 };
3883 return payload;
39103884}
39113885
39123886fn warn(c: *Context, scope: *Scope, loc: clang.SourceLocation, comptime format: []const u8, args: anytype) !void {
39133887 const args_prefix = .{c.locStr(loc)};
3914 const value = std.fmt.allocPrint(c.arena, "// {s}: warning: " ++ format, args_prefix ++ args);
3915 try scope.appendNode(c.gpa, try Node.warning.create(c.arena, value));
3888 const value = try std.fmt.allocPrint(c.arena, "// {s}: warning: " ++ format, args_prefix ++ args);
3889 try scope.appendNode(try Tag.warning.create(c.arena, value));
39163890}
39173891
39183892fn fail(
......@@ -3922,17 +3896,17 @@ fn fail(
39223896 comptime format: []const u8,
39233897 args: anytype,
39243898) (@TypeOf(err) || error{OutOfMemory}) {
3925 try warn(c, source_loc, format, args);
3899 try warn(c, &c.global_scope.base, source_loc, format, args);
39263900 return err;
39273901}
39283902
3929pub fn failDecl(c: *Context, loc: clang.SourceLocation, name: []const u8, comptime format: []const u8, args: anytype) !void {
3903pub fn failDecl(c: *Context, loc: clang.SourceLocation, name: []const u8, comptime format: []const u8, args: anytype) Error!void {
39303904 // location
39313905 // pub const name = @compileError(msg);
3932 const location_comment = std.fmt.allocPrint(c.arena, "// {s}", .{c.locStr(loc)});
3933 try c.global_scope.nodes.append(try Node.warning.create(c.arena, location_comment));
3934 const fail_msg = std.fmt.allocPrint(c.arena, format, args);
3935 try c.global_scope.nodes.append(try Node.fail_decl.create(c.arena, fail_msg));
3906 const location_comment = try std.fmt.allocPrint(c.arena, "// {s}", .{c.locStr(loc)});
3907 try c.global_scope.nodes.append(try Tag.warning.create(c.arena, location_comment));
3908 const fail_msg = try std.fmt.allocPrint(c.arena, format, args);
3909 try c.global_scope.nodes.append(try Tag.fail_decl.create(c.arena, fail_msg));
39363910}
39373911
39383912pub fn freeErrors(errors: []ClangErrMsg) void {
......@@ -4075,7 +4049,7 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void {
40754049 if (last != .Eof and last != .Nl)
40764050 return m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(last)});
40774051
4078 const var_decl = try Node.pub_var_simple.create(c.arena, .{ .name = m.name, .init = init_node });
4052 const var_decl = try Tag.pub_var_simple.create(c.arena, .{ .name = m.name, .init = init_node });
40794053 _ = try c.global_scope.macro_table.put(m.name, var_decl);
40804054}
40814055
......@@ -4099,7 +4073,7 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void {
40994073 try fn_params.append(.{
41004074 .is_noalias = false,
41014075 .name = mangled_name,
4102 .type = Node.@"anytype".init(),
4076 .type = Tag.@"anytype".init(),
41034077 });
41044078
41054079 if (m.peek().? != .Comma) break;
......@@ -4119,19 +4093,19 @@ fn transMacroFnDefine(c: *Context, m: *MacroCtx) ParseError!void {
41194093 const stmts = some.data.stmts;
41204094 const blk_last = stmts[stmts.len - 1];
41214095 const br = blk_last.castTag(.break_val).?;
4122 break :blk br.data;
4096 break :blk br.data.val;
41234097 } else expr;
4124 const typeof = try Node.typeof.create(c.arean, typeof_arg);
4125 const return_expr = try Node.@"return".create(c.arena, expr);
4126 try block_scope.statements.append(&return_expr.base);
4127
4128 const fn_decl = try Node.pub_inline_fn.create(c.arena, .{
4098 const typeof = try Tag.typeof.create(c.arena, typeof_arg);
4099 const return_expr = try Tag.@"return".create(c.arena, expr);
4100 try block_scope.statements.append(return_expr);
4101
4102 const fn_decl = try Tag.pub_inline_fn.create(c.arena, .{
41294103 .name = m.name,
41304104 .params = try c.arena.dupe(ast.Payload.Param, fn_params.items),
41314105 .return_type = typeof,
41324106 .body = try block_scope.complete(c),
41334107 });
4134 _ = try c.global_scope.macro_table.put(m.name, &fn_proto.base);
4108 _ = try c.global_scope.macro_table.put(m.name, fn_decl);
41354109}
41364110
41374111const ParseError = Error || error{ParseError};
......@@ -4149,7 +4123,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
41494123 var last = node;
41504124 while (true) {
41514125 // suppress result
4152 const ignore = try Node.ignore.create(c.arena, last);
4126 const ignore = try Tag.ignore.create(c.arena, last);
41534127 try block_scope.statements.append(ignore);
41544128
41554129 last = try parseCCondExpr(c, m, scope);
......@@ -4159,7 +4133,7 @@ fn parseCExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
41594133 }
41604134 }
41614135
4162 const break_node = try Node.break_val.create(c.arena, .{
4136 const break_node = try Tag.break_val.create(c.arena, .{
41634137 .label = block_scope.label,
41644138 .val = last,
41654139 });
......@@ -4190,7 +4164,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node {
41904164 return transCreateNodeNumber(c, lit_bytes);
41914165 }
41924166
4193 const type_node = try Node.type.create(c.arena, switch (suffix) {
4167 const type_node = try Tag.type.create(c.arena, switch (suffix) {
41944168 .u => "c_uint",
41954169 .l => "c_long",
41964170 .lu => "c_ulong",
......@@ -4205,7 +4179,7 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node {
42054179 else => unreachable,
42064180 }];
42074181 const rhs = try transCreateNodeNumber(c, lit_bytes);
4208 return Node.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs });
4182 return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs });
42094183 },
42104184 .FloatLiteral => |suffix| {
42114185 if (lit_bytes[0] == '.')
......@@ -4213,13 +4187,13 @@ fn parseCNumLit(c: *Context, m: *MacroCtx) ParseError!Node {
42134187 if (suffix == .none) {
42144188 return transCreateNodeNumber(c, lit_bytes);
42154189 }
4216 const type_node = try Node.type.create(c.arena, switch (suffix) {
4190 const type_node = try Tag.type.create(c.arena, switch (suffix) {
42174191 .f => "f32",
42184192 .l => "c_longdouble",
42194193 else => unreachable,
42204194 });
42214195 const rhs = try transCreateNodeNumber(c, lit_bytes[0 .. lit_bytes.len - 1]);
4222 return Node.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs });
4196 return Tag.as.create(c.arena, .{ .lhs = type_node, .rhs = rhs });
42234197 },
42244198 else => unreachable,
42254199 }
......@@ -4391,56 +4365,56 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
43914365 switch (tok) {
43924366 .CharLiteral => {
43934367 if (slice[0] != '\'' or slice[1] == '\\' or slice.len == 3) {
4394 return Node.char_literal.create(c.arena, try zigifyEscapeSequences(c, m));
4368 return Tag.char_literal.create(c.arena, try zigifyEscapeSequences(c, m));
43954369 } else {
43964370 const str = try std.fmt.allocPrint(c.arena, "0x{x}", .{slice[1 .. slice.len - 1]});
4397 return Node.int_literal.create(c.arena, str);
4371 return Tag.number_literal.create(c.arena, str);
43984372 }
43994373 },
44004374 .StringLiteral => {
4401 return Node.string_literal.create(c.arena, try zigifyEscapeSequences(c, m));
4375 return Tag.string_literal.create(c.arena, try zigifyEscapeSequences(c, m));
44024376 },
44034377 .IntegerLiteral, .FloatLiteral => {
44044378 return parseCNumLit(c, m);
44054379 },
44064380 // eventually this will be replaced by std.c.parse which will handle these correctly
4407 .Keyword_void => return Node.type.create(c.arena, "c_void"),
4408 .Keyword_bool => return Node.type.create(c.arena, "bool"),
4409 .Keyword_double => return Node.type.create(c.arena, "f64"),
4410 .Keyword_long => return Node.type.create(c.arena, "c_long"),
4411 .Keyword_int => return Node.type.create(c.arena, "c_int"),
4412 .Keyword_float => return Node.type.create(c.arena, "f32"),
4413 .Keyword_short => return Node.type.create(c.arena, "c_short"),
4414 .Keyword_char => return Node.type.create(c.arena, "u8"),
4381 .Keyword_void => return Tag.type.create(c.arena, "c_void"),
4382 .Keyword_bool => return Tag.type.create(c.arena, "bool"),
4383 .Keyword_double => return Tag.type.create(c.arena, "f64"),
4384 .Keyword_long => return Tag.type.create(c.arena, "c_long"),
4385 .Keyword_int => return Tag.type.create(c.arena, "c_int"),
4386 .Keyword_float => return Tag.type.create(c.arena, "f32"),
4387 .Keyword_short => return Tag.type.create(c.arena, "c_short"),
4388 .Keyword_char => return Tag.type.create(c.arena, "u8"),
44154389 .Keyword_unsigned => if (m.next()) |t| switch (t) {
4416 .Keyword_char => return Node.type.create(c.arena, "u8"),
4417 .Keyword_short => return Node.type.create(c.arena, "c_ushort"),
4418 .Keyword_int => return Node.type.create(c.arena, "c_uint"),
4390 .Keyword_char => return Tag.type.create(c.arena, "u8"),
4391 .Keyword_short => return Tag.type.create(c.arena, "c_ushort"),
4392 .Keyword_int => return Tag.type.create(c.arena, "c_uint"),
44194393 .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) {
44204394 _ = m.next();
4421 return Node.type.create(c.arena, "c_ulonglong");
4422 } else return Node.type.create(c.arena, "c_ulong"),
4395 return Tag.type.create(c.arena, "c_ulonglong");
4396 } else return Tag.type.create(c.arena, "c_ulong"),
44234397 else => {
44244398 m.i -= 1;
4425 return Node.type.create(c.arena, "c_uint");
4399 return Tag.type.create(c.arena, "c_uint");
44264400 },
44274401 } else {
4428 return Node.type.create(c.arena, "c_uint");
4402 return Tag.type.create(c.arena, "c_uint");
44294403 },
44304404 .Keyword_signed => if (m.next()) |t| switch (t) {
4431 .Keyword_char => return Node.type.create(c.arena, "i8"),
4432 .Keyword_short => return Node.type.create(c.arena, "c_short"),
4433 .Keyword_int => return Node.type.create(c.arena, "c_int"),
4405 .Keyword_char => return Tag.type.create(c.arena, "i8"),
4406 .Keyword_short => return Tag.type.create(c.arena, "c_short"),
4407 .Keyword_int => return Tag.type.create(c.arena, "c_int"),
44344408 .Keyword_long => if (m.peek() != null and m.peek().? == .Keyword_long) {
44354409 _ = m.next();
4436 return Node.type.create(c.arena, "c_longlong");
4437 } else return Node.type.create(c.arena, "c_long"),
4410 return Tag.type.create(c.arena, "c_longlong");
4411 } else return Tag.type.create(c.arena, "c_long"),
44384412 else => {
44394413 m.i -= 1;
4440 return Node.type.create(c.arena, "c_int");
4414 return Tag.type.create(c.arena, "c_int");
44414415 },
44424416 } else {
4443 return Node.type.create(c.arena, "c_int");
4417 return Tag.type.create(c.arena, "c_int");
44444418 },
44454419 .Keyword_enum, .Keyword_struct, .Keyword_union => {
44464420 // struct Foo will be declared as struct_Foo by transRecordDecl
......@@ -4451,11 +4425,11 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
44514425 }
44524426
44534427 const name = try std.fmt.allocPrint(c.arena, "{s}_{s}", .{ slice, m.slice() });
4454 return Node.identifier.create(c.arena, name);
4428 return Tag.identifier.create(c.arena, name);
44554429 },
44564430 .Identifier => {
44574431 const mangled_name = scope.getAlias(slice);
4458 return Node.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name);
4432 return Tag.identifier.create(c.arena, builtin_typedef_map.get(mangled_name) orelse mangled_name);
44594433 },
44604434 .LParen => {
44614435 const inner_node = try parseCExpr(c, m, scope);
......@@ -4492,7 +4466,7 @@ fn parseCPrimaryExprInner(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!N
44924466 return error.ParseError;
44934467 }
44944468
4495 return Node.std_meta_cast.create(c.arena, .{ .lhs = inner_node, .rhs = node_to_cast });
4469 return Tag.std_meta_cast.create(c.arena, .{ .lhs = inner_node, .rhs = node_to_cast });
44964470 },
44974471 else => {
44984472 try m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(tok)});
......@@ -4511,7 +4485,7 @@ fn parseCPrimaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
45114485 .StringLiteral, .Identifier => {},
45124486 else => break,
45134487 }
4514 node = try Node.array_cat.create(c.arena, .{ .lhs = node, .rhs = try parseCPrimaryExprInner(c, m, scope) });
4488 node = try Tag.array_cat.create(c.arena, .{ .lhs = node, .rhs = try parseCPrimaryExprInner(c, m, scope) });
45154489 }
45164490 return node;
45174491}
......@@ -4521,7 +4495,7 @@ fn macroBoolToInt(c: *Context, node: Node) !Node {
45214495 return node;
45224496 }
45234497
4524 return Node.bool_to_int.create(c.arena, node);
4498 return Tag.bool_to_int.create(c.arena, node);
45254499}
45264500
45274501fn macroIntToBool(c: *Context, node: Node) !Node {
......@@ -4529,7 +4503,7 @@ fn macroIntToBool(c: *Context, node: Node) !Node {
45294503 return node;
45304504 }
45314505
4532 return Node.not_equal.create(c.arena, .{ .lhs = node, .rhs = Node.zero_literal.init() });
4506 return Tag.not_equal.create(c.arena, .{ .lhs = node, .rhs = Tag.zero_literal.init() });
45334507}
45344508
45354509fn parseCCondExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
......@@ -4545,7 +4519,7 @@ fn parseCCondExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
45454519 return error.ParseError;
45464520 }
45474521 const else_body = try parseCCondExpr(c, m, scope);
4548 return Node.@"if".create(c.arena, .{ .cond = node, .then = then_body, .@"else" = else_body });
4522 return Tag.@"if".create(c.arena, .{ .cond = node, .then = then_body, .@"else" = else_body });
45494523}
45504524
45514525fn parseCOrExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
......@@ -4553,7 +4527,7 @@ fn parseCOrExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
45534527 while (m.next().? == .PipePipe) {
45544528 const lhs = try macroIntToBool(c, node);
45554529 const rhs = try macroIntToBool(c, try parseCAndExpr(c, m, scope));
4556 node = try Node.@"or".create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4530 node = try Tag.@"or".create(c.arena, .{ .lhs = lhs, .rhs = rhs });
45574531 }
45584532 m.i -= 1;
45594533 return node;
......@@ -4564,7 +4538,7 @@ fn parseCAndExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
45644538 while (m.next().? == .AmpersandAmpersand) {
45654539 const lhs = try macroIntToBool(c, node);
45664540 const rhs = try macroIntToBool(c, try parseCBitOrExpr(c, m, scope));
4567 node = try Node.@"and".create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4541 node = try Tag.@"and".create(c.arena, .{ .lhs = lhs, .rhs = rhs });
45684542 }
45694543 m.i -= 1;
45704544 return node;
......@@ -4575,7 +4549,7 @@ fn parseCBitOrExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
45754549 while (m.next().? == .Pipe) {
45764550 const lhs = try macroBoolToInt(c, node);
45774551 const rhs = try macroBoolToInt(c, try parseCBitXorExpr(c, m, scope));
4578 node = try Node.bit_or.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4552 node = try Tag.bit_or.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
45794553 }
45804554 m.i -= 1;
45814555 return node;
......@@ -4586,7 +4560,7 @@ fn parseCBitXorExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
45864560 while (m.next().? == .Caret) {
45874561 const lhs = try macroBoolToInt(c, node);
45884562 const rhs = try macroBoolToInt(c, try parseCBitAndExpr(c, m, scope));
4589 node = try Node.bit_xor.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4563 node = try Tag.bit_xor.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
45904564 }
45914565 m.i -= 1;
45924566 return node;
......@@ -4597,7 +4571,7 @@ fn parseCBitAndExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
45974571 while (m.next().? == .Ampersand) {
45984572 const lhs = try macroBoolToInt(c, node);
45994573 const rhs = try macroBoolToInt(c, try parseCEqExpr(c, m, scope));
4600 node = try Node.bit_and.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4574 node = try Tag.bit_and.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
46014575 }
46024576 m.i -= 1;
46034577 return node;
......@@ -4611,13 +4585,13 @@ fn parseCEqExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
46114585 _ = m.next();
46124586 const lhs = try macroBoolToInt(c, node);
46134587 const rhs = try macroBoolToInt(c, try parseCRelExpr(c, m, scope));
4614 node = try Node.not_equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4588 node = try Tag.not_equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
46154589 },
46164590 .EqualEqual => {
46174591 _ = m.next();
46184592 const lhs = try macroBoolToInt(c, node);
46194593 const rhs = try macroBoolToInt(c, try parseCRelExpr(c, m, scope));
4620 node = try Node.equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4594 node = try Tag.equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
46214595 },
46224596 else => return node,
46234597 }
......@@ -4632,25 +4606,25 @@ fn parseCRelExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
46324606 _ = m.next();
46334607 const lhs = try macroBoolToInt(c, node);
46344608 const rhs = try macroBoolToInt(c, try parseCShiftExpr(c, m, scope));
4635 node = try Node.greater_than.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4609 node = try Tag.greater_than.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
46364610 },
46374611 .AngleBracketRightEqual => {
46384612 _ = m.next();
46394613 const lhs = try macroBoolToInt(c, node);
46404614 const rhs = try macroBoolToInt(c, try parseCShiftExpr(c, m, scope));
4641 node = try Node.greater_than_equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4615 node = try Tag.greater_than_equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
46424616 },
46434617 .AngleBracketLeft => {
46444618 _ = m.next();
46454619 const lhs = try macroBoolToInt(c, node);
46464620 const rhs = try macroBoolToInt(c, try parseCShiftExpr(c, m, scope));
4647 node = try Node.less_than.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4621 node = try Tag.less_than.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
46484622 },
46494623 .AngleBracketLeftEqual => {
46504624 _ = m.next();
46514625 const lhs = try macroBoolToInt(c, node);
46524626 const rhs = try macroBoolToInt(c, try parseCShiftExpr(c, m, scope));
4653 node = try Node.less_than_equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4627 node = try Tag.less_than_equal.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
46544628 },
46554629 else => return node,
46564630 }
......@@ -4665,13 +4639,13 @@ fn parseCShiftExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
46654639 _ = m.next();
46664640 const lhs = try macroBoolToInt(c, node);
46674641 const rhs = try macroBoolToInt(c, try parseCAddSubExpr(c, m, scope));
4668 node = try Node.shl.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4642 node = try Tag.shl.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
46694643 },
46704644 .AngleBracketAngleBracketRight => {
46714645 _ = m.next();
46724646 const lhs = try macroBoolToInt(c, node);
46734647 const rhs = try macroBoolToInt(c, try parseCAddSubExpr(c, m, scope));
4674 node = try Node.shr.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4648 node = try Tag.shr.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
46754649 },
46764650 else => return node,
46774651 }
......@@ -4686,13 +4660,13 @@ fn parseCAddSubExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
46864660 _ = m.next();
46874661 const lhs = try macroBoolToInt(c, node);
46884662 const rhs = try macroBoolToInt(c, try parseCMulExpr(c, m, scope));
4689 node = try Node.add.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4663 node = try Tag.add.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
46904664 },
46914665 .Minus => {
46924666 _ = m.next();
46934667 const lhs = try macroBoolToInt(c, node);
46944668 const rhs = try macroBoolToInt(c, try parseCMulExpr(c, m, scope));
4695 node = try Node.sub.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4669 node = try Tag.sub.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
46964670 },
46974671 else => return node,
46984672 }
......@@ -4711,14 +4685,14 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
47114685 const prev_id = m.list[m.i - 1].id;
47124686
47134687 if (prev_id == .Keyword_void) {
4714 const ptr = try Node.single_pointer.create(c.arena, .{
4688 const ptr = try Tag.single_pointer.create(c.arena, .{
47154689 .is_const = false,
47164690 .is_volatile = false,
47174691 .elem_type = node,
47184692 });
4719 return Node.optional_type.create(c.arena, ptr);
4693 return Tag.optional_type.create(c.arena, ptr);
47204694 } else {
4721 return Node.c_pointer.create(c.arena, .{
4695 return Tag.c_pointer.create(c.arena, .{
47224696 .is_const = false,
47234697 .is_volatile = false,
47244698 .elem_type = node,
......@@ -4728,18 +4702,18 @@ fn parseCMulExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
47284702 // expr * expr
47294703 const lhs = try macroBoolToInt(c, node);
47304704 const rhs = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope));
4731 node = try Node.mul.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4705 node = try Tag.mul.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
47324706 }
47334707 },
47344708 .Slash => {
47354709 const lhs = try macroBoolToInt(c, node);
47364710 const rhs = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope));
4737 node = try Node.div.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4711 node = try Tag.div.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
47384712 },
47394713 .Percent => {
47404714 const lhs = try macroBoolToInt(c, node);
47414715 const rhs = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope));
4742 node = try Node.mod.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
4716 node = try Tag.mod.create(c.arena, .{ .lhs = lhs, .rhs = rhs });
47434717 },
47444718 else => {
47454719 m.i -= 1;
......@@ -4759,8 +4733,8 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
47594733 return error.ParseError;
47604734 }
47614735
4762 const ident = try Node.identifier.create(c.arena, m.slice());
4763 node = try Node.field_access.create(c.arena, .{ .lhs = node, .rhs = ident });
4736 const ident = try Tag.identifier.create(c.arena, m.slice());
4737 node = try Tag.field_access.create(c.arena, .{ .lhs = node, .rhs = ident });
47644738 },
47654739 .Arrow => {
47664740 if (m.next().? != .Identifier) {
......@@ -4768,20 +4742,20 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
47684742 return error.ParseError;
47694743 }
47704744
4771 const deref = try Node.deref.create(c.arena, node);
4772 const ident = try Node.identifier.create(c.arena, m.slice());
4773 node = try Node.field_access.create(c.arena, .{ .lhs = deref, .rhs = ident });
4745 const deref = try Tag.deref.create(c.arena, node);
4746 const ident = try Tag.identifier.create(c.arena, m.slice());
4747 node = try Tag.field_access.create(c.arena, .{ .lhs = deref, .rhs = ident });
47744748 },
47754749 .LBracket => {
47764750 const index = try macroBoolToInt(c, try parseCExpr(c, m, scope));
4777 node = try Node.array_access.create(c.arena, .{ .lhs = node, .rhs = index });
4751 node = try Tag.array_access.create(c.arena, .{ .lhs = node, .rhs = index });
47784752 },
47794753 .LParen => {
4780 var call_params = std.ArrayList(Node).init(c.gpa);
4781 defer call_params.deinit();
4754 var args = std.ArrayList(Node).init(c.gpa);
4755 defer args.deinit();
47824756 while (true) {
47834757 const arg = try parseCCondExpr(c, m, scope);
4784 try call_params.append(arg);
4758 try args.append(arg);
47854759 switch (m.next().?) {
47864760 .Comma => {},
47874761 .RParen => break,
......@@ -4791,7 +4765,7 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
47914765 },
47924766 }
47934767 }
4794 node = try Node.call.create(c.arena, .{ .lhs = node, .rhs = try c.arena.dupe(Node, call_params.items) });
4768 node = try Tag.call.create(c.arena, .{ .lhs = node, .args = try c.arena.dupe(Node, args.items) });
47954769 },
47964770 .LBrace => {
47974771 var init_vals = std.ArrayList(Node).init(c.gpa);
......@@ -4809,8 +4783,8 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
48094783 },
48104784 }
48114785 }
4812 const tuple_node = try Node.tuple.create(c.arena, try c.arena.dupe(Node, init_vals.items));
4813 node = try Node.std_mem_zeroinit.create(c.arena, .{ .lhs = node, .rhs = tuple_node });
4786 const tuple_node = try Tag.tuple.create(c.arena, try c.arena.dupe(Node, init_vals.items));
4787 node = try Tag.std_mem_zeroinit.create(c.arena, .{ .lhs = node, .rhs = tuple_node });
48144788 },
48154789 .PlusPlus, .MinusMinus => {
48164790 try m.fail(c, "TODO postfix inc/dec expr", .{});
......@@ -4828,24 +4802,24 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
48284802 switch (m.next().?) {
48294803 .Bang => {
48304804 const operand = try macroIntToBool(c, try parseCUnaryExpr(c, m, scope));
4831 return Node.not.create(c.arena, operand);
4805 return Tag.not.create(c.arena, operand);
48324806 },
48334807 .Minus => {
48344808 const operand = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope));
4835 return Node.negate.create(c.arena, operand);
4809 return Tag.negate.create(c.arena, operand);
48364810 },
48374811 .Plus => return try parseCUnaryExpr(c, m, scope),
48384812 .Tilde => {
48394813 const operand = try macroBoolToInt(c, try parseCUnaryExpr(c, m, scope));
4840 return Node.bit_not.create(c.arena, operand);
4814 return Tag.bit_not.create(c.arena, operand);
48414815 },
48424816 .Asterisk => {
48434817 const operand = try parseCUnaryExpr(c, m, scope);
4844 return Node.deref.create(c.arena, operand);
4818 return Tag.deref.create(c.arena, operand);
48454819 },
48464820 .Ampersand => {
48474821 const operand = try parseCUnaryExpr(c, m, scope);
4848 return Node.address_of.create(c.arena, operand);
4822 return Tag.address_of.create(c.arena, operand);
48494823 },
48504824 .Keyword_sizeof => {
48514825 const operand = if (m.peek().? == .LParen) blk: {
......@@ -4860,7 +4834,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
48604834 break :blk inner;
48614835 } else try parseCUnaryExpr(c, m, scope);
48624836
4863 return Node.std_meta_sizeof.create(c.arena, operand);
4837 return Tag.std_meta_sizeof.create(c.arena, operand);
48644838 },
48654839 .Keyword_alignof => {
48664840 // TODO this won't work if using <stdalign.h>'s
......@@ -4877,7 +4851,7 @@ fn parseCUnaryExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
48774851 return error.ParseError;
48784852 }
48794853
4880 return Node.alignof.create(c.arena, operand);
4854 return Tag.alignof.create(c.arena, operand);
48814855 },
48824856 .PlusPlus, .MinusMinus => {
48834857 try m.fail(c, "TODO unary inc/dec expr", .{});
......@@ -4902,7 +4876,7 @@ fn getContainer(c: *Context, node: Node) ?Node {
49024876 .negate,
49034877 .negate_wrap,
49044878 .array_type,
4905 .c_pointer,
4879 .c_pointer,
49064880 .single_pointer,
49074881 => return node,
49084882
......@@ -4910,7 +4884,7 @@ fn getContainer(c: *Context, node: Node) ?Node {
49104884 const ident = node.castTag(.identifier).?;
49114885 if (c.global_scope.sym_table.get(ident.data)) |value| {
49124886 if (value.castTag(.var_decl)) |var_decl|
4913 return getContainer(c, var_decl.data.init);
4887 return getContainer(c, var_decl.data.init.?);
49144888 if (value.castTag(.var_simple) orelse value.castTag(.pub_var_simple)) |var_decl|
49154889 return getContainer(c, var_decl.data.init);
49164890 }
......@@ -4923,8 +4897,8 @@ fn getContainer(c: *Context, node: Node) ?Node {
49234897 if (ty_node.castTag(.@"struct") orelse ty_node.castTag(.@"union")) |container| {
49244898 for (container.data.fields) |field| {
49254899 const ident = infix.data.rhs.castTag(.identifier).?;
4926 if (mem.eql(u8, field.data.name, field.data)) {
4927 return getContainer(c, field.type_expr.?);
4900 if (mem.eql(u8, field.name, ident.data)) {
4901 return getContainer(c, field.type);
49284902 }
49294903 }
49304904 }
......@@ -4960,9 +4934,9 @@ fn getContainerTypeOf(c: *Context, ref: Node) ?Node {
49604934}
49614935
49624936fn getFnProto(c: *Context, ref: Node) ?*ast.Payload.Func {
4963 const init = if (value.castTag(.var_decl)) |v|
4964 v.data.init
4965 else if (value.castTag(.var_simple) orelse value.castTag(.pub_var_simple)) |v|
4937 const init = if (ref.castTag(.var_decl)) |v|
4938 v.data.init orelse return null
4939 else if (ref.castTag(.var_simple) orelse ref.castTag(.pub_var_simple)) |v|
49664940 v.data.init
49674941 else
49684942 return null;
src/translate_c/ast.zig+61-47
......@@ -1,5 +1,6 @@
11const std = @import("std");
22const Type = @import("../type.zig").Type;
3const Allocator = std.mem.Allocator;
34
45pub const Node = extern union {
56 /// If the tag value is less than Tag.no_payload_count, then no pointer
......@@ -20,6 +21,8 @@ pub const Node = extern union {
2021 one_literal,
2122 void_type,
2223 noreturn_type,
24 @"anytype",
25 @"continue",
2326 /// pub usingnamespace @import("std").c.builtins;
2427 usingnamespace_builtins,
2528 // After this, the tag requires a payload.
......@@ -40,7 +43,6 @@ pub const Node = extern union {
4043 switch_else,
4144 /// lhs => rhs,
4245 switch_prong,
43 @"continue",
4446 @"break",
4547 break_val,
4648 @"return",
......@@ -60,7 +62,6 @@ pub const Node = extern union {
6062 container_init,
6163 std_meta_cast,
6264 discard,
63 block,
6465
6566 // a + b
6667 add,
......@@ -111,8 +112,11 @@ pub const Node = extern union {
111112 equal,
112113 not_equal,
113114 bit_and,
115 bit_and_assign,
114116 bit_or,
117 bit_or_assign,
115118 bit_xor,
119 bit_xor_assign,
116120 array_cat,
117121 ellipsis3,
118122 assign,
......@@ -126,7 +130,7 @@ pub const Node = extern union {
126130 rem,
127131 /// @divTrunc(lhs, rhs)
128132 div_trunc,
129 /// @boolToInt(lhs, rhs)
133 /// @boolToInt(operand)
130134 bool_to_int,
131135 /// @as(lhs, rhs)
132136 as,
......@@ -150,24 +154,26 @@ pub const Node = extern union {
150154 ptr_to_int,
151155 /// @alignCast(lhs, rhs)
152156 align_cast,
157 /// @ptrCast(lhs, rhs)
158 ptr_cast,
153159
154160 negate,
155161 negate_wrap,
156162 bit_not,
157163 not,
158164 address_of,
159 /// operand.?.*
160 unwrap_deref,
165 /// .?
166 unwrap,
161167 /// .*
162168 deref,
163169
164170 block,
165171 /// { operand }
166172 block_single,
167 @"break",
168173
169174 sizeof,
170175 alignof,
176 typeof,
171177 type,
172178
173179 optional_type,
......@@ -185,6 +191,8 @@ pub const Node = extern union {
185191 fail_decl,
186192 // var actual = mangled;
187193 arg_redecl,
194 /// pub const alias = actual;
195 alias,
188196 /// const name = init;
189197 typedef,
190198 var_simple,
......@@ -204,18 +212,17 @@ pub const Node = extern union {
204212
205213 /// _ = operand;
206214 ignore,
207 @"anytype",
208215
209216 pub const last_no_payload_tag = Tag.usingnamespace_builtins;
210217 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
211218
212 pub fn Type(tag: Tag) ?type {
213 return switch (tag) {
219 pub fn Type(comptime t: Tag) type {
220 return switch (t) {
214221 .null_literal,
215222 .undefined_literal,
216223 .opaque_literal,
217224 .true_literal,
218 .false_litral,
225 .false_literal,
219226 .empty_block,
220227 .usingnamespace_builtins,
221228 .return_void,
......@@ -224,6 +231,7 @@ pub const Node = extern union {
224231 .void_type,
225232 .noreturn_type,
226233 .@"anytype",
234 .@"continue",
227235 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
228236
229237 .std_mem_zeroes,
......@@ -236,7 +244,7 @@ pub const Node = extern union {
236244 .not,
237245 .optional_type,
238246 .address_of,
239 .unwrap_deref,
247 .unwrap,
240248 .deref,
241249 .ptr_to_int,
242250 .enum_to_int,
......@@ -246,6 +254,11 @@ pub const Node = extern union {
246254 .switch_else,
247255 .ignore,
248256 .block_single,
257 .std_meta_sizeof,
258 .bool_to_int,
259 .sizeof,
260 .alignof,
261 .typeof,
249262 => Payload.UnOp,
250263
251264 .add,
......@@ -294,12 +307,14 @@ pub const Node = extern union {
294307 .equal,
295308 .not_equal,
296309 .bit_and,
310 .bit_and_assign,
297311 .bit_or,
312 .bit_or_assign,
298313 .bit_xor,
314 .bit_xor_assign,
299315 .div_trunc,
300316 .rem,
301317 .int_cast,
302 .bool_to_int,
303318 .as,
304319 .truncate,
305320 .bit_cast,
......@@ -316,6 +331,7 @@ pub const Node = extern union {
316331 .align_cast,
317332 .array_access,
318333 .std_mem_zeroinit,
334 .ptr_cast,
319335 => Payload.BinOp,
320336
321337 .number_literal,
......@@ -324,8 +340,6 @@ pub const Node = extern union {
324340 .identifier,
325341 .warning,
326342 .failed_decl,
327 .sizeof,
328 .alignof,
329343 .type,
330344 .fail_decl,
331345 => Payload.Value,
......@@ -345,7 +359,7 @@ pub const Node = extern union {
345359 .block => Payload.Block,
346360 .c_pointer, .single_pointer => Payload.Pointer,
347361 .array_type => Payload.Array,
348 .arg_redecl => Payload.ArgRedecl,
362 .arg_redecl, .alias => Payload.ArgRedecl,
349363 .log2_int_type => Payload.Log2IntType,
350364 .typedef, .pub_typedef, .var_simple, .pub_var_simple => Payload.SimpleVarDecl,
351365 .enum_redecl => Payload.EnumRedecl,
......@@ -375,7 +389,7 @@ pub const Node = extern union {
375389
376390 pub fn tag(self: Node) Tag {
377391 if (self.tag_if_small_enough < Tag.no_payload_count) {
378 return @intToEnum(Tag, @intCast(@TagType(Tag), self.tag_if_small_enough));
392 return @intToEnum(Tag, @intCast(std.meta.Tag(Tag), self.tag_if_small_enough));
379393 } else {
380394 return self.ptr_otherwise.tag;
381395 }
......@@ -392,16 +406,16 @@ pub const Node = extern union {
392406 }
393407
394408 pub fn initPayload(payload: *Payload) Node {
395 assert(@enumToInt(payload.tag) >= Tag.no_payload_count);
409 std.debug.assert(@enumToInt(payload.tag) >= Tag.no_payload_count);
396410 return .{ .ptr_otherwise = payload };
397411 }
398412};
399413
400414pub const Payload = struct {
401 tag: Tag,
415 tag: Node.Tag,
402416
403417 pub const Infix = struct {
404 base: Node,
418 base: Payload,
405419 data: struct {
406420 lhs: Node,
407421 rhs: Node,
......@@ -409,17 +423,17 @@ pub const Payload = struct {
409423 };
410424
411425 pub const Value = struct {
412 base: Node,
426 base: Payload,
413427 data: []const u8,
414428 };
415429
416430 pub const UnOp = struct {
417 base: Node,
431 base: Payload,
418432 data: Node,
419433 };
420434
421435 pub const BinOp = struct {
422 base: Node,
436 base: Payload,
423437 data: struct {
424438 lhs: Node,
425439 rhs: Node,
......@@ -427,7 +441,7 @@ pub const Payload = struct {
427441 };
428442
429443 pub const If = struct {
430 base: Node = .{ .tag = .@"if" },
444 base: Payload,
431445 data: struct {
432446 cond: Node,
433447 then: Node,
......@@ -436,7 +450,7 @@ pub const Payload = struct {
436450 };
437451
438452 pub const While = struct {
439 base: Node = .{ .tag = .@"while" },
453 base: Payload,
440454 data: struct {
441455 cond: Node,
442456 body: Node,
......@@ -445,7 +459,7 @@ pub const Payload = struct {
445459 };
446460
447461 pub const Switch = struct {
448 base: Node = .{ .tag = .@"switch" },
462 base: Payload,
449463 data: struct {
450464 cond: Node,
451465 cases: []Node,
......@@ -453,12 +467,12 @@ pub const Payload = struct {
453467 };
454468
455469 pub const Break = struct {
456 base: Node = .{ .tag = .@"break" },
470 base: Payload,
457471 data: ?[]const u8,
458472 };
459473
460474 pub const BreakVal = struct {
461 base: Node = .{ .tag = .break_val },
475 base: Payload,
462476 data: struct {
463477 label: ?[]const u8,
464478 val: Node,
......@@ -466,7 +480,7 @@ pub const Payload = struct {
466480 };
467481
468482 pub const Call = struct {
469 base: Node = .{.call},
483 base: Payload,
470484 data: struct {
471485 lhs: Node,
472486 args: []Node,
......@@ -474,7 +488,7 @@ pub const Payload = struct {
474488 };
475489
476490 pub const VarDecl = struct {
477 base: Node = .{ .tag = .var_decl },
491 base: Payload,
478492 data: struct {
479493 is_pub: bool,
480494 is_const: bool,
......@@ -489,13 +503,13 @@ pub const Payload = struct {
489503 };
490504
491505 pub const Func = struct {
492 base: Node = .{.func},
506 base: Payload,
493507 data: struct {
494508 is_pub: bool,
495509 is_extern: bool,
496510 is_export: bool,
497511 is_var_args: bool,
498 name: []const u8,
512 name: ?[]const u8,
499513 linksection_string: ?[]const u8,
500514 explicit_callconv: ?std.builtin.CallingConvention,
501515 params: []Param,
......@@ -512,7 +526,7 @@ pub const Payload = struct {
512526 };
513527
514528 pub const Enum = struct {
515 base: Node = .{ .tag = .@"enum" },
529 base: Payload,
516530 data: []Field,
517531
518532 pub const Field = struct {
......@@ -522,9 +536,9 @@ pub const Payload = struct {
522536 };
523537
524538 pub const Record = struct {
525 base: Node,
539 base: Payload,
526540 data: struct {
527 @"packed": bool,
541 is_packed: bool,
528542 fields: []Field,
529543 },
530544
......@@ -536,12 +550,12 @@ pub const Payload = struct {
536550 };
537551
538552 pub const ArrayInit = struct {
539 base: Node = .{ .tag = .array_init },
553 base: Payload,
540554 data: []Node,
541555 };
542556
543557 pub const ContainerInit = struct {
544 base: Node = .{ .tag = .container_init },
558 base: Payload,
545559 data: []Initializer,
546560
547561 pub const Initializer = struct {
......@@ -551,7 +565,7 @@ pub const Payload = struct {
551565 };
552566
553567 pub const Block = struct {
554 base: Node,
568 base: Payload,
555569 data: struct {
556570 label: ?[]const u8,
557571 stmts: []Node
......@@ -559,15 +573,15 @@ pub const Payload = struct {
559573 };
560574
561575 pub const Array = struct {
562 base: Node,
576 base: Payload,
563577 data: struct {
564578 elem_type: Node,
565 len: Node,
579 len: usize,
566580 },
567581 };
568582
569583 pub const Pointer = struct {
570 base: Node,
584 base: Payload,
571585 data: struct {
572586 elem_type: Node,
573587 is_const: bool,
......@@ -576,7 +590,7 @@ pub const Payload = struct {
576590 };
577591
578592 pub const ArgRedecl = struct {
579 base: Node,
593 base: Payload,
580594 data: struct {
581595 actual: []const u8,
582596 mangled: []const u8,
......@@ -584,12 +598,12 @@ pub const Payload = struct {
584598 };
585599
586600 pub const Log2IntType = struct {
587 base: Node,
601 base: Payload,
588602 data: std.math.Log2Int(u64),
589603 };
590604
591605 pub const SimpleVarDecl = struct {
592 base: Node,
606 base: Payload,
593607 data: struct {
594608 name: []const u8,
595609 init: Node,
......@@ -597,7 +611,7 @@ pub const Payload = struct {
597611 };
598612
599613 pub const EnumRedecl = struct {
600 base: Node,
614 base: Payload,
601615 data: struct {
602616 enum_val_name: []const u8,
603617 field_name: []const u8,
......@@ -606,7 +620,7 @@ pub const Payload = struct {
606620 };
607621
608622 pub const ArrayFiller = struct {
609 base: Node,
623 base: Payload,
610624 data: struct {
611625 type: Node,
612626 filler: Node,
......@@ -615,7 +629,7 @@ pub const Payload = struct {
615629 };
616630
617631 pub const PubInlineFn = struct {
618 base: Node,
632 base: Payload,
619633 data: struct {
620634 name: []const u8,
621635 params: []Param,
......@@ -626,6 +640,6 @@ pub const Payload = struct {
626640};
627641
628642/// Converts the nodes into a Zig ast.
629pub fn render(allocator: *Allocator, nodes: []const Node) !*ast.Tree {
643pub fn render(allocator: *Allocator, nodes: []const Node) !std.zig.ast.Tree {
630644 @panic("TODO");
631645}
src/type.zig+4
......@@ -1682,6 +1682,8 @@ pub const Type = extern union {
16821682 .i32 => unreachable,
16831683 .u64 => unreachable,
16841684 .i64 => unreachable,
1685 .u128 => unreachable,
1686 .i128 => unreachable,
16851687 .usize => unreachable,
16861688 .isize => unreachable,
16871689 .c_short => unreachable,
......@@ -2197,6 +2199,8 @@ pub const Type = extern union {
21972199 .i32 => .{ .signedness = .signed, .bits = 32 },
21982200 .u64 => .{ .signedness = .unsigned, .bits = 64 },
21992201 .i64 => .{ .signedness = .signed, .bits = 64 },
2202 .u128 => .{ .signedness = .unsigned, .bits = 128 },
2203 .i128 => .{ .signedness = .signed, .bits = 128 },
22002204 .usize => .{ .signedness = .unsigned, .bits = target.cpu.arch.ptrBitWidth() },
22012205 .isize => .{ .signedness = .signed, .bits = target.cpu.arch.ptrBitWidth() },
22022206 .c_short => .{ .signedness = .signed, .bits = CType.short.sizeInBits(target) },