authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-23 12:48:17-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-23 12:48:17-04:00
loge072692e1ffb6012d3d75051996bfcbbbd80e093
treeb8a7767b0e8238c5f0d7614b1c67462e1007c6dc
parent8df0841d6ab964e2aec750a8ceeda51912ae448b

update translate-c to new AST API


2 files changed, 527 insertions(+), 466 deletions(-)

src-self-hosted/clang.zig+6-7
...@@ -63,7 +63,7 @@ pub const struct_ZigClangReturnStmt = @Type(.Opaque);...@@ -63,7 +63,7 @@ pub const struct_ZigClangReturnStmt = @Type(.Opaque);
63pub const struct_ZigClangSkipFunctionBodiesScope = @Type(.Opaque);63pub const struct_ZigClangSkipFunctionBodiesScope = @Type(.Opaque);
64pub const struct_ZigClangSourceManager = @Type(.Opaque);64pub const struct_ZigClangSourceManager = @Type(.Opaque);
65pub const struct_ZigClangSourceRange = @Type(.Opaque);65pub const struct_ZigClangSourceRange = @Type(.Opaque);
66pub const struct_ZigClangStmt = @Type(.Opaque);66pub const ZigClangStmt = @Type(.Opaque);
67pub const struct_ZigClangStringLiteral = @Type(.Opaque);67pub const struct_ZigClangStringLiteral = @Type(.Opaque);
68pub const struct_ZigClangStringRef = @Type(.Opaque);68pub const struct_ZigClangStringRef = @Type(.Opaque);
69pub const struct_ZigClangSwitchStmt = @Type(.Opaque);69pub const struct_ZigClangSwitchStmt = @Type(.Opaque);
...@@ -842,9 +842,9 @@ pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*...@@ -842,9 +842,9 @@ pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*
842pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType;842pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType;
843pub extern fn ZigClangType_getAsRecordType(self: *const ZigClangType) ?*const ZigClangRecordType;843pub extern fn ZigClangType_getAsRecordType(self: *const ZigClangType) ?*const ZigClangRecordType;
844pub extern fn ZigClangType_getAsUnionType(self: *const ZigClangType) ?*const ZigClangRecordType;844pub extern fn ZigClangType_getAsUnionType(self: *const ZigClangType) ?*const ZigClangRecordType;
845pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;845pub extern fn ZigClangStmt_getBeginLoc(self: *const ZigClangStmt) struct_ZigClangSourceLocation;
846pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;846pub extern fn ZigClangStmt_getStmtClass(self: ?*const ZigClangStmt) ZigClangStmtClass;
847pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;847pub extern fn ZigClangStmt_classof_Expr(self: ?*const ZigClangStmt) bool;
848pub extern fn ZigClangExpr_getStmtClass(self: *const struct_ZigClangExpr) ZigClangStmtClass;848pub extern fn ZigClangExpr_getStmtClass(self: *const struct_ZigClangExpr) ZigClangStmtClass;
849pub extern fn ZigClangExpr_getType(self: *const struct_ZigClangExpr) struct_ZigClangQualType;849pub extern fn ZigClangExpr_getType(self: *const struct_ZigClangExpr) struct_ZigClangQualType;
850pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;850pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;
...@@ -873,7 +873,7 @@ pub extern fn ZigClangFunctionDecl_getLocation(self: *const ZigClangFunctionDecl...@@ -873,7 +873,7 @@ pub extern fn ZigClangFunctionDecl_getLocation(self: *const ZigClangFunctionDecl
873pub extern fn ZigClangFunctionDecl_hasBody(self: *const ZigClangFunctionDecl) bool;873pub extern fn ZigClangFunctionDecl_hasBody(self: *const ZigClangFunctionDecl) bool;
874pub extern fn ZigClangFunctionDecl_getStorageClass(self: *const ZigClangFunctionDecl) ZigClangStorageClass;874pub extern fn ZigClangFunctionDecl_getStorageClass(self: *const ZigClangFunctionDecl) ZigClangStorageClass;
875pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const ZigClangFunctionDecl, i: c_uint) *const struct_ZigClangParmVarDecl;875pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const ZigClangFunctionDecl, i: c_uint) *const struct_ZigClangParmVarDecl;
876pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const struct_ZigClangStmt;876pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const ZigClangStmt;
877pub extern fn ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(self: *const ZigClangFunctionDecl) bool;877pub extern fn ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(self: *const ZigClangFunctionDecl) bool;
878pub extern fn ZigClangFunctionDecl_isThisDeclarationADefinition(self: *const ZigClangFunctionDecl) bool;878pub extern fn ZigClangFunctionDecl_isThisDeclarationADefinition(self: *const ZigClangFunctionDecl) bool;
879pub extern fn ZigClangFunctionDecl_doesThisDeclarationHaveABody(self: *const ZigClangFunctionDecl) bool;879pub extern fn ZigClangFunctionDecl_doesThisDeclarationHaveABody(self: *const ZigClangFunctionDecl) bool;
...@@ -959,7 +959,6 @@ pub const ZigClangReturnStmt = struct_ZigClangReturnStmt;...@@ -959,7 +959,6 @@ pub const ZigClangReturnStmt = struct_ZigClangReturnStmt;
959pub const ZigClangSkipFunctionBodiesScope = struct_ZigClangSkipFunctionBodiesScope;959pub const ZigClangSkipFunctionBodiesScope = struct_ZigClangSkipFunctionBodiesScope;
960pub const ZigClangSourceManager = struct_ZigClangSourceManager;960pub const ZigClangSourceManager = struct_ZigClangSourceManager;
961pub const ZigClangSourceRange = struct_ZigClangSourceRange;961pub const ZigClangSourceRange = struct_ZigClangSourceRange;
962pub const ZigClangStmt = struct_ZigClangStmt;
963pub const ZigClangStringLiteral = struct_ZigClangStringLiteral;962pub const ZigClangStringLiteral = struct_ZigClangStringLiteral;
964pub const ZigClangStringRef = struct_ZigClangStringRef;963pub const ZigClangStringRef = struct_ZigClangStringRef;
965pub const ZigClangSwitchStmt = struct_ZigClangSwitchStmt;964pub const ZigClangSwitchStmt = struct_ZigClangSwitchStmt;
...@@ -1018,7 +1017,7 @@ pub extern fn ZigClangLoadFromCommandLine(...@@ -1018,7 +1017,7 @@ pub extern fn ZigClangLoadFromCommandLine(
1018pub extern fn ZigClangDecl_getKind(decl: *const ZigClangDecl) ZigClangDeclKind;1017pub extern fn ZigClangDecl_getKind(decl: *const ZigClangDecl) ZigClangDeclKind;
1019pub extern fn ZigClangDecl_getDeclKindName(decl: *const struct_ZigClangDecl) [*:0]const u8;1018pub extern fn ZigClangDecl_getDeclKindName(decl: *const struct_ZigClangDecl) [*:0]const u8;
10201019
1021pub const ZigClangCompoundStmt_const_body_iterator = [*]const *struct_ZigClangStmt;1020pub const ZigClangCompoundStmt_const_body_iterator = [*]const *ZigClangStmt;
10221021
1023pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;1022pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
1024pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;1023pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
src-self-hosted/translate_c.zig+521-459
...@@ -54,44 +54,79 @@ const Scope = struct {...@@ -54,44 +54,79 @@ const Scope = struct {
54 Loop,54 Loop,
55 };55 };
5656
57 /// Represents an in-progress ast.Node.Switch. This struct is stack-allocated.
58 /// When it is deinitialized, it produces an ast.Node.Switch which is allocated
59 /// into the main arena.
57 const Switch = struct {60 const Switch = struct {
58 base: Scope,61 base: Scope,
59 pending_block: *ast.Node.Block,62 pending_block: *Block,
60 cases: *ast.Node.Switch.CaseList,63 cases: []*ast.Node,
64 case_index: usize,
61 has_default: bool = false,65 has_default: bool = false,
62 };66 };
6367
68 /// Used for the scope of condition expressions, for example `if (cond)`.
69 /// The block is lazily initialised because it is only needed for rare
70 /// cases of comma operators being used.
71 const Condition = struct {
72 base: Scope,
73 block: ?Block = null,
74
75 fn getBlockScope(self: *Condition, c: *Context) !*Block {
76 if (self.block) |*b| return b;
77 self.block = try Block.init(c, &self.base, "blk");
78 return &self.block.?;
79 }
80
81 fn deinit(self: *Condition) void {
82 if (self.block) |*b| b.deinit();
83 }
84 };
85
86 /// Represents an in-progress ast.Node.Block. This struct is stack-allocated.
87 /// When it is deinitialized, it produces an ast.Node.Block which is allocated
88 /// into the main arena.
64 const Block = struct {89 const Block = struct {
65 base: Scope,90 base: Scope,
66 block_node: *ast.Node.Block,91 statements: std.ArrayList(*ast.Node),
67 statements_it: *?*std.SinglyLinkedList(*ast.Node),
68 variables: AliasList,92 variables: AliasList,
69 label: ?[]const u8,93 label: ?ast.TokenIndex,
70 mangle_count: u32 = 0,94 mangle_count: u32 = 0,
95 lbrace: ast.TokenIndex,
7196
72 /// Don't forget to set rbrace token and block_node later97 fn init(c: *Context, parent: *Scope, label: ?[]const u8) !Block {
73 fn init(c: *Context, parent: *Scope, label: ?[]const u8) !*Block {98 return Block{
74 const block = try c.arena.create(Block);
75 block.* = .{
76 .base = .{99 .base = .{
77 .id = .Block,100 .id = .Block,
78 .parent = parent,101 .parent = parent,
79 },102 },
80 .block_node = undefined,103 .statements = std.ArrayList(*ast.Node).init(c.gpa),
81 .statements_it = undefined,104 .variables = AliasList.init(c.gpa),
82 .variables = AliasList.init(c.arena),105 .label = if (self.label) |l| blk: {
83 .label = label,106 const ll = try appendIdentifier(c, l);
107 _ = try appendToken(c, .Colon, ":");
108 break :blk ll;
109 } else null,
110 .lbrace = try appendToken(c, .LBrace, "{"),
84 };111 };
85 return block;
86 }112 }
87113
88 fn pushStatement(self: *Block, c: *Context, stmt: *ast.Node) !void {114 fn deinit(self: *Block) void {
89 self.statements_it = c.llpush(*ast.Node, self.statements_it, stmt);115 self.statements.deinit();
116 self.variables.deinit();
117 self.* = undefined;
90 }118 }
91119
92 fn setBlockNode(self: *Block, block: *ast.Node.Block) void {120 fn complete(self: *Block, c: *Context) !*ast.Node.Block {
93 self.block_node = block;121 const node = try ast.Node.Block.alloc(c.arena, self.statements.items.len);
94 self.statements_it = &block.statements.first;122 node.* = .{
123 .statements_len = self.statements.items.len,
124 .lbrace = self.lbrace,
125 .rbrace = try appendToken(c, .RBrace, "}"),
126 .label = self.label,
127 };
128 mem.copy(*ast.Node, node.statements(), self.statements.items);
129 return node;
95 }130 }
96131
97 /// Given the desired name, return a name that does not shadow anything from outer scopes.132 /// Given the desired name, return a name that does not shadow anything from outer scopes.
...@@ -102,12 +137,13 @@ const Scope = struct {...@@ -102,12 +137,13 @@ const Scope = struct {
102 scope.mangle_count += 1;137 scope.mangle_count += 1;
103 proposed_name = try std.fmt.allocPrint(c.arena, "{}_{}", .{ name, scope.mangle_count });138 proposed_name = try std.fmt.allocPrint(c.arena, "{}_{}", .{ name, scope.mangle_count });
104 }139 }
105 try scope.variables.append(.{ .name = name, .alias = proposed_name });140 try scope.variables.push(.{ .name = name, .alias = proposed_name });
106 return proposed_name;141 return proposed_name;
107 }142 }
108143
109 fn getAlias(scope: *Block, name: []const u8) []const u8 {144 fn getAlias(scope: *Block, name: []const u8) []const u8 {
110 for (scope.variables.items) |p| {145 var it = scope.variables.iterator(0);
146 while (it.next()) |p| {
111 if (mem.eql(u8, p.name, name))147 if (mem.eql(u8, p.name, name))
112 return p.alias;148 return p.alias;
113 }149 }
...@@ -115,7 +151,8 @@ const Scope = struct {...@@ -115,7 +151,8 @@ const Scope = struct {
115 }151 }
116152
117 fn localContains(scope: *Block, name: []const u8) bool {153 fn localContains(scope: *Block, name: []const u8) bool {
118 for (scope.variables.items) |p| {154 var it = scope.variables.iterator(0);
155 while (it.next()) |p| {
119 if (mem.eql(u8, p.name, name))156 if (mem.eql(u8, p.name, name))
120 return true;157 return true;
121 }158 }
...@@ -167,10 +204,7 @@ const Scope = struct {...@@ -167,10 +204,7 @@ const Scope = struct {
167 switch (scope.id) {204 switch (scope.id) {
168 .Root => unreachable,205 .Root => unreachable,
169 .Block => return @fieldParentPtr(Block, "base", scope),206 .Block => return @fieldParentPtr(Block, "base", scope),
170 .Condition => {207 .Condition => return @fieldParentPtr(Condition, "base", scope).getBlockScope(c),
171 // comma operator used
172 return try Block.init(c, scope, "blk");
173 },
174 else => scope = scope.parent.?,208 else => scope = scope.parent.?,
175 }209 }
176 }210 }
...@@ -219,7 +253,8 @@ const Scope = struct {...@@ -219,7 +253,8 @@ const Scope = struct {
219pub const Context = struct {253pub const Context = struct {
220 gpa: *mem.Allocator,254 gpa: *mem.Allocator,
221 arena: *mem.Allocator,255 arena: *mem.Allocator,
222 tokens: std.ArrayListUnmanaged(Token),256 token_ids: std.ArrayListUnmanaged(Token.Id),
257 token_locs: std.ArrayListUnmanaged(Token.Loc),
223 errors: std.ArrayListUnmanaged(ast.Error),258 errors: std.ArrayListUnmanaged(ast.Error),
224 source_buffer: *std.ArrayList(u8),259 source_buffer: *std.ArrayList(u8),
225 err: Error,260 err: Error,
...@@ -237,16 +272,6 @@ pub const Context = struct {...@@ -237,16 +272,6 @@ pub const Context = struct {
237 /// up front in a pre-processing step.272 /// up front in a pre-processing step.
238 global_names: std.StringHashMap(void),273 global_names: std.StringHashMap(void),
239274
240 /// Helper type to append elements to a singly linked list.
241 const LinkedListPusher = struct {
242 c: *Context,
243 it: *?*std.SinglyLinkedList(*ast.Node).Node,
244
245 fn push(self: *LinkedListPusher, element: *ast.Node) !void {
246 self.it = try self.c.llpush(*ast.Node, self.it, element);
247 }
248 };
249
250 fn getMangle(c: *Context) u32 {275 fn getMangle(c: *Context) u32 {
251 c.mangle_count += 1;276 c.mangle_count += 1;
252 return c.mangle_count;277 return c.mangle_count;
...@@ -267,6 +292,46 @@ pub const Context = struct {...@@ -267,6 +292,46 @@ pub const Context = struct {
267 const column = ZigClangSourceManager_getSpellingColumnNumber(c.source_manager, spelling_loc);292 const column = ZigClangSourceManager_getSpellingColumnNumber(c.source_manager, spelling_loc);
268 return std.fmt.allocPrint(c.arena, "{}:{}:{}", .{ filename, line, column });293 return std.fmt.allocPrint(c.arena, "{}:{}:{}", .{ filename, line, column });
269 }294 }
295
296 fn createCall(c: *Context, fn_expr: *ast.Node, params_len: ast.NodeIndex) !*ast.Node.Call {
297 _ = try appendToken(c, .LParen, "(");
298 const node = try ast.Node.Call.alloc(c.arena, params_len);
299 node.* = .{
300 .lhs = fn_expr,
301 .params_len = params_len,
302 .async_token = null,
303 .rtoken = undefined, // set after appending args
304 };
305 return node;
306 }
307
308 fn createBuiltinCall(c: *Context, name: []const u8, params_len: ast.NodeIndex) !*ast.Node.BuiltinCall {
309 const builtin_token = try appendToken(c, .Builtin, name);
310 _ = try appendToken(c, .LParen, "(");
311 const node = try ast.Node.BuiltinCall.alloc(c.arena, params_len);
312 node.* = .{
313 .builtin_token = builtin_token,
314 .params_len = params_len,
315 .rparen_token = undefined, // set after appending args
316 };
317 return node;
318 }
319
320 fn createBlock(c: *Context, label: ?[]const u8, statements_len: ast.NodeIndex) !*ast.Node.Block {
321 const label_node = if (label) |l| blk: {
322 const ll = try appendIdentifier(c, l);
323 _ = try appendToken(c, .Colon, ":");
324 break :blk ll;
325 } else null;
326 const block_node = try ast.Node.Block.alloc(c.arena, statements_len);
327 block_node.* = .{
328 .label = label_node,
329 .lbrace = try appendToken(c, .LBrace, "{"),
330 .statements_len = statements_len,
331 .rbrace = undefined,
332 };
333 return block_node;
334 }
270};335};
271336
272pub fn translate(337pub fn translate(
...@@ -307,14 +372,16 @@ pub fn translate(...@@ -307,14 +372,16 @@ pub fn translate(
307 .global_scope = try arena.allocator.create(Scope.Root),372 .global_scope = try arena.allocator.create(Scope.Root),
308 .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,373 .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
309 .global_names = std.StringHashMap(void).init(gpa),374 .global_names = std.StringHashMap(void).init(gpa),
310 .tokens = .{},375 .token_ids = .{},
376 .token_locs = .{},
311 .errors = .{},377 .errors = .{},
312 .root_decls = .{},378 .root_decls = .{},
313 };379 };
314 context.global_scope.* = Scope.Root.init(&context);380 context.global_scope.* = Scope.Root.init(&context);
315 defer context.decl_table.deinit();381 defer context.decl_table.deinit();
316 defer context.alias_list.deinit();382 defer context.alias_list.deinit();
317 defer context.tokens.deinit(gpa);383 defer context.token_ids.deinit(gpa);
384 defer context.token_locs.deinit(gpa);
318 defer context.errors.deinit(gpa);385 defer context.errors.deinit(gpa);
319 defer context.global_names.deinit();386 defer context.global_names.deinit();
320 defer context.root_decls.deinit(gpa);387 defer context.root_decls.deinit(gpa);
...@@ -349,7 +416,8 @@ pub fn translate(...@@ -349,7 +416,8 @@ pub fn translate(
349 tree.* = .{416 tree.* = .{
350 .gpa = gpa,417 .gpa = gpa,
351 .source = try arena.allocator.dupe(u8, source_buffer.items),418 .source = try arena.allocator.dupe(u8, source_buffer.items),
352 .tokens = context.tokens.toOwnedSlice(gpa),419 .token_ids = context.token_ids.toOwnedSlice(gpa),
420 .token_locs = context.token_locs.toOwnedSlice(gpa),
353 .errors = context.errors.toOwnedSlice(gpa),421 .errors = context.errors.toOwnedSlice(gpa),
354 .root_node = root_node,422 .root_node = root_node,
355 .arena = arena.state,423 .arena = arena.state,
...@@ -508,10 +576,9 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {...@@ -508,10 +576,9 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
508576
509 // actual function definition with body577 // actual function definition with body
510 const body_stmt = ZigClangFunctionDecl_getBody(fn_decl);578 const body_stmt = ZigClangFunctionDecl_getBody(fn_decl);
511 const block_scope = try Scope.Block.init(rp.c, &c.global_scope.base, null);579 var block_scope = try Scope.Block.init(rp.c, &c.global_scope.base, null);
580 defer block_scope.deinit();
512 var scope = &block_scope.base;581 var scope = &block_scope.base;
513 const block_node = try transCreateNodeBlock(rp.c, null);
514 block_scope.setBlockNode(block_node);
515582
516 var param_id: c_uint = 0;583 var param_id: c_uint = 0;
517 for (proto_node.params()) |param, i| {584 for (proto_node.params()) |param, i| {
...@@ -541,7 +608,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {...@@ -541,7 +608,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
541 node.eq_token = try appendToken(c, .Equal, "=");608 node.eq_token = try appendToken(c, .Equal, "=");
542 node.init_node = try transCreateNodeIdentifier(c, arg_name);609 node.init_node = try transCreateNodeIdentifier(c, arg_name);
543 node.semicolon_token = try appendToken(c, .Semicolon, ";");610 node.semicolon_token = try appendToken(c, .Semicolon, ";");
544 block_scope.block_statements_it = try c.llpush(*ast.Node, block_scope.block_statements_it, &node.base);611 try block_scope.statements.append(&node.base);
545 param.name_token = try appendIdentifier(c, arg_name);612 param.name_token = try appendIdentifier(c, arg_name);
546 _ = try appendToken(c, .Colon, ":");613 _ = try appendToken(c, .Colon, ":");
547 }614 }
...@@ -549,14 +616,14 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {...@@ -549,14 +616,14 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
549 param_id += 1;616 param_id += 1;
550 }617 }
551618
552 transCompoundStmtInline(rp, &block_scope.base, @ptrCast(*const ZigClangCompoundStmt, body_stmt), block_node) catch |err| switch (err) {619 const casted_body = @ptrCast(*const ZigClangCompoundStmt, body_stmt);
620 transCompoundStmtInline(rp, &block_scope.base, casted_body, &block_scope) catch |err| switch (err) {
553 error.OutOfMemory => |e| return e,621 error.OutOfMemory => |e| return e,
554 error.UnsupportedTranslation,622 error.UnsupportedTranslation,
555 error.UnsupportedType,623 error.UnsupportedType,
556 => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function", .{}),624 => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function", .{}),
557 };625 };
558 block_node.rbrace = try appendToken(rp.c, .RBrace, "}");626 proto_node.body_node = try block_scope.complete(rp.c);
559 proto_node.body_node = &block_node.base;
560 return addTopLevelDecl(c, fn_name, &proto_node.base);627 return addTopLevelDecl(c, fn_name, &proto_node.base);
561}628}
562629
...@@ -999,7 +1066,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No...@@ -999,7 +1066,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
999 // At this point we can rely on the enum emitting successfully.1066 // At this point we can rely on the enum emitting successfully.
1000 const tld_node = try transCreateNodeVarDecl(c, true, true, enum_val_name);1067 const tld_node = try transCreateNodeVarDecl(c, true, true, enum_val_name);
1001 tld_node.eq_token = try appendToken(c, .Equal, "=");1068 tld_node.eq_token = try appendToken(c, .Equal, "=");
1002 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt");1069 const cast_node = try rp.c.createBuiltinCall("@enumToInt", 1);
1003 const enum_ident = try transCreateNodeIdentifier(c, name);1070 const enum_ident = try transCreateNodeIdentifier(c, name);
1004 const period_tok = try appendToken(c, .Period, ".");1071 const period_tok = try appendToken(c, .Period, ".");
1005 const field_ident = try transCreateNodeIdentifier(c, field_name);1072 const field_ident = try transCreateNodeIdentifier(c, field_name);
...@@ -1010,7 +1077,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No...@@ -1010,7 +1077,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
1010 .op = .Period,1077 .op = .Period,
1011 .rhs = field_ident,1078 .rhs = field_ident,
1012 };1079 };
1013 try cast_node.params.push(&field_access_node.base);1080 cast_node.params()[0] = &field_access_node.base;
1014 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");1081 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1015 tld_node.init_node = &cast_node.base;1082 tld_node.init_node = &cast_node.base;
1016 tld_node.semicolon_token = try appendToken(c, .Semicolon, ";");1083 tld_node.semicolon_token = try appendToken(c, .Semicolon, ";");
...@@ -1104,7 +1171,7 @@ fn transStmt(...@@ -1104,7 +1171,7 @@ fn transStmt(
1104 .WhileStmtClass => return transWhileLoop(rp, scope, @ptrCast(*const ZigClangWhileStmt, stmt)),1171 .WhileStmtClass => return transWhileLoop(rp, scope, @ptrCast(*const ZigClangWhileStmt, stmt)),
1105 .DoStmtClass => return transDoWhileLoop(rp, scope, @ptrCast(*const ZigClangDoStmt, stmt)),1172 .DoStmtClass => return transDoWhileLoop(rp, scope, @ptrCast(*const ZigClangDoStmt, stmt)),
1106 .NullStmtClass => {1173 .NullStmtClass => {
1107 const block = try transCreateNodeBlock(rp.c, null);1174 const block = try rp.c.createBlock(null, 0);
1108 block.rbrace = try appendToken(rp.c, .RBrace, "}");1175 block.rbrace = try appendToken(rp.c, .RBrace, "}");
1109 return &block.base;1176 return &block.base;
1110 },1177 },
...@@ -1170,27 +1237,23 @@ fn transBinaryOperator(...@@ -1170,27 +1237,23 @@ fn transBinaryOperator(
1170 .Comma => {1237 .Comma => {
1171 const block_scope = try scope.findBlockScope(rp.c);1238 const block_scope = try scope.findBlockScope(rp.c);
1172 const expr = block_scope.base.parent == scope;1239 const expr = block_scope.base.parent == scope;
1173 const lparen = if (expr) blk: {1240 const lparen = if (expr) try appendToken(rp.c, .LParen, "(") else undefined;
1174 const l = try appendToken(rp.c, .LParen, "(");
1175 block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
1176 break :blk l;
1177 } else undefined;
11781241
1179 const lhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getLHS(stmt), .unused, .r_value);1242 const lhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getLHS(stmt), .unused, .r_value);
1180 try block_scope.statements.push(lhs);1243 try block_scope.statements.append(lhs);
11811244
1182 const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);1245 const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
1183 if (expr) {1246 if (expr) {
1184 _ = try appendToken(rp.c, .Semicolon, ";");1247 _ = try appendToken(rp.c, .Semicolon, ";");
1185 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);1248 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
1186 break_node.rhs = rhs;1249 break_node.rhs = rhs;
1187 try block_scope.block_node.statements.push(&break_node.base);1250 try block_scope.statements.append(&break_node.base);
1188 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");1251 const block_node = try block_scope.complete(rp.c);
1189 const rparen = try appendToken(rp.c, .RParen, ")");1252 const rparen = try appendToken(rp.c, .RParen, ")");
1190 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);1253 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
1191 grouped_expr.* = .{1254 grouped_expr.* = .{
1192 .lparen = lparen,1255 .lparen = lparen,
1193 .expr = &block_scope.block_node.base,1256 .expr = &block_node.base,
1194 .rparen = rparen,1257 .rparen = rparen,
1195 };1258 };
1196 return maybeSuppressResult(rp, scope, result_used, &grouped_expr.base);1259 return maybeSuppressResult(rp, scope, result_used, &grouped_expr.base);
...@@ -1201,11 +1264,11 @@ fn transBinaryOperator(...@@ -1201,11 +1264,11 @@ fn transBinaryOperator(
1201 .Div => {1264 .Div => {
1202 if (cIsSignedInteger(qt)) {1265 if (cIsSignedInteger(qt)) {
1203 // signed integer division uses @divTrunc1266 // signed integer division uses @divTrunc
1204 const div_trunc_node = try transCreateNodeBuiltinFnCall(rp.c, "@divTrunc");1267 const div_trunc_node = try rp.c.createBuiltinCall("@divTrunc", 2);
1205 try div_trunc_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value));1268 div_trunc_node.params()[0] = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value);
1206 _ = try appendToken(rp.c, .Comma, ",");1269 _ = try appendToken(rp.c, .Comma, ",");
1207 const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);1270 const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
1208 try div_trunc_node.params.push(rhs);1271 div_trunc_node.params()[1] = rhs;
1209 div_trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")");1272 div_trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1210 return maybeSuppressResult(rp, scope, result_used, &div_trunc_node.base);1273 return maybeSuppressResult(rp, scope, result_used, &div_trunc_node.base);
1211 }1274 }
...@@ -1213,11 +1276,11 @@ fn transBinaryOperator(...@@ -1213,11 +1276,11 @@ fn transBinaryOperator(
1213 .Rem => {1276 .Rem => {
1214 if (cIsSignedInteger(qt)) {1277 if (cIsSignedInteger(qt)) {
1215 // signed integer division uses @rem1278 // signed integer division uses @rem
1216 const rem_node = try transCreateNodeBuiltinFnCall(rp.c, "@rem");1279 const rem_node = try rp.c.createBuiltinCall("@rem", 2);
1217 try rem_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value));1280 rem_node.params()[0] = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value);
1218 _ = try appendToken(rp.c, .Comma, ",");1281 _ = try appendToken(rp.c, .Comma, ",");
1219 const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);1282 const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
1220 try rem_node.params.push(rhs);1283 rem_node.params()[1] = rhs;
1221 rem_node.rparen_token = try appendToken(rp.c, .RParen, ")");1284 rem_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1222 return maybeSuppressResult(rp, scope, result_used, &rem_node.base);1285 return maybeSuppressResult(rp, scope, result_used, &rem_node.base);
1223 }1286 }
...@@ -1321,15 +1384,15 @@ fn transBinaryOperator(...@@ -1321,15 +1384,15 @@ fn transBinaryOperator(
1321 const rhs_node = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);1384 const rhs_node = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
13221385
1323 const lhs = if (isBoolRes(lhs_node)) init: {1386 const lhs = if (isBoolRes(lhs_node)) init: {
1324 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");1387 const cast_node = try rp.c.createBuiltinCall("@boolToInt", 1);
1325 try cast_node.params.push(lhs_node);1388 cast_node.params()[0] = lhs_node;
1326 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");1389 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1327 break :init &cast_node.base;1390 break :init &cast_node.base;
1328 } else lhs_node;1391 } else lhs_node;
13291392
1330 const rhs = if (isBoolRes(rhs_node)) init: {1393 const rhs = if (isBoolRes(rhs_node)) init: {
1331 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");1394 const cast_node = try rp.c.createBuiltinCall("@boolToInt", 1);
1332 try cast_node.params.push(rhs_node);1395 cast_node.params()[0] = rhs_node;
1333 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");1396 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1334 break :init &cast_node.base;1397 break :init &cast_node.base;
1335 } else rhs_node;1398 } else rhs_node;
...@@ -1341,23 +1404,22 @@ fn transCompoundStmtInline(...@@ -1341,23 +1404,22 @@ fn transCompoundStmtInline(
1341 rp: RestorePoint,1404 rp: RestorePoint,
1342 parent_scope: *Scope,1405 parent_scope: *Scope,
1343 stmt: *const ZigClangCompoundStmt,1406 stmt: *const ZigClangCompoundStmt,
1344 block_node: *ast.Node.Block,1407 block: *Scope.Block,
1345) TransError!void {1408) TransError!void {
1346 var it = ZigClangCompoundStmt_body_begin(stmt);1409 var it = ZigClangCompoundStmt_body_begin(stmt);
1347 const end_it = ZigClangCompoundStmt_body_end(stmt);1410 const end_it = ZigClangCompoundStmt_body_end(stmt);
1348 while (it != end_it) : (it += 1) {1411 while (it != end_it) : (it += 1) {
1349 const result = try transStmt(rp, parent_scope, it[0], .unused, .r_value);1412 const result = try transStmt(rp, parent_scope, it[0], .unused, .r_value);
1350 if (result != &block_node.base)1413 try block.statements.append(result);
1351 try block_node.statements.push(result);
1352 }1414 }
1353}1415}
13541416
1355fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node {1417fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node {
1356 const block_scope = try Scope.Block.init(rp.c, scope, null);1418 var block_scope = try Scope.Block.init(rp.c, scope, null);
1357 block_scope.setBlockNode(try transCreateNodeBlock(rp.c, null));1419 defer block_scope.deinit();
1358 try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node);1420 try transCompoundStmtInline(rp, &block_scope.base, stmt, &block_scope);
1359 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");1421 const node = block_scope.complete(c);
1360 return &block_scope.block_node.base;1422 return &node.base;
1361}1423}
13621424
1363fn transCStyleCastExprClass(1425fn transCStyleCastExprClass(
...@@ -1411,14 +1473,14 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)...@@ -1411,14 +1473,14 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
1411 else1473 else
1412 try transCreateNodeUndefinedLiteral(c);1474 try transCreateNodeUndefinedLiteral(c);
1413 if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) {1475 if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) {
1414 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");1476 const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
1415 try builtin_node.params.push(init_node);1477 builtin_node.params()[0] = init_node;
1416 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");1478 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1417 init_node = &builtin_node.base;1479 init_node = &builtin_node.base;
1418 }1480 }
1419 node.init_node = init_node;1481 node.init_node = init_node;
1420 node.semicolon_token = try appendToken(c, .Semicolon, ";");1482 node.semicolon_token = try appendToken(c, .Semicolon, ";");
1421 try block_scope.block_node.statements.push(&node.base);1483 try block_scope.statements.append(&node.base);
1422 },1484 },
1423 .Typedef => {1485 .Typedef => {
1424 const typedef_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]);1486 const typedef_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]);
...@@ -1437,7 +1499,7 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)...@@ -1437,7 +1499,7 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
1437 });1499 });
1438 } else {1500 } else {
1439 const node = (try transCreateNodeTypedef(rp, typedef_decl, false, mangled_name)) orelse return error.UnsupportedTranslation;1501 const node = (try transCreateNodeTypedef(rp, typedef_decl, false, mangled_name)) orelse return error.UnsupportedTranslation;
1440 try block_scope.block_node.statements.push(&node.base);1502 try block_scope.statements.append(&node.base);
1441 }1503 }
1442 },1504 },
1443 else => |kind| return revertAndWarn(1505 else => |kind| return revertAndWarn(
...@@ -1499,8 +1561,8 @@ fn transImplicitCastExpr(...@@ -1499,8 +1561,8 @@ fn transImplicitCastExpr(
1499 },1561 },
1500 .PointerToBoolean => {1562 .PointerToBoolean => {
1501 // @ptrToInt(val) != 01563 // @ptrToInt(val) != 0
1502 const ptr_to_int = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");1564 const ptr_to_int = try rp.c.createBuiltinCall("@ptrToInt", 1);
1503 try ptr_to_int.params.push(try transExpr(rp, scope, sub_expr, .used, .r_value));1565 ptr_to_int.params()[0] = try transExpr(rp, scope, sub_expr, .used, .r_value);
1504 ptr_to_int.rparen_token = try appendToken(rp.c, .RParen, ")");1566 ptr_to_int.rparen_token = try appendToken(rp.c, .RParen, ")");
15051567
1506 const op_token = try appendToken(rp.c, .BangEqual, "!=");1568 const op_token = try appendToken(rp.c, .BangEqual, "!=");
...@@ -1724,13 +1786,11 @@ fn transIntegerLiteral(...@@ -1724,13 +1786,11 @@ fn transIntegerLiteral(
17241786
1725 // @as(T, x)1787 // @as(T, x)
1726 const expr_base = @ptrCast(*const ZigClangExpr, expr);1788 const expr_base = @ptrCast(*const ZigClangExpr, expr);
1727 const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");1789 const as_node = try rp.c.createBuiltinCall("@as", 2);
1728 const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base));1790 const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base));
1729 try as_node.params.push(ty_node);1791 as_node.params()[0] = ty_node;
1730 _ = try appendToken(rp.c, .Comma, ",");1792 _ = try appendToken(rp.c, .Comma, ",");
17311793 as_node.params()[1] = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val));
1732 const int_lit_node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val));
1733 try as_node.params.push(int_lit_node);
17341794
1735 as_node.rparen_token = try appendToken(rp.c, .RParen, ")");1795 as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1736 return maybeSuppressResult(rp, scope, result_used, &as_node.base);1796 return maybeSuppressResult(rp, scope, result_used, &as_node.base);
...@@ -1840,35 +1900,35 @@ fn transCCast(...@@ -1840,35 +1900,35 @@ fn transCCast(
1840 // 2. Bit-cast to correct signed-ness1900 // 2. Bit-cast to correct signed-ness
18411901
1842 // @bitCast(dest_type, intermediate_value)1902 // @bitCast(dest_type, intermediate_value)
1843 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast");1903 const cast_node = try rp.c.createBuiltinCall("@bitCast", 2);
1844 try cast_node.params.push(try transQualType(rp, dst_type, loc));1904 cast_node.params()[0] = try transQualType(rp, dst_type, loc);
1845 _ = try appendToken(rp.c, .Comma, ",");1905 _ = try appendToken(rp.c, .Comma, ",");
18461906
1847 switch (cIntTypeCmp(dst_type, src_type)) {1907 switch (cIntTypeCmp(dst_type, src_type)) {
1848 .lt => {1908 .lt => {
1849 // @truncate(SameSignSmallerInt, src_type)1909 // @truncate(SameSignSmallerInt, src_type)
1850 const trunc_node = try transCreateNodeBuiltinFnCall(rp.c, "@truncate");1910 const trunc_node = try rp.c.createBuiltinCall("@truncate", 2);
1851 const ty_node = try transQualTypeIntWidthOf(rp.c, dst_type, cIsSignedInteger(src_type));1911 const ty_node = try transQualTypeIntWidthOf(rp.c, dst_type, cIsSignedInteger(src_type));
1852 try trunc_node.params.push(ty_node);1912 trunc_node.params()[0] = ty_node;
1853 _ = try appendToken(rp.c, .Comma, ",");1913 _ = try appendToken(rp.c, .Comma, ",");
1854 try trunc_node.params.push(expr);1914 trunc_node.params()[1] = expr;
1855 trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")");1915 trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")");
18561916
1857 try cast_node.params.push(&trunc_node.base);1917 cast_node.params()[1] = &trunc_node.base;
1858 },1918 },
1859 .gt => {1919 .gt => {
1860 // @as(SameSignBiggerInt, src_type)1920 // @as(SameSignBiggerInt, src_type)
1861 const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");1921 const as_node = try rp.c.createBuiltinCall("@as", 2);
1862 const ty_node = try transQualTypeIntWidthOf(rp.c, dst_type, cIsSignedInteger(src_type));1922 const ty_node = try transQualTypeIntWidthOf(rp.c, dst_type, cIsSignedInteger(src_type));
1863 try as_node.params.push(ty_node);1923 as_node.params()[0] = ty_node;
1864 _ = try appendToken(rp.c, .Comma, ",");1924 _ = try appendToken(rp.c, .Comma, ",");
1865 try as_node.params.push(expr);1925 as_node.params()[1] = expr;
1866 as_node.rparen_token = try appendToken(rp.c, .RParen, ")");1926 as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
18671927
1868 try cast_node.params.push(&as_node.base);1928 cast_node.params()[1] = &as_node.base;
1869 },1929 },
1870 .eq => {1930 .eq => {
1871 try cast_node.params.push(expr);1931 cast_node.params()[1] = expr;
1872 },1932 },
1873 }1933 }
1874 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");1934 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
...@@ -1876,46 +1936,46 @@ fn transCCast(...@@ -1876,46 +1936,46 @@ fn transCCast(
1876 }1936 }
1877 if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) {1937 if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) {
1878 // @intCast(dest_type, @ptrToInt(val))1938 // @intCast(dest_type, @ptrToInt(val))
1879 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");1939 const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
1880 try cast_node.params.push(try transQualType(rp, dst_type, loc));1940 cast_node.params()[0] = try transQualType(rp, dst_type, loc);
1881 _ = try appendToken(rp.c, .Comma, ",");1941 _ = try appendToken(rp.c, .Comma, ",");
1882 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");1942 const builtin_node = try rp.c.createBuiltinCall("@ptrToInt", 1);
1883 try builtin_node.params.push(expr);1943 builtin_node.params()[0] = expr;
1884 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");1944 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1885 try cast_node.params.push(&builtin_node.base);1945 cast_node.params()[1] = &builtin_node.base;
1886 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");1946 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1887 return &cast_node.base;1947 return &cast_node.base;
1888 }1948 }
1889 if (cIsInteger(src_type) and qualTypeIsPtr(dst_type)) {1949 if (cIsInteger(src_type) and qualTypeIsPtr(dst_type)) {
1890 // @intToPtr(dest_type, val)1950 // @intToPtr(dest_type, val)
1891 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr");1951 const builtin_node = try rp.c.createBuiltinCall("@intToPtr", 2);
1892 try builtin_node.params.push(try transQualType(rp, dst_type, loc));1952 builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
1893 _ = try appendToken(rp.c, .Comma, ",");1953 _ = try appendToken(rp.c, .Comma, ",");
1894 try builtin_node.params.push(expr);1954 builtin_node.params()[1] = expr;
1895 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");1955 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1896 return &builtin_node.base;1956 return &builtin_node.base;
1897 }1957 }
1898 if (cIsFloating(src_type) and cIsFloating(dst_type)) {1958 if (cIsFloating(src_type) and cIsFloating(dst_type)) {
1899 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@floatCast");1959 const builtin_node = try rp.c.createBuiltinCall("@floatCast", 2);
1900 try builtin_node.params.push(try transQualType(rp, dst_type, loc));1960 builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
1901 _ = try appendToken(rp.c, .Comma, ",");1961 _ = try appendToken(rp.c, .Comma, ",");
1902 try builtin_node.params.push(expr);1962 builtin_node.params()[1] = expr;
1903 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");1963 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1904 return &builtin_node.base;1964 return &builtin_node.base;
1905 }1965 }
1906 if (cIsFloating(src_type) and !cIsFloating(dst_type)) {1966 if (cIsFloating(src_type) and !cIsFloating(dst_type)) {
1907 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@floatToInt");1967 const builtin_node = try rp.c.createBuiltinCall("@floatToInt", 2);
1908 try builtin_node.params.push(try transQualType(rp, dst_type, loc));1968 builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
1909 _ = try appendToken(rp.c, .Comma, ",");1969 _ = try appendToken(rp.c, .Comma, ",");
1910 try builtin_node.params.push(expr);1970 builtin_node.params()[1] = expr;
1911 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");1971 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1912 return &builtin_node.base;1972 return &builtin_node.base;
1913 }1973 }
1914 if (!cIsFloating(src_type) and cIsFloating(dst_type)) {1974 if (!cIsFloating(src_type) and cIsFloating(dst_type)) {
1915 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToFloat");1975 const builtin_node = try rp.c.createBuiltinCall("@intToFloat", 2);
1916 try builtin_node.params.push(try transQualType(rp, dst_type, loc));1976 builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
1917 _ = try appendToken(rp.c, .Comma, ",");1977 _ = try appendToken(rp.c, .Comma, ",");
1918 try builtin_node.params.push(expr);1978 builtin_node.params()[1] = expr;
1919 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");1979 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1920 return &builtin_node.base;1980 return &builtin_node.base;
1921 }1981 }
...@@ -1923,54 +1983,54 @@ fn transCCast(...@@ -1923,54 +1983,54 @@ fn transCCast(
1923 !ZigClangType_isBooleanType(qualTypeCanon(dst_type)))1983 !ZigClangType_isBooleanType(qualTypeCanon(dst_type)))
1924 {1984 {
1925 // @boolToInt returns either a comptime_int or a u11985 // @boolToInt returns either a comptime_int or a u1
1926 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");1986 const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
1927 try builtin_node.params.push(expr);1987 builtin_node.params()[0] = expr;
1928 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");1988 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
19291989
1930 const inner_cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");1990 const inner_cast_node = try rp.c.createBuiltinCall("@intCast", 2);
1931 try inner_cast_node.params.push(try transCreateNodeIdentifier(rp.c, "u1"));1991 inner_cast_node.params()[0] = try transCreateNodeIdentifier(rp.c, "u1");
1932 _ = try appendToken(rp.c, .Comma, ",");1992 _ = try appendToken(rp.c, .Comma, ",");
1933 try inner_cast_node.params.push(&builtin_node.base);1993 inner_cast_node.params()[1] = &builtin_node.base;
1934 inner_cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");1994 inner_cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
19351995
1936 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");1996 const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
1937 try cast_node.params.push(try transQualType(rp, dst_type, loc));1997 cast_node.params()[0] = try transQualType(rp, dst_type, loc);
1938 _ = try appendToken(rp.c, .Comma, ",");1998 _ = try appendToken(rp.c, .Comma, ",");
19391999
1940 if (cIsSignedInteger(dst_type)) {2000 if (cIsSignedInteger(dst_type)) {
1941 const bitcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast");2001 const bitcast_node = try rp.c.createBuiltinCall("@bitCast", 2);
1942 try bitcast_node.params.push(try transCreateNodeIdentifier(rp.c, "i1"));2002 bitcast_node.params()[0] = try transCreateNodeIdentifier(rp.c, "i1");
1943 _ = try appendToken(rp.c, .Comma, ",");2003 _ = try appendToken(rp.c, .Comma, ",");
1944 try bitcast_node.params.push(&inner_cast_node.base);2004 bitcast_node.params()[1] = &inner_cast_node.base;
1945 bitcast_node.rparen_token = try appendToken(rp.c, .RParen, ")");2005 bitcast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1946 try cast_node.params.push(&bitcast_node.base);2006 cast_node.params()[1] = &bitcast_node.base;
1947 } else {2007 } else {
1948 try cast_node.params.push(&inner_cast_node.base);2008 cast_node.params()[1] = &inner_cast_node.base;
1949 }2009 }
1950 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");2010 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
19512011
1952 return &cast_node.base;2012 return &cast_node.base;
1953 }2013 }
1954 if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) {2014 if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) {
1955 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");2015 const builtin_node = try rp.c.createBuiltinCall("@intToEnum", 2);
1956 try builtin_node.params.push(try transQualType(rp, dst_type, loc));2016 builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
1957 _ = try appendToken(rp.c, .Comma, ",");2017 _ = try appendToken(rp.c, .Comma, ",");
1958 try builtin_node.params.push(expr);2018 builtin_node.params()[1] = expr;
1959 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");2019 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1960 return &builtin_node.base;2020 return &builtin_node.base;
1961 }2021 }
1962 if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(src_type)) == .Enum and2022 if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(src_type)) == .Enum and
1963 ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) != .Enum)2023 ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) != .Enum)
1964 {2024 {
1965 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt");2025 const builtin_node = try rp.c.createBuiltinCall("@enumToInt", 1);
1966 try builtin_node.params.push(expr);2026 builtin_node.params()[0] = expr;
1967 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");2027 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1968 return &builtin_node.base;2028 return &builtin_node.base;
1969 }2029 }
1970 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");2030 const cast_node = try rp.c.createBuiltinCall("@as", 2);
1971 try cast_node.params.push(try transQualType(rp, dst_type, loc));2031 cast_node.params()[0] = try transQualType(rp, dst_type, loc);
1972 _ = try appendToken(rp.c, .Comma, ",");2032 _ = try appendToken(rp.c, .Comma, ",");
1973 try cast_node.params.push(expr);2033 cast_node.params()[1] = expr;
1974 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");2034 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
1975 return &cast_node.base;2035 return &cast_node.base;
1976}2036}
...@@ -2077,12 +2137,13 @@ fn transInitListExprRecord(...@@ -2077,12 +2137,13 @@ fn transInitListExprRecord(
20772137
2078 _ = try appendToken(c, .LBrace, "{");2138 _ = try appendToken(c, .LBrace, "{");
20792139
2080 const node = try rp.c.arena.create(ast.Node.StructInitializer);2140 const node = try ast.Node.StructInitializer.alloc(rp.c.arena, field_inits.items.len);
2081 node.* = .{2141 node.* = .{
2082 .lhs = ty,2142 .lhs = ty,
2083 .rtoken = try appendToken(rp.c, .RBrace, "}"),2143 .rtoken = try appendToken(rp.c, .RBrace, "}"),
2084 .list = try rp.c.arena.dupe(*ast.Node, field_inits.items),2144 .list_len = field_inits.items.len,
2085 };2145 };
2146 mem.copy(*ast.Node, node.list(), field_inits.items);
2086 return &node.base;2147 return &node.base;
2087}2148}
20882149
...@@ -2292,11 +2353,15 @@ fn transIfStmt(...@@ -2292,11 +2353,15 @@ fn transIfStmt(
2292 // if (c) t else e2353 // if (c) t else e
2293 const if_node = try transCreateNodeIf(rp.c);2354 const if_node = try transCreateNodeIf(rp.c);
22942355
2295 var cond_scope = Scope{2356 var cond_scope = Scope.Condition{
2296 .parent = scope,2357 .base = .{
2297 .id = .Condition,2358 .parent = scope,
2359 .id = .Condition,
2360 },
2298 };2361 };
2299 if_node.condition = try transBoolExpr(rp, &cond_scope, @ptrCast(*const ZigClangExpr, ZigClangIfStmt_getCond(stmt)), .used, .r_value, false);2362 defer cond_scope.deinit();
2363 const cond_expr = @ptrCast(*const ZigClangExpr, ZigClangIfStmt_getCond(stmt));
2364 if_node.condition = try transBoolExpr(rp, &cond_scope.base, cond_expr, .used, .r_value, false);
2300 _ = try appendToken(rp.c, .RParen, ")");2365 _ = try appendToken(rp.c, .RParen, ")");
23012366
2302 if_node.body = try transStmt(rp, scope, ZigClangIfStmt_getThen(stmt), .unused, .r_value);2367 if_node.body = try transStmt(rp, scope, ZigClangIfStmt_getThen(stmt), .unused, .r_value);
...@@ -2316,11 +2381,15 @@ fn transWhileLoop(...@@ -2316,11 +2381,15 @@ fn transWhileLoop(
2316) TransError!*ast.Node {2381) TransError!*ast.Node {
2317 const while_node = try transCreateNodeWhile(rp.c);2382 const while_node = try transCreateNodeWhile(rp.c);
23182383
2319 var cond_scope = Scope{2384 var cond_scope = Scope.Condition{
2320 .parent = scope,2385 .base = .{
2321 .id = .Condition,2386 .parent = scope,
2387 .id = .Condition,
2388 },
2322 };2389 };
2323 while_node.condition = try transBoolExpr(rp, &cond_scope, @ptrCast(*const ZigClangExpr, ZigClangWhileStmt_getCond(stmt)), .used, .r_value, false);2390 defer cond_scope.deinit();
2391 const cond_expr = @ptrCast(*const ZigClangExpr, ZigClangWhileStmt_getCond(stmt));
2392 while_node.condition = try transBoolExpr(rp, &cond_scope.base, cond_expr, .used, .r_value, false);
2324 _ = try appendToken(rp.c, .RParen, ")");2393 _ = try appendToken(rp.c, .RParen, ")");
23252394
2326 var loop_scope = Scope{2395 var loop_scope = Scope{
...@@ -2349,12 +2418,15 @@ fn transDoWhileLoop(...@@ -2349,12 +2418,15 @@ fn transDoWhileLoop(
23492418
2350 // if (!cond) break;2419 // if (!cond) break;
2351 const if_node = try transCreateNodeIf(rp.c);2420 const if_node = try transCreateNodeIf(rp.c);
2352 var cond_scope = Scope{2421 var cond_scope = Scope.Condition{
2353 .parent = scope,2422 .base = .{
2354 .id = .Condition,2423 .parent = scope,
2424 .id = .Condition,
2425 },
2355 };2426 };
2427 defer cond_scope.deinit();
2356 const prefix_op = try transCreateNodePrefixOp(rp.c, .BoolNot, .Bang, "!");2428 const prefix_op = try transCreateNodePrefixOp(rp.c, .BoolNot, .Bang, "!");
2357 prefix_op.rhs = try transBoolExpr(rp, &cond_scope, @ptrCast(*const ZigClangExpr, ZigClangDoStmt_getCond(stmt)), .used, .r_value, true);2429 prefix_op.rhs = try transBoolExpr(rp, &cond_scope.base, @ptrCast(*const ZigClangExpr, ZigClangDoStmt_getCond(stmt)), .used, .r_value, true);
2358 _ = try appendToken(rp.c, .RParen, ")");2430 _ = try appendToken(rp.c, .RParen, ")");
2359 if_node.condition = &prefix_op.base;2431 if_node.condition = &prefix_op.base;
2360 if_node.body = &(try transCreateNodeBreak(rp.c, null)).base;2432 if_node.body = &(try transCreateNodeBreak(rp.c, null)).base;
...@@ -2404,24 +2476,26 @@ fn transForLoop(...@@ -2404,24 +2476,26 @@ fn transForLoop(
2404 .id = .Loop,2476 .id = .Loop,
2405 };2477 };
24062478
2407 var block_scope: ?*Scope.Block = null;2479 var block_scope: ?Scope.Block = null;
2480 defer if (block_scope) |*bs| bs.deinit();
2481
2408 if (ZigClangForStmt_getInit(stmt)) |init| {2482 if (ZigClangForStmt_getInit(stmt)) |init| {
2409 block_scope = try Scope.Block.init(rp.c, scope, null);2483 block_scope = try Scope.Block.init(rp.c, scope, null);
2410 const block = try transCreateNodeBlock(rp.c, null);
2411 block_scope.?.setBlockNode(block);
2412 loop_scope.parent = &block_scope.?.base;2484 loop_scope.parent = &block_scope.?.base;
2413 const result = try transStmt(rp, &block_scope.?.base, init, .unused, .r_value);2485 const result = try transStmt(rp, &block_scope.?.base, init, .unused, .r_value);
2414 if (result != &block.base)2486 try block_scope.statements.push(result);
2415 try block.statements.push(result);
2416 }2487 }
2417 var cond_scope = Scope{2488 var cond_scope = Scope.Condition{
2418 .parent = scope,2489 .base = .{
2419 .id = .Condition,2490 .parent = scope,
2491 .id = .Condition,
2492 },
2420 };2493 };
2494 defer cond_scope.deinit();
24212495
2422 const while_node = try transCreateNodeWhile(rp.c);2496 const while_node = try transCreateNodeWhile(rp.c);
2423 while_node.condition = if (ZigClangForStmt_getCond(stmt)) |cond|2497 while_node.condition = if (ZigClangForStmt_getCond(stmt)) |cond|
2424 try transBoolExpr(rp, &cond_scope, cond, .used, .r_value, false)2498 try transBoolExpr(rp, &cond_scope.base, cond, .used, .r_value, false)
2425 else2499 else
2426 try transCreateNodeBoolLiteral(rp.c, true);2500 try transCreateNodeBoolLiteral(rp.c, true);
2427 _ = try appendToken(rp.c, .RParen, ")");2501 _ = try appendToken(rp.c, .RParen, ")");
...@@ -2429,62 +2503,90 @@ fn transForLoop(...@@ -2429,62 +2503,90 @@ fn transForLoop(
2429 if (ZigClangForStmt_getInc(stmt)) |incr| {2503 if (ZigClangForStmt_getInc(stmt)) |incr| {
2430 _ = try appendToken(rp.c, .Colon, ":");2504 _ = try appendToken(rp.c, .Colon, ":");
2431 _ = try appendToken(rp.c, .LParen, "(");2505 _ = try appendToken(rp.c, .LParen, "(");
2432 while_node.continue_expr = try transExpr(rp, &cond_scope, incr, .unused, .r_value);2506 while_node.continue_expr = try transExpr(rp, &cond_scope.base, incr, .unused, .r_value);
2433 _ = try appendToken(rp.c, .RParen, ")");2507 _ = try appendToken(rp.c, .RParen, ")");
2434 }2508 }
24352509
2436 while_node.body = try transStmt(rp, &loop_scope, ZigClangForStmt_getBody(stmt), .unused, .r_value);2510 while_node.body = try transStmt(rp, &loop_scope, ZigClangForStmt_getBody(stmt), .unused, .r_value);
2437 if (block_scope != null) {2511 if (block_scope) |*bs| {
2438 try block_scope.?.block_node.statements.push(&while_node.base);2512 try bs.statements.push(&while_node.base);
2439 block_scope.?.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");2513 const node = bs.complete(rp.c);
2440 return &block_scope.?.block_node.base;2514 return &node.base;
2441 } else {2515 } else {
2442 _ = try appendToken(rp.c, .Semicolon, ";");2516 _ = try appendToken(rp.c, .Semicolon, ";");
2443 return &while_node.base;2517 return &while_node.base;
2444 }2518 }
2445}2519}
24462520
2521fn getSwitchCaseCount(stmt: *const ZigClangSwitchStmt) usize {
2522 const stmt = ZigClangSwitchStmt_getBody(stmt);
2523 const comp = ZigClangStmtExpr_getSubStmt(stmt);
2524 return ZigClangCompoundStmt_body_end(comp) - ZigClangCompoundStmt_body_begin(comp);
2525}
2526
2447fn transSwitch(2527fn transSwitch(
2448 rp: RestorePoint,2528 rp: RestorePoint,
2449 scope: *Scope,2529 scope: *Scope,
2450 stmt: *const ZigClangSwitchStmt,2530 stmt: *const ZigClangSwitchStmt,
2451) TransError!*ast.Node {2531) TransError!*ast.Node {
2452 const switch_node = try transCreateNodeSwitch(rp.c);2532 const switch_tok = try appendToken(rp.c, .Keyword_switch, "switch");
2533 _ = try appendToken(rp.c, .LParen, "(");
2534
2535 const cases_len = getSwitchCaseCount(ZigClangSwitchStmt_getBody(stmt));
2536
2537 var cond_scope = Scope.Condition{
2538 .base = .{
2539 .parent = scope,
2540 .id = .Condition,
2541 },
2542 };
2543 defer cond_scope.deinit();
2544 const switch_expr = try transExpr(rp, &cond_scope.base, ZigClangSwitchStmt_getCond(stmt), .used, .r_value);
2545 _ = try appendToken(rp.c, .RParen, ")");
2546 _ = try appendToken(rp.c, .LBrace, "{");
2547 // reserve +1 case in case there is no default case
2548 const switch_node = try ast.Node.Switch.alloc(rp.c.arena, cases_len + 1);
2549 switch_node.* = .{
2550 .switch_token = switch_tok,
2551 .expr = switch_expr,
2552 .cases_len = cases_len + 1,
2553 .rbrace = try appendToken(rp.c, .RBrace, "}"),
2554 };
2555
2453 var switch_scope = Scope.Switch{2556 var switch_scope = Scope.Switch{
2454 .base = .{2557 .base = .{
2455 .id = .Switch,2558 .id = .Switch,
2456 .parent = scope,2559 .parent = scope,
2457 },2560 },
2458 .cases = &switch_node.cases,2561 .cases = switch_node.cases(),
2562 .case_index = 0,
2459 .pending_block = undefined,2563 .pending_block = undefined,
2460 };2564 };
24612565
2462 var cond_scope = Scope{
2463 .parent = scope,
2464 .id = .Condition,
2465 };
2466 switch_node.expr = try transExpr(rp, &cond_scope, ZigClangSwitchStmt_getCond(stmt), .used, .r_value);
2467 _ = try appendToken(rp.c, .RParen, ")");
2468 _ = try appendToken(rp.c, .LBrace, "{");
2469 switch_node.rbrace = try appendToken(rp.c, .RBrace, "}");
2470
2471 const block_scope = try Scope.Block.init(rp.c, &switch_scope.base, null);
2472 // tmp block that all statements will go before being picked up by a case or default2566 // tmp block that all statements will go before being picked up by a case or default
2473 const block = try transCreateNodeBlock(rp.c, null);2567 var block_scope = try Scope.Block.init(rp.c, &switch_scope.base, null);
2474 block_scope.setBlockNode(block);2568 defer block_scope.deinit();
24752569
2476 const switch_block = try transCreateNodeBlock(rp.c, null);2570 // Note that we do not defer a deinit here; the switch_scope.pending_block field
2477 try switch_block.statements.push(&switch_node.base);2571 // has its own memory management. This resource is freed inside `transCase` and
2478 switch_scope.pending_block = switch_block;2572 // then the final pending_block is freed at the bottom of this function with
2573 // pending_block.deinit().
2574 switch_scope.pending_block = try Scope.Block.init(rp.c, scope, null);
2575 try switch_scope.pending_block.statements.append(&switch_node.base);
24792576
2480 const last = try transStmt(rp, &block_scope.base, ZigClangSwitchStmt_getBody(stmt), .unused, .r_value);2577 _ = try transStmt(rp, &block_scope.base, ZigClangSwitchStmt_getBody(stmt), .unused, .r_value);
2481 _ = try appendToken(rp.c, .Semicolon, ";");2578 _ = try appendToken(rp.c, .Semicolon, ";");
24822579
2483 // take all pending statements2580 // take all pending statements
2484 var it = last.cast(ast.Node.Block).?.statements.iterator(0);2581 try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items);
2485 while (it.next()) |n| {2582 // TODO delete the following commented out code
2486 try switch_scope.pending_block.statements.push(n.*);2583 //const last_block_stmts = last.cast(ast.Node.Block).?.statements();
2487 }2584 //switch_scope.pending_block.statements.ensureCapacity(
2585 // switch_scope.pending_block.statements.items.len + last_block_stmts.len,
2586 //);
2587 //for (last_block_stmts) |n| {
2588 // switch_scope.pending_block.statements.appendAssumeCapacity(n);
2589 //}
24882590
2489 switch_scope.pending_block.label = try appendIdentifier(rp.c, "__switch");2591 switch_scope.pending_block.label = try appendIdentifier(rp.c, "__switch");
2490 _ = try appendToken(rp.c, .Colon, ":");2592 _ = try appendToken(rp.c, .Colon, ":");
...@@ -2492,10 +2594,16 @@ fn transSwitch(...@@ -2492,10 +2594,16 @@ fn transSwitch(
2492 const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c));2594 const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c));
2493 else_prong.expr = &(try transCreateNodeBreak(rp.c, "__switch")).base;2595 else_prong.expr = &(try transCreateNodeBreak(rp.c, "__switch")).base;
2494 _ = try appendToken(rp.c, .Comma, ",");2596 _ = try appendToken(rp.c, .Comma, ",");
2495 try switch_node.cases.push(&else_prong.base);2597 switch_node.cases[switch_node.case_index] = &else_prong.base;
2598 switch_node.case_index += 1;
2496 }2599 }
2497 switch_scope.pending_block.rbrace = try appendToken(rp.c, .RBrace, "}");2600 // We overallocated in case there was no default, so now we correct
2498 return &switch_scope.pending_block.base;2601 // the number of cases in the AST node.
2602 switch_node.cases_len = switch_scope.case_index;
2603
2604 const result_node = try switch_scope.pending_block.complete(rp.c);
2605 switch_scope.pending_block.deinit();
2606 return &result_node.base;
2499}2607}
25002608
2501fn transCase(2609fn transCase(
...@@ -2527,22 +2635,21 @@ fn transCase(...@@ -2527,22 +2635,21 @@ fn transCase(
2527 const switch_prong = try transCreateNodeSwitchCase(rp.c, expr);2635 const switch_prong = try transCreateNodeSwitchCase(rp.c, expr);
2528 switch_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base;2636 switch_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base;
2529 _ = try appendToken(rp.c, .Comma, ",");2637 _ = try appendToken(rp.c, .Comma, ",");
2530 try switch_scope.cases.push(&switch_prong.base);2638 switch_scope.cases[switch_scope.case_index] = &switch_prong.base;
2639 switch_scope.case_index += 1;
25312640
2532 const block = try transCreateNodeBlock(rp.c, null);
2533 switch_scope.pending_block.label = try appendIdentifier(rp.c, label);2641 switch_scope.pending_block.label = try appendIdentifier(rp.c, label);
2534 _ = try appendToken(rp.c, .Colon, ":");2642 _ = try appendToken(rp.c, .Colon, ":");
2535 switch_scope.pending_block.rbrace = try appendToken(rp.c, .RBrace, "}");
2536 try block.statements.push(&switch_scope.pending_block.base);
25372643
2538 // take all pending statements2644 // take all pending statements
2539 var it = block_scope.block_node.statements.iterator(0);2645 try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items);
2540 while (it.next()) |n| {2646 block_scope.statements.shrink(0);
2541 try switch_scope.pending_block.statements.push(n.*);2647
2542 }2648 const pending_node = try switch_scope.pending_block.complete(rp.c);
2543 block_scope.block_node.statements.shrink(0);2649 switch_scope.pending_block.deinit();
2650 switch_scope.pending_block = try Scope.Block.init(rp.c, scope, null);
25442651
2545 switch_scope.pending_block = block;2652 try switch_scope.pending_block.statements.append(&pending_node.base);
25462653
2547 return transStmt(rp, scope, ZigClangCaseStmt_getSubStmt(stmt), .unused, .r_value);2654 return transStmt(rp, scope, ZigClangCaseStmt_getSubStmt(stmt), .unused, .r_value);
2548}2655}
...@@ -2561,22 +2668,21 @@ fn transDefault(...@@ -2561,22 +2668,21 @@ fn transDefault(
2561 const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c));2668 const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c));
2562 else_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base;2669 else_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base;
2563 _ = try appendToken(rp.c, .Comma, ",");2670 _ = try appendToken(rp.c, .Comma, ",");
2564 try switch_scope.cases.push(&else_prong.base);2671 switch_scope.cases[switch_scope.case_index] = &else_prong.base;
2672 switch_scope.case_index += 1;
25652673
2566 const block = try transCreateNodeBlock(rp.c, null);
2567 switch_scope.pending_block.label = try appendIdentifier(rp.c, label);2674 switch_scope.pending_block.label = try appendIdentifier(rp.c, label);
2568 _ = try appendToken(rp.c, .Colon, ":");2675 _ = try appendToken(rp.c, .Colon, ":");
2569 switch_scope.pending_block.rbrace = try appendToken(rp.c, .RBrace, "}");
2570 try block.statements.push(&switch_scope.pending_block.base);
25712676
2572 // take all pending statements2677 // take all pending statements
2573 var it = block_scope.block_node.statements.iterator(0);2678 try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items);
2574 while (it.next()) |n| {2679 block_scope.statements.shrink(0);
2575 try switch_scope.pending_block.statements.push(n.*);2680
2576 }2681 const pending_node = try switch_scope.pending_block.complete(rp.c);
2577 block_scope.block_node.statements.shrink(0);2682 switch_scope.pending_block.deinit();
2683 switch_scope.pending_block = try Scope.Block.init(rp.c, scope, null);
2684 try switch_scope.pending_block.statements.append(&pending_node.base);
25782685
2579 switch_scope.pending_block = block;
2580 return transStmt(rp, scope, ZigClangDefaultStmt_getSubStmt(stmt), .unused, .r_value);2686 return transStmt(rp, scope, ZigClangDefaultStmt_getSubStmt(stmt), .unused, .r_value);
2581}2687}
25822688
...@@ -2591,13 +2697,13 @@ fn transConstantExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangExpr,...@@ -2591,13 +2697,13 @@ fn transConstantExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangExpr,
2591 // See comment in `transIntegerLiteral` for why this code is here.2697 // See comment in `transIntegerLiteral` for why this code is here.
2592 // @as(T, x)2698 // @as(T, x)
2593 const expr_base = @ptrCast(*const ZigClangExpr, expr);2699 const expr_base = @ptrCast(*const ZigClangExpr, expr);
2594 const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");2700 const as_node = try rp.c.createBuiltinCall("@as", 2);
2595 const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base));2701 const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base));
2596 try as_node.params.push(ty_node);2702 as_node.params()[0] = ty_node;
2597 _ = try appendToken(rp.c, .Comma, ",");2703 _ = try appendToken(rp.c, .Comma, ",");
25982704
2599 const int_lit_node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&result.Val));2705 const int_lit_node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&result.Val));
2600 try as_node.params.push(int_lit_node);2706 as_node.params()[1] = int_lit_node;
26012707
2602 as_node.rparen_token = try appendToken(rp.c, .RParen, ")");2708 as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
26032709
...@@ -2653,12 +2759,11 @@ fn transCharLiteral(...@@ -2653,12 +2759,11 @@ fn transCharLiteral(
2653 // See comment in `transIntegerLiteral` for why this code is here.2759 // See comment in `transIntegerLiteral` for why this code is here.
2654 // @as(T, x)2760 // @as(T, x)
2655 const expr_base = @ptrCast(*const ZigClangExpr, stmt);2761 const expr_base = @ptrCast(*const ZigClangExpr, stmt);
2656 const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");2762 const as_node = try rp.c.createBuiltinCall("@as", 2);
2657 const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base));2763 const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base));
2658 try as_node.params.push(ty_node);2764 as_node.params()[0] = ty_node;
2659 _ = try appendToken(rp.c, .Comma, ",");2765 _ = try appendToken(rp.c, .Comma, ",");
26602766 as_node.params()[1] = int_lit_node;
2661 try as_node.params.push(int_lit_node);
26622767
2663 as_node.rparen_token = try appendToken(rp.c, .RParen, ")");2768 as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
2664 return maybeSuppressResult(rp, scope, result_used, &as_node.base);2769 return maybeSuppressResult(rp, scope, result_used, &as_node.base);
...@@ -2671,26 +2776,24 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr,...@@ -2671,26 +2776,24 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr,
2671 }2776 }
2672 const lparen = try appendToken(rp.c, .LParen, "(");2777 const lparen = try appendToken(rp.c, .LParen, "(");
2673 const block_scope = try Scope.Block.init(rp.c, scope, "blk");2778 const block_scope = try Scope.Block.init(rp.c, scope, "blk");
2674 const block = try transCreateNodeBlock(rp.c, "blk");2779 defer block_scope.deinit();
2675 block_scope.setBlockNode(block);
26762780
2677 var it = ZigClangCompoundStmt_body_begin(comp);2781 var it = ZigClangCompoundStmt_body_begin(comp);
2678 const end_it = ZigClangCompoundStmt_body_end(comp);2782 const end_it = ZigClangCompoundStmt_body_end(comp);
2679 while (it != end_it - 1) : (it += 1) {2783 while (it != end_it - 1) : (it += 1) {
2680 const result = try transStmt(rp, &block_scope.base, it[0], .unused, .r_value);2784 const result = try transStmt(rp, &block_scope.base, it[0], .unused, .r_value);
2681 if (result != &block.base)2785 try block_scope.statements.append(result);
2682 try block.statements.push(result);
2683 }2786 }
2684 const break_node = try transCreateNodeBreak(rp.c, "blk");2787 const break_node = try transCreateNodeBreak(rp.c, "blk");
2685 break_node.rhs = try transStmt(rp, &block_scope.base, it[0], .used, .r_value);2788 break_node.rhs = try transStmt(rp, &block_scope.base, it[0], .used, .r_value);
2686 _ = try appendToken(rp.c, .Semicolon, ";");2789 _ = try appendToken(rp.c, .Semicolon, ";");
2687 try block.statements.push(&break_node.base);2790 try block_scope.statements.append(&break_node.base);
2688 block.rbrace = try appendToken(rp.c, .RBrace, "}");2791 const block_node = try block_scope.complete(rp.c);
2689 const rparen = try appendToken(rp.c, .RParen, ")");2792 const rparen = try appendToken(rp.c, .RParen, ")");
2690 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);2793 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
2691 grouped_expr.* = .{2794 grouped_expr.* = .{
2692 .lparen = lparen,2795 .lparen = lparen,
2693 .expr = &block.base,2796 .expr = &block_node.base,
2694 .rparen = rparen,2797 .rparen = rparen,
2695 };2798 };
2696 return maybeSuppressResult(rp, scope, used, &grouped_expr.base);2799 return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
...@@ -2746,12 +2849,12 @@ fn transArrayAccess(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangArrayS...@@ -2746,12 +2849,12 @@ fn transArrayAccess(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangArrayS
2746 const is_signed = cIsSignedInteger(qt);2849 const is_signed = cIsSignedInteger(qt);
27472850
2748 if (is_longlong or is_signed) {2851 if (is_longlong or is_signed) {
2749 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");2852 const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
2750 // check if long long first so that signed long long doesn't just become unsigned long long2853 // check if long long first so that signed long long doesn't just become unsigned long long
2751 var typeid_node = if (is_longlong) try transCreateNodeIdentifier(rp.c, "usize") else try transQualTypeIntWidthOf(rp.c, qt, false);2854 var typeid_node = if (is_longlong) try transCreateNodeIdentifier(rp.c, "usize") else try transQualTypeIntWidthOf(rp.c, qt, false);
2752 try cast_node.params.push(typeid_node);2855 cast_node.params()[0] = typeid_node;
2753 _ = try appendToken(rp.c, .Comma, ",");2856 _ = try appendToken(rp.c, .Comma, ",");
2754 try cast_node.params.push(try transExpr(rp, scope, subscr_expr, .used, .r_value));2857 cast_node.params()[1] = try transExpr(rp, scope, subscr_expr, .used, .r_value);
2755 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");2858 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
2756 node.rtoken = try appendToken(rp.c, .RBrace, "]");2859 node.rtoken = try appendToken(rp.c, .RBrace, "]");
2757 node.op.ArrayAccess = &cast_node.base;2860 node.op.ArrayAccess = &cast_node.base;
...@@ -2787,17 +2890,18 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr,...@@ -2787,17 +2890,18 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr,
2787 break :blk try transCreateNodeUnwrapNull(rp.c, raw_fn_expr);2890 break :blk try transCreateNodeUnwrapNull(rp.c, raw_fn_expr);
2788 } else2891 } else
2789 raw_fn_expr;2892 raw_fn_expr;
2790 const node = try transCreateNodeFnCall(rp.c, fn_expr);
27912893
2792 const num_args = ZigClangCallExpr_getNumArgs(stmt);2894 const num_args = ZigClangCallExpr_getNumArgs(stmt);
2895 const node = try c.createCall(fn_expr, num_args);
2896 const call_params = node.params();
2897
2793 const args = ZigClangCallExpr_getArgs(stmt);2898 const args = ZigClangCallExpr_getArgs(stmt);
2794 var i: usize = 0;2899 var i: usize = 0;
2795 while (i < num_args) : (i += 1) {2900 while (i < num_args) : (i += 1) {
2796 if (i != 0) {2901 if (i != 0) {
2797 _ = try appendToken(rp.c, .Comma, ",");2902 _ = try appendToken(rp.c, .Comma, ",");
2798 }2903 }
2799 const arg = try transExpr(rp, scope, args[i], .used, .r_value);2904 call_params[i] = try transExpr(rp, scope, args[i], .used, .r_value);
2800 try node.op.Call.params.push(arg);
2801 }2905 }
2802 node.rtoken = try appendToken(rp.c, .RParen, ")");2906 node.rtoken = try appendToken(rp.c, .RParen, ")");
28032907
...@@ -2856,8 +2960,8 @@ fn transUnaryExprOrTypeTraitExpr(...@@ -2856,8 +2960,8 @@ fn transUnaryExprOrTypeTraitExpr(
2856 ZigClangUnaryExprOrTypeTraitExpr_getBeginLoc(stmt),2960 ZigClangUnaryExprOrTypeTraitExpr_getBeginLoc(stmt),
2857 );2961 );
28582962
2859 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@sizeOf");2963 const builtin_node = try rp.c.createBuiltinCall("@sizeOf", 1);
2860 try builtin_node.params.push(type_node);2964 builtin_node.params()[0] = type_node;
2861 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");2965 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
2862 return maybeSuppressResult(rp, scope, result_used, &builtin_node.base);2966 return maybeSuppressResult(rp, scope, result_used, &builtin_node.base);
2863}2967}
...@@ -2966,8 +3070,8 @@ fn transCreatePreCrement(...@@ -2966,8 +3070,8 @@ fn transCreatePreCrement(
2966 // zig: _ref.* += 1;3070 // zig: _ref.* += 1;
2967 // zig: break :blk _ref.*3071 // zig: break :blk _ref.*
2968 // zig: })3072 // zig: })
2969 const block_scope = try Scope.Block.init(rp.c, scope, "blk");3073 var block_scope = try Scope.Block.init(rp.c, scope, "blk");
2970 block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));3074 defer block_scope.deinit();
2971 const ref = try block_scope.makeMangledName(rp.c, "ref");3075 const ref = try block_scope.makeMangledName(rp.c, "ref");
29723076
2973 const node = try transCreateNodeVarDecl(rp.c, false, true, ref);3077 const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
...@@ -2976,7 +3080,7 @@ fn transCreatePreCrement(...@@ -2976,7 +3080,7 @@ fn transCreatePreCrement(
2976 rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value);3080 rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value);
2977 node.init_node = &rhs_node.base;3081 node.init_node = &rhs_node.base;
2978 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");3082 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
2979 try block_scope.block_node.statements.push(&node.base);3083 try block_scope.statements.append(&node.base);
29803084
2981 const lhs_node = try transCreateNodeIdentifier(rp.c, ref);3085 const lhs_node = try transCreateNodeIdentifier(rp.c, ref);
2982 const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);3086 const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);
...@@ -2985,18 +3089,18 @@ fn transCreatePreCrement(...@@ -2985,18 +3089,18 @@ fn transCreatePreCrement(
2985 const one = try transCreateNodeInt(rp.c, 1);3089 const one = try transCreateNodeInt(rp.c, 1);
2986 _ = try appendToken(rp.c, .Semicolon, ";");3090 _ = try appendToken(rp.c, .Semicolon, ";");
2987 const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false);3091 const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false);
2988 try block_scope.block_node.statements.push(assign);3092 try block_scope.statements.append(assign);
29893093
2990 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);3094 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
2991 break_node.rhs = ref_node;3095 break_node.rhs = ref_node;
2992 try block_scope.block_node.statements.push(&break_node.base);3096 try block_scope.statements.push(&break_node.base);
2993 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");3097 const block_node = try block_scope.complete(rp.c);
2994 // semicolon must immediately follow rbrace because it is the last token in a block3098 // semicolon must immediately follow rbrace because it is the last token in a block
2995 _ = try appendToken(rp.c, .Semicolon, ";");3099 _ = try appendToken(rp.c, .Semicolon, ";");
2996 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);3100 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
2997 grouped_expr.* = .{3101 grouped_expr.* = .{
2998 .lparen = try appendToken(rp.c, .LParen, "("),3102 .lparen = try appendToken(rp.c, .LParen, "("),
2999 .expr = &block_scope.block_node.base,3103 .expr = &block_node.base,
3000 .rparen = try appendToken(rp.c, .RParen, ")"),3104 .rparen = try appendToken(rp.c, .RParen, ")"),
3001 };3105 };
3002 return &grouped_expr.base;3106 return &grouped_expr.base;
...@@ -3032,8 +3136,8 @@ fn transCreatePostCrement(...@@ -3032,8 +3136,8 @@ fn transCreatePostCrement(
3032 // zig: _ref.* += 1;3136 // zig: _ref.* += 1;
3033 // zig: break :blk _tmp3137 // zig: break :blk _tmp
3034 // zig: })3138 // zig: })
3035 const block_scope = try Scope.Block.init(rp.c, scope, "blk");3139 var block_scope = try Scope.Block.init(rp.c, scope, "blk");
3036 block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));3140 defer block_scope.deinit();
3037 const ref = try block_scope.makeMangledName(rp.c, "ref");3141 const ref = try block_scope.makeMangledName(rp.c, "ref");
30383142
3039 const node = try transCreateNodeVarDecl(rp.c, false, true, ref);3143 const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
...@@ -3042,7 +3146,7 @@ fn transCreatePostCrement(...@@ -3042,7 +3146,7 @@ fn transCreatePostCrement(
3042 rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value);3146 rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value);
3043 node.init_node = &rhs_node.base;3147 node.init_node = &rhs_node.base;
3044 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");3148 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
3045 try block_scope.block_node.statements.push(&node.base);3149 try block_scope.statements.push(&node.base);
30463150
3047 const lhs_node = try transCreateNodeIdentifier(rp.c, ref);3151 const lhs_node = try transCreateNodeIdentifier(rp.c, ref);
3048 const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);3152 const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);
...@@ -3053,23 +3157,23 @@ fn transCreatePostCrement(...@@ -3053,23 +3157,23 @@ fn transCreatePostCrement(
3053 tmp_node.eq_token = try appendToken(rp.c, .Equal, "=");3157 tmp_node.eq_token = try appendToken(rp.c, .Equal, "=");
3054 tmp_node.init_node = ref_node;3158 tmp_node.init_node = ref_node;
3055 tmp_node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");3159 tmp_node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
3056 try block_scope.block_node.statements.push(&tmp_node.base);3160 try block_scope.statements.push(&tmp_node.base);
30573161
3058 const token = try appendToken(rp.c, op_tok_id, bytes);3162 const token = try appendToken(rp.c, op_tok_id, bytes);
3059 const one = try transCreateNodeInt(rp.c, 1);3163 const one = try transCreateNodeInt(rp.c, 1);
3060 _ = try appendToken(rp.c, .Semicolon, ";");3164 _ = try appendToken(rp.c, .Semicolon, ";");
3061 const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false);3165 const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false);
3062 try block_scope.block_node.statements.push(assign);3166 try block_scope.statements.push(assign);
30633167
3064 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);3168 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
3065 break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp);3169 break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp);
3066 try block_scope.block_node.statements.push(&break_node.base);3170 try block_scope.statements.push(&break_node.base);
3067 _ = try appendToken(rp.c, .Semicolon, ";");3171 _ = try appendToken(rp.c, .Semicolon, ";");
3068 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");3172 const block_node = try block_scope.complete(rp.c);
3069 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);3173 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
3070 grouped_expr.* = .{3174 grouped_expr.* = .{
3071 .lparen = try appendToken(rp.c, .LParen, "("),3175 .lparen = try appendToken(rp.c, .LParen, "("),
3072 .expr = &block_scope.block_node.base,3176 .expr = &block_node.base,
3073 .rparen = try appendToken(rp.c, .RParen, ")"),3177 .rparen = try appendToken(rp.c, .RParen, ")"),
3074 };3178 };
3075 return &grouped_expr.base;3179 return &grouped_expr.base;
...@@ -3134,11 +3238,11 @@ fn transCreateCompoundAssign(...@@ -3134,11 +3238,11 @@ fn transCreateCompoundAssign(
3134 const op_token = try appendToken(rp.c, .Equal, "=");3238 const op_token = try appendToken(rp.c, .Equal, "=");
3135 const op_node = try rp.c.arena.create(ast.Node.InfixOp);3239 const op_node = try rp.c.arena.create(ast.Node.InfixOp);
3136 const builtin = if (is_mod) "@rem" else "@divTrunc";3240 const builtin = if (is_mod) "@rem" else "@divTrunc";
3137 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, builtin);3241 const builtin_node = try rp.c.createBuiltinCall(builtin, 2);
3138 const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);3242 const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
3139 try builtin_node.params.push(lhs_node);3243 builtin_node.params()[0] = lhs_node;
3140 _ = try appendToken(rp.c, .Comma, ",");3244 _ = try appendToken(rp.c, .Comma, ",");
3141 try builtin_node.params.push(try transExpr(rp, scope, rhs, .used, .r_value));3245 builtin_node.params()[1] = try transExpr(rp, scope, rhs, .used, .r_value);
3142 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");3246 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
3143 op_node.* = .{3247 op_node.* = .{
3144 .op_token = op_token,3248 .op_token = op_token,
...@@ -3158,11 +3262,11 @@ fn transCreateCompoundAssign(...@@ -3158,11 +3262,11 @@ fn transCreateCompoundAssign(
3158 try transExpr(rp, scope, rhs, .used, .r_value);3262 try transExpr(rp, scope, rhs, .used, .r_value);
31593263
3160 if (is_shift) {3264 if (is_shift) {
3161 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");3265 const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
3162 const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc);3266 const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc);
3163 try cast_node.params.push(rhs_type);3267 cast_node.params()[0] = rhs_type;
3164 _ = try appendToken(rp.c, .Comma, ",");3268 _ = try appendToken(rp.c, .Comma, ",");
3165 try cast_node.params.push(rhs_node);3269 cast_node.params()[1] = rhs_node;
3166 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");3270 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
3167 rhs_node = &cast_node.base;3271 rhs_node = &cast_node.base;
3168 }3272 }
...@@ -3177,8 +3281,8 @@ fn transCreateCompoundAssign(...@@ -3177,8 +3281,8 @@ fn transCreateCompoundAssign(
3177 // zig: _ref.* = _ref.* + rhs;3281 // zig: _ref.* = _ref.* + rhs;
3178 // zig: break :blk _ref.*3282 // zig: break :blk _ref.*
3179 // zig: })3283 // zig: })
3180 const block_scope = try Scope.Block.init(rp.c, scope, "blk");3284 var block_scope = try Scope.Block.init(rp.c, scope, "blk");
3181 block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));3285 defer block_scope.deinit();
3182 const ref = try block_scope.makeMangledName(rp.c, "ref");3286 const ref = try block_scope.makeMangledName(rp.c, "ref");
31833287
3184 const node = try transCreateNodeVarDecl(rp.c, false, true, ref);3288 const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
...@@ -3187,7 +3291,7 @@ fn transCreateCompoundAssign(...@@ -3187,7 +3291,7 @@ fn transCreateCompoundAssign(
3187 addr_node.rhs = try transExpr(rp, scope, lhs, .used, .l_value);3291 addr_node.rhs = try transExpr(rp, scope, lhs, .used, .l_value);
3188 node.init_node = &addr_node.base;3292 node.init_node = &addr_node.base;
3189 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");3293 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
3190 try block_scope.block_node.statements.push(&node.base);3294 try block_scope.statements.append(&node.base);
31913295
3192 const lhs_node = try transCreateNodeIdentifier(rp.c, ref);3296 const lhs_node = try transCreateNodeIdentifier(rp.c, ref);
3193 const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);3297 const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);
...@@ -3197,10 +3301,10 @@ fn transCreateCompoundAssign(...@@ -3197,10 +3301,10 @@ fn transCreateCompoundAssign(
3197 const op_token = try appendToken(rp.c, .Equal, "=");3301 const op_token = try appendToken(rp.c, .Equal, "=");
3198 const op_node = try rp.c.arena.create(ast.Node.InfixOp);3302 const op_node = try rp.c.arena.create(ast.Node.InfixOp);
3199 const builtin = if (is_mod) "@rem" else "@divTrunc";3303 const builtin = if (is_mod) "@rem" else "@divTrunc";
3200 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, builtin);3304 const builtin_node = try rp.c.createBuiltinCall(builtin, 2);
3201 try builtin_node.params.push(try transCreateNodePtrDeref(rp.c, lhs_node));3305 builtin_node.params()[0] = try transCreateNodePtrDeref(rp.c, lhs_node);
3202 _ = try appendToken(rp.c, .Comma, ",");3306 _ = try appendToken(rp.c, .Comma, ",");
3203 try builtin_node.params.push(try transExpr(rp, scope, rhs, .used, .r_value));3307 builtin_node.params()[1] = try transExpr(rp, scope, rhs, .used, .r_value);
3204 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");3308 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
3205 _ = try appendToken(rp.c, .Semicolon, ";");3309 _ = try appendToken(rp.c, .Semicolon, ";");
3206 op_node.* = .{3310 op_node.* = .{
...@@ -3210,17 +3314,17 @@ fn transCreateCompoundAssign(...@@ -3210,17 +3314,17 @@ fn transCreateCompoundAssign(
3210 .rhs = &builtin_node.base,3314 .rhs = &builtin_node.base,
3211 };3315 };
3212 _ = try appendToken(rp.c, .Semicolon, ";");3316 _ = try appendToken(rp.c, .Semicolon, ";");
3213 try block_scope.block_node.statements.push(&op_node.base);3317 try block_scope.statements.append(&op_node.base);
3214 } else {3318 } else {
3215 const bin_token = try appendToken(rp.c, bin_tok_id, bin_bytes);3319 const bin_token = try appendToken(rp.c, bin_tok_id, bin_bytes);
3216 var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);3320 var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
32173321
3218 if (is_shift) {3322 if (is_shift) {
3219 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");3323 const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
3220 const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc);3324 const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc);
3221 try cast_node.params.push(rhs_type);3325 cast_node.params()[0] = rhs_type;
3222 _ = try appendToken(rp.c, .Comma, ",");3326 _ = try appendToken(rp.c, .Comma, ",");
3223 try cast_node.params.push(rhs_node);3327 cast_node.params()[1] = rhs_node;
3224 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");3328 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
3225 rhs_node = &cast_node.base;3329 rhs_node = &cast_node.base;
3226 }3330 }
...@@ -3230,17 +3334,17 @@ fn transCreateCompoundAssign(...@@ -3230,17 +3334,17 @@ fn transCreateCompoundAssign(
32303334
3231 const eq_token = try appendToken(rp.c, .Equal, "=");3335 const eq_token = try appendToken(rp.c, .Equal, "=");
3232 const assign = try transCreateNodeInfixOp(rp, scope, ref_node, .Assign, eq_token, rhs_bin, .used, false);3336 const assign = try transCreateNodeInfixOp(rp, scope, ref_node, .Assign, eq_token, rhs_bin, .used, false);
3233 try block_scope.block_node.statements.push(assign);3337 try block_scope.statements.append(assign);
3234 }3338 }
32353339
3236 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);3340 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
3237 break_node.rhs = ref_node;3341 break_node.rhs = ref_node;
3238 try block_scope.block_node.statements.push(&break_node.base);3342 try block_scope.statements.append(&break_node.base);
3239 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");3343 const block_node = try block_scope.complete(rp.c);
3240 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);3344 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
3241 grouped_expr.* = .{3345 grouped_expr.* = .{
3242 .lparen = try appendToken(rp.c, .LParen, "("),3346 .lparen = try appendToken(rp.c, .LParen, "("),
3243 .expr = &block_scope.block_node.base,3347 .expr = &block_node.base,
3244 .rparen = try appendToken(rp.c, .RParen, ")"),3348 .rparen = try appendToken(rp.c, .RParen, ")"),
3245 };3349 };
3246 return &grouped_expr.base;3350 return &grouped_expr.base;
...@@ -3264,43 +3368,43 @@ fn transCPtrCast(...@@ -3264,43 +3368,43 @@ fn transCPtrCast(
3264 !ZigClangQualType_isVolatileQualified(child_type)))3368 !ZigClangQualType_isVolatileQualified(child_type)))
3265 {3369 {
3266 // Casting away const or volatile requires us to use @intToPtr3370 // Casting away const or volatile requires us to use @intToPtr
3267 const inttoptr_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr");3371 const inttoptr_node = try rp.c.createBuiltinCall("@intToPtr", 2);
3268 const dst_type_node = try transType(rp, ty, loc);3372 const dst_type_node = try transType(rp, ty, loc);
3269 try inttoptr_node.params.push(dst_type_node);3373 inttoptr_node.params()[0] = dst_type_node;
3270 _ = try appendToken(rp.c, .Comma, ",");3374 _ = try appendToken(rp.c, .Comma, ",");
32713375
3272 const ptrtoint_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");3376 const ptrtoint_node = try rp.c.createBuiltinCall("@ptrToInt", 1);
3273 try ptrtoint_node.params.push(expr);3377 ptrtoint_node.params()[0] = expr;
3274 ptrtoint_node.rparen_token = try appendToken(rp.c, .RParen, ")");3378 ptrtoint_node.rparen_token = try appendToken(rp.c, .RParen, ")");
32753379
3276 try inttoptr_node.params.push(&ptrtoint_node.base);3380 inttoptr_node.params()[1] = &ptrtoint_node.base;
3277 inttoptr_node.rparen_token = try appendToken(rp.c, .RParen, ")");3381 inttoptr_node.rparen_token = try appendToken(rp.c, .RParen, ")");
3278 return &inttoptr_node.base;3382 return &inttoptr_node.base;
3279 } else {3383 } else {
3280 // Implicit downcasting from higher to lower alignment values is forbidden,3384 // Implicit downcasting from higher to lower alignment values is forbidden,
3281 // use @alignCast to side-step this problem3385 // use @alignCast to side-step this problem
3282 const ptrcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrCast");3386 const ptrcast_node = try rp.c.createBuiltinCall("@ptrCast", 2);
3283 const dst_type_node = try transType(rp, ty, loc);3387 const dst_type_node = try transType(rp, ty, loc);
3284 try ptrcast_node.params.push(dst_type_node);3388 ptrcast_node.params()[0] = dst_type_node;
3285 _ = try appendToken(rp.c, .Comma, ",");3389 _ = try appendToken(rp.c, .Comma, ",");
32863390
3287 if (ZigClangType_isVoidType(qualTypeCanon(child_type))) {3391 if (ZigClangType_isVoidType(qualTypeCanon(child_type))) {
3288 // void has 1-byte alignment, so @alignCast is not needed3392 // void has 1-byte alignment, so @alignCast is not needed
3289 try ptrcast_node.params.push(expr);3393 ptrcast_node.params()[1] = expr;
3290 } else if (typeIsOpaque(rp.c, qualTypeCanon(child_type), loc)) {3394 } else if (typeIsOpaque(rp.c, qualTypeCanon(child_type), loc)) {
3291 // For opaque types a ptrCast is enough3395 // For opaque types a ptrCast is enough
3292 try ptrcast_node.params.push(expr);3396 ptrcast_node.params()[1] = expr;
3293 } else {3397 } else {
3294 const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast");3398 const aligncast_node = try rp.c.createBuiltinCall("@alignCast", 2);
3295 const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf");3399 const alignof_node = try rp.c.createBuiltinCall("@alignOf", 1);
3296 const child_type_node = try transQualType(rp, child_type, loc);3400 const child_type_node = try transQualType(rp, child_type, loc);
3297 try alignof_node.params.push(child_type_node);3401 alignof_node.params()[0] = child_type_node;
3298 alignof_node.rparen_token = try appendToken(rp.c, .RParen, ")");3402 alignof_node.rparen_token = try appendToken(rp.c, .RParen, ")");
3299 try aligncast_node.params.push(&alignof_node.base);3403 aligncast_node.params()[0] = &alignof_node.base;
3300 _ = try appendToken(rp.c, .Comma, ",");3404 _ = try appendToken(rp.c, .Comma, ",");
3301 try aligncast_node.params.push(expr);3405 aligncast_node.params()[1] = expr;
3302 aligncast_node.rparen_token = try appendToken(rp.c, .RParen, ")");3406 aligncast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
3303 try ptrcast_node.params.push(&aligncast_node.base);3407 ptrcast_node.params()[1] = &aligncast_node.base;
3304 }3408 }
3305 ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")");3409 ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
33063410
...@@ -3343,27 +3447,30 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const...@@ -3343,27 +3447,30 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const
3343 // })3447 // })
3344 const lparen = try appendToken(rp.c, .LParen, "(");3448 const lparen = try appendToken(rp.c, .LParen, "(");
33453449
3346 const block_scope = try Scope.Block.init(rp.c, scope, "blk");3450 var block_scope = try Scope.Block.init(rp.c, scope, "blk");
3347 block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));3451 defer block_scope.deinit();
33483452
3349 const mangled_name = try block_scope.makeMangledName(rp.c, "cond_temp");3453 const mangled_name = try block_scope.makeMangledName(rp.c, "cond_temp");
3350 const tmp_var = try transCreateNodeVarDecl(rp.c, false, true, mangled_name);3454 const tmp_var = try transCreateNodeVarDecl(rp.c, false, true, mangled_name);
3351 tmp_var.eq_token = try appendToken(rp.c, .Equal, "=");3455 tmp_var.eq_token = try appendToken(rp.c, .Equal, "=");
3352 tmp_var.init_node = try transExpr(rp, &block_scope.base, cond_expr, .used, .r_value);3456 tmp_var.init_node = try transExpr(rp, &block_scope.base, cond_expr, .used, .r_value);
3353 tmp_var.semicolon_token = try appendToken(rp.c, .Semicolon, ";");3457 tmp_var.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
3354 try block_scope.block_node.statements.push(&tmp_var.base);3458 try block_scope.statements.append(&tmp_var.base);
33553459
3356 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);3460 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
33573461
3358 const if_node = try transCreateNodeIf(rp.c);3462 const if_node = try transCreateNodeIf(rp.c);
3359 var cond_scope = Scope{3463 var cond_scope = Scope.Condition{
3360 .parent = &block_scope.base,3464 .base = .{
3361 .id = .Condition,3465 .parent = &block_scope.base,
3466 .id = .Condition,
3467 },
3362 };3468 };
3469 defer cond_scope.deinit();
3363 const tmp_var_node = try transCreateNodeIdentifier(rp.c, mangled_name);3470 const tmp_var_node = try transCreateNodeIdentifier(rp.c, mangled_name);
33643471
3365 const ty = ZigClangQualType_getTypePtr(getExprQualType(rp.c, cond_expr));3472 const ty = ZigClangQualType_getTypePtr(getExprQualType(rp.c, cond_expr));
3366 const cond_node = try finishBoolExpr(rp, &block_scope.base, ZigClangExpr_getBeginLoc(cond_expr), ty, tmp_var_node, used);3473 const cond_node = try finishBoolExpr(rp, &cond_scope.base, ZigClangExpr_getBeginLoc(cond_expr), ty, tmp_var_node, used);
3367 if_node.condition = cond_node;3474 if_node.condition = cond_node;
3368 _ = try appendToken(rp.c, .RParen, ")");3475 _ = try appendToken(rp.c, .RParen, ")");
33693476
...@@ -3374,13 +3481,13 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const...@@ -3374,13 +3481,13 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const
33743481
3375 break_node.rhs = &if_node.base;3482 break_node.rhs = &if_node.base;
3376 _ = try appendToken(rp.c, .Semicolon, ";");3483 _ = try appendToken(rp.c, .Semicolon, ";");
3377 try block_scope.block_node.statements.push(&break_node.base);3484 try block_scope.statements.append(&break_node.base);
3378 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");3485 const block_node = block_scope.complete(rp.c);
33793486
3380 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);3487 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
3381 grouped_expr.* = .{3488 grouped_expr.* = .{
3382 .lparen = lparen,3489 .lparen = lparen,
3383 .expr = &block_scope.block_node.base,3490 .expr = &block_node.base,
3384 .rparen = try appendToken(rp.c, .RParen, ")"),3491 .rparen = try appendToken(rp.c, .RParen, ")"),
3385 };3492 };
3386 return maybeSuppressResult(rp, scope, used, &grouped_expr.base);3493 return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
...@@ -3390,17 +3497,20 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla...@@ -3390,17 +3497,20 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla
3390 const grouped = scope.id == .Condition;3497 const grouped = scope.id == .Condition;
3391 const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined;3498 const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined;
3392 const if_node = try transCreateNodeIf(rp.c);3499 const if_node = try transCreateNodeIf(rp.c);
3393 var cond_scope = Scope{3500 var cond_scope = Scope.Condition{
3394 .parent = scope,3501 .base = .{
3395 .id = .Condition,3502 .parent = scope,
3503 .id = .Condition,
3504 },
3396 };3505 };
3506 defer cond_scope.deinit();
33973507
3398 const casted_stmt = @ptrCast(*const ZigClangAbstractConditionalOperator, stmt);3508 const casted_stmt = @ptrCast(*const ZigClangAbstractConditionalOperator, stmt);
3399 const cond_expr = ZigClangAbstractConditionalOperator_getCond(casted_stmt);3509 const cond_expr = ZigClangAbstractConditionalOperator_getCond(casted_stmt);
3400 const true_expr = ZigClangAbstractConditionalOperator_getTrueExpr(casted_stmt);3510 const true_expr = ZigClangAbstractConditionalOperator_getTrueExpr(casted_stmt);
3401 const false_expr = ZigClangAbstractConditionalOperator_getFalseExpr(casted_stmt);3511 const false_expr = ZigClangAbstractConditionalOperator_getFalseExpr(casted_stmt);
34023512
3403 if_node.condition = try transBoolExpr(rp, &cond_scope, cond_expr, .used, .r_value, false);3513 if_node.condition = try transBoolExpr(rp, &cond_scope.base, cond_expr, .used, .r_value, false);
3404 _ = try appendToken(rp.c, .RParen, ")");3514 _ = try appendToken(rp.c, .RParen, ")");
34053515
3406 if_node.body = try transExpr(rp, scope, true_expr, .used, .r_value);3516 if_node.body = try transExpr(rp, scope, true_expr, .used, .r_value);
...@@ -3571,19 +3681,19 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC...@@ -3571,19 +3681,19 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC
3571 // Symbol "Log2Int"3681 // Symbol "Log2Int"
3572 // Symbol <zig_type_node> (var from above)3682 // Symbol <zig_type_node> (var from above)
35733683
3574 const import_fn_call = try transCreateNodeBuiltinFnCall(rp.c, "@import");3684 const import_fn_call = try rp.c.createBuiltinCall("@import", 1);
3575 const std_token = try appendToken(rp.c, .StringLiteral, "\"std\"");3685 const std_token = try appendToken(rp.c, .StringLiteral, "\"std\"");
3576 const std_node = try rp.c.arena.create(ast.Node.StringLiteral);3686 const std_node = try rp.c.arena.create(ast.Node.StringLiteral);
3577 std_node.* = .{3687 std_node.* = .{
3578 .token = std_token,3688 .token = std_token,
3579 };3689 };
3580 try import_fn_call.params.push(&std_node.base);3690 import_fn_call.params()[0] = &std_node.base;
3581 import_fn_call.rparen_token = try appendToken(rp.c, .RParen, ")");3691 import_fn_call.rparen_token = try appendToken(rp.c, .RParen, ")");
35823692
3583 const inner_field_access = try transCreateNodeFieldAccess(rp.c, &import_fn_call.base, "math");3693 const inner_field_access = try transCreateNodeFieldAccess(rp.c, &import_fn_call.base, "math");
3584 const outer_field_access = try transCreateNodeFieldAccess(rp.c, inner_field_access, "Log2Int");3694 const outer_field_access = try transCreateNodeFieldAccess(rp.c, inner_field_access, "Log2Int");
3585 const log2int_fn_call = try transCreateNodeFnCall(rp.c, outer_field_access);3695 const log2int_fn_call = try rp.c.createCall(outer_field_access, 1);
3586 try @fieldParentPtr(ast.Node.SuffixOp, "base", &log2int_fn_call.base).op.Call.params.push(zig_type_node);3696 log2int_fn_call.params()[0] = zig_type_node;
3587 log2int_fn_call.rtoken = try appendToken(rp.c, .RParen, ")");3697 log2int_fn_call.rtoken = try appendToken(rp.c, .RParen, ")");
35883698
3589 return &log2int_fn_call.base;3699 return &log2int_fn_call.base;
...@@ -3757,8 +3867,8 @@ fn transCreateNodeAssign(...@@ -3757,8 +3867,8 @@ fn transCreateNodeAssign(
3757 const eq_token = try appendToken(rp.c, .Equal, "=");3867 const eq_token = try appendToken(rp.c, .Equal, "=");
3758 var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value);3868 var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value);
3759 if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {3869 if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {
3760 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");3870 const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
3761 try builtin_node.params.push(rhs_node);3871 builtin_node.params()[0] = rhs_node;
3762 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");3872 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
3763 rhs_node = &builtin_node.base;3873 rhs_node = &builtin_node.base;
3764 }3874 }
...@@ -3774,22 +3884,23 @@ fn transCreateNodeAssign(...@@ -3774,22 +3884,23 @@ fn transCreateNodeAssign(
3774 // zig: lhs = _tmp;3884 // zig: lhs = _tmp;
3775 // zig: break :blk _tmp3885 // zig: break :blk _tmp
3776 // zig: })3886 // zig: })
3777 const block_scope = try Scope.Block.init(rp.c, scope, "blk");3887 var block_scope = try Scope.Block.init(rp.c, scope, "blk");
3778 block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));3888 defer block_scope.deinit();
3889
3779 const tmp = try block_scope.makeMangledName(rp.c, "tmp");3890 const tmp = try block_scope.makeMangledName(rp.c, "tmp");
37803891
3781 const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);3892 const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);
3782 node.eq_token = try appendToken(rp.c, .Equal, "=");3893 node.eq_token = try appendToken(rp.c, .Equal, "=");
3783 var rhs_node = try transExpr(rp, &block_scope.base, rhs, .used, .r_value);3894 var rhs_node = try transExpr(rp, &block_scope.base, rhs, .used, .r_value);
3784 if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {3895 if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {
3785 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");3896 const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
3786 try builtin_node.params.push(rhs_node);3897 builtin_node.params()[0] = rhs_node;
3787 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");3898 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
3788 rhs_node = &builtin_node.base;3899 rhs_node = &builtin_node.base;
3789 }3900 }
3790 node.init_node = rhs_node;3901 node.init_node = rhs_node;
3791 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");3902 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
3792 try block_scope.block_node.statements.push(&node.base);3903 try block_scope.statements.append(&node.base);
37933904
3794 const lhs_node = try transExpr(rp, &block_scope.base, lhs, .used, .l_value);3905 const lhs_node = try transExpr(rp, &block_scope.base, lhs, .used, .l_value);
3795 const eq_token = try appendToken(rp.c, .Equal, "=");3906 const eq_token = try appendToken(rp.c, .Equal, "=");
...@@ -3797,44 +3908,16 @@ fn transCreateNodeAssign(...@@ -3797,44 +3908,16 @@ fn transCreateNodeAssign(
3797 _ = try appendToken(rp.c, .Semicolon, ";");3908 _ = try appendToken(rp.c, .Semicolon, ";");
37983909
3799 const assign = try transCreateNodeInfixOp(rp, &block_scope.base, lhs_node, .Assign, eq_token, ident, .used, false);3910 const assign = try transCreateNodeInfixOp(rp, &block_scope.base, lhs_node, .Assign, eq_token, ident, .used, false);
3800 try block_scope.block_node.statements.push(assign);3911 try block_scope.statements.append(assign);
38013912
3802 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);3913 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
3803 break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp);3914 break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp);
3804 _ = try appendToken(rp.c, .Semicolon, ";");3915 _ = try appendToken(rp.c, .Semicolon, ";");
3805 try block_scope.block_node.statements.push(&break_node.base);3916 try block_scope.statements.append(&break_node.base);
3806 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");3917 const block_node = try block_scope.complete(rp.c);
3807 // semicolon must immediately follow rbrace because it is the last token in a block3918 // semicolon must immediately follow rbrace because it is the last token in a block
3808 _ = try appendToken(rp.c, .Semicolon, ";");3919 _ = try appendToken(rp.c, .Semicolon, ";");
3809 return &block_scope.block_node.base;3920 return &block_node.base;
3810}
3811
3812fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.BuiltinCall {
3813 const builtin_token = try appendToken(c, .Builtin, name);
3814 _ = try appendToken(c, .LParen, "(");
3815 const node = try c.arena.create(ast.Node.BuiltinCall);
3816 node.* = .{
3817 .builtin_token = builtin_token,
3818 .params = ast.Node.BuiltinCall.ParamList{},
3819 .rparen_token = undefined, // set after appending args
3820 };
3821 return node;
3822}
3823
3824fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp {
3825 _ = try appendToken(c, .LParen, "(");
3826 const node = try c.arena.create(ast.Node.SuffixOp);
3827 node.* = .{
3828 .lhs = fn_expr,
3829 .op = .{
3830 .Call = .{
3831 .params = ast.Node.SuffixOp.Op.Call.ParamList{},
3832 .async_token = null,
3833 },
3834 },
3835 .rtoken = undefined, // set after appending args
3836 };
3837 return node;
3838}3921}
38393922
3840fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []const u8) !*ast.Node {3923fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []const u8) !*ast.Node {
...@@ -4083,8 +4166,8 @@ fn transCreateNodeFloat(c: *Context, int: var) !*ast.Node {...@@ -4083,8 +4166,8 @@ fn transCreateNodeFloat(c: *Context, int: var) !*ast.Node {
4083}4166}
40844167
4085fn transCreateNodeOpaqueType(c: *Context) !*ast.Node {4168fn transCreateNodeOpaqueType(c: *Context) !*ast.Node {
4086 const call_node = try transCreateNodeBuiltinFnCall(c, "@Type");4169 const call_node = try c.createBuiltinCall("@Type", 1);
4087 try call_node.params.push(try transCreateNodeEnumLiteral(c, "Opaque"));4170 call_node.params()[0] = try transCreateNodeEnumLiteral(c, "Opaque");
4088 call_node.rparen_token = try appendToken(c, .RParen, ")");4171 call_node.rparen_token = try appendToken(c, .RParen, ")");
4089 return &call_node.base;4172 return &call_node.base;
4090}4173}
...@@ -4139,26 +4222,33 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a...@@ -4139,26 +4222,33 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
4139 };4222 };
4140 mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items);4223 mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items);
41414224
4142 const block = try transCreateNodeBlock(c, null);4225 const block_lbrace = try appendToken(c, .LBrace, "{");
4143 var block_statements_it = &block.statements.first;
41444226
4145 const return_expr = try transCreateNodeReturnExpr(c);4227 const return_expr = try transCreateNodeReturnExpr(c);
4146 const unwrap_expr = try transCreateNodeUnwrapNull(c, ref.cast(ast.Node.VarDecl).?.init_node.?);4228 const unwrap_expr = try transCreateNodeUnwrapNull(c, ref.cast(ast.Node.VarDecl).?.init_node.?);
4147 const call_expr = try transCreateNodeFnCall(c, unwrap_expr);4229
4148 var call_params_it = &call_expr.op.Call.params.first;4230 const call_expr = try c.createCall(unwrap_expr, fn_params.items.len);
4231 const call_params = call_expr.params();
41494232
4150 for (fn_params.items) |param, i| {4233 for (fn_params.items) |param, i| {
4151 if (i != 0) {4234 if (i != 0) {
4152 _ = try appendToken(c, .Comma, ",");4235 _ = try appendToken(c, .Comma, ",");
4153 }4236 }
4154 call_params_it = try c.llpush(*ast.Node, call_params_it, try transCreateNodeIdentifier(c, tokenSlice(c, param.name_token.?)),);4237 call_params[i] = try transCreateNodeIdentifier(c, tokenSlice(c, param.name_token.?));
4155 }4238 }
4156 call_expr.rtoken = try appendToken(c, .RParen, ")");4239 call_expr.rtoken = try appendToken(c, .RParen, ")");
4240
4157 return_expr.rhs = &call_expr.base;4241 return_expr.rhs = &call_expr.base;
4158 _ = try appendToken(c, .Semicolon, ";");4242 _ = try appendToken(c, .Semicolon, ";");
41594243
4160 block.rbrace = try appendToken(c, .RBrace, "}");4244 const block = try ast.Node.Block.alloc(c.arena, 1);
4161 block_statements_it = try c.llpush(*ast.Node, block_statements_it, &return_expr.base);4245 block.* = .{
4246 .label = null,
4247 .lbrace = block_lbrace,
4248 .statements_len = 1,
4249 .rbrace = try appendToken(c, .RBrace, "}"),
4250 };
4251 block.statements()[0] = &return_expr.base;
4162 fn_proto.body_node = &block.base;4252 fn_proto.body_node = &block.base;
4163 return &fn_proto.base;4253 return &fn_proto.base;
4164}4254}
...@@ -4216,22 +4306,6 @@ fn transCreateNodeElse(c: *Context) !*ast.Node.Else {...@@ -4216,22 +4306,6 @@ fn transCreateNodeElse(c: *Context) !*ast.Node.Else {
4216 return node;4306 return node;
4217}4307}
42184308
4219fn transCreateNodeBlock(c: *Context, label: ?[]const u8) !*ast.Node.Block {
4220 const label_node = if (label) |l| blk: {
4221 const ll = try appendIdentifier(c, l);
4222 _ = try appendToken(c, .Colon, ":");
4223 break :blk ll;
4224 } else null;
4225 const block_node = try c.arena.create(ast.Node.Block);
4226 block_node.* = .{
4227 .label = label_node,
4228 .lbrace = try appendToken(c, .LBrace, "{"),
4229 .statements = ast.Node.Block.StatementList{},
4230 .rbrace = undefined,
4231 };
4232 return block_node;
4233}
4234
4235fn transCreateNodeBreak(c: *Context, label: ?[]const u8) !*ast.Node.ControlFlowExpression {4309fn transCreateNodeBreak(c: *Context, label: ?[]const u8) !*ast.Node.ControlFlowExpression {
4236 const ltoken = try appendToken(c, .Keyword_break, "break");4310 const ltoken = try appendToken(c, .Keyword_break, "break");
4237 const label_node = if (label) |l| blk: {4311 const label_node = if (label) |l| blk: {
...@@ -4302,20 +4376,6 @@ fn transCreateNodeContinue(c: *Context) !*ast.Node {...@@ -4302,20 +4376,6 @@ fn transCreateNodeContinue(c: *Context) !*ast.Node {
4302 return &node.base;4376 return &node.base;
4303}4377}
43044378
4305fn transCreateNodeSwitch(c: *Context) !*ast.Node.Switch {
4306 const switch_tok = try appendToken(c, .Keyword_switch, "switch");
4307 _ = try appendToken(c, .LParen, "(");
4308
4309 const node = try c.arena.create(ast.Node.Switch);
4310 node.* = .{
4311 .switch_token = switch_tok,
4312 .expr = undefined,
4313 .cases = ast.Node.Switch.CaseList{},
4314 .rbrace = undefined,
4315 };
4316 return node;
4317}
4318
4319fn transCreateNodeSwitchCase(c: *Context, lhs: *ast.Node) !*ast.Node.SwitchCase {4379fn transCreateNodeSwitchCase(c: *Context, lhs: *ast.Node) !*ast.Node.SwitchCase {
4320 const arrow_tok = try appendToken(c, .EqualAngleBracketRight, "=>");4380 const arrow_tok = try appendToken(c, .EqualAngleBracketRight, "=>");
43214381
...@@ -4356,12 +4416,12 @@ fn transCreateNodeShiftOp(...@@ -4356,12 +4416,12 @@ fn transCreateNodeShiftOp(
4356 const lhs = try transExpr(rp, scope, lhs_expr, .used, .l_value);4416 const lhs = try transExpr(rp, scope, lhs_expr, .used, .l_value);
4357 const op_token = try appendToken(rp.c, op_tok_id, bytes);4417 const op_token = try appendToken(rp.c, op_tok_id, bytes);
43584418
4359 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");4419 const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
4360 const rhs_type = try qualTypeToLog2IntRef(rp, ZigClangBinaryOperator_getType(stmt), rhs_location);4420 const rhs_type = try qualTypeToLog2IntRef(rp, ZigClangBinaryOperator_getType(stmt), rhs_location);
4361 try cast_node.params.push(rhs_type);4421 cast_node.params()[0] = rhs_type;
4362 _ = try appendToken(rp.c, .Comma, ",");4422 _ = try appendToken(rp.c, .Comma, ",");
4363 const rhs = try transExprCoercing(rp, scope, rhs_expr, .used, .r_value);4423 const rhs = try transExprCoercing(rp, scope, rhs_expr, .used, .r_value);
4364 try cast_node.params.push(rhs);4424 cast_node.params()[1] = rhs;
4365 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");4425 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
43664426
4367 const node = try rp.c.arena.create(ast.Node.InfixOp);4427 const node = try rp.c.arena.create(ast.Node.InfixOp);
...@@ -4832,14 +4892,13 @@ pub fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comp...@@ -4832,14 +4892,13 @@ pub fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comp
4832 .token = msg_tok,4892 .token = msg_tok,
4833 };4893 };
48344894
4835 const call_node = try c.arena.create(ast.Node.BuiltinCall);4895 const call_node = try ast.Node.BuiltinCall.alloc(c.arena, 1);
4836 call_node.* = .{4896 call_node.* = .{
4837 .builtin_token = builtin_tok,4897 .builtin_token = builtin_tok,
4838 .params = ast.Node.BuiltinCall.ParamList{},4898 .params_len = 1,
4839 .rparen_token = rparen_tok,4899 .rparen_token = rparen_tok,
4840 };4900 };
4841 var call_params_it = &call_node.params.first;4901 call_node.params()[0] = &msg_node.base;
4842 call_params_it = try c.llpush(*ast.Node, call_params_it, &msg_node.base);
48434902
4844 const var_decl_node = try c.arena.create(ast.Node.VarDecl);4903 const var_decl_node = try c.arena.create(ast.Node.VarDecl);
4845 var_decl_node.* = .{4904 var_decl_node.* = .{
...@@ -4868,23 +4927,20 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd...@@ -4868,23 +4927,20 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd
48684927
4869fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex {4928fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex {
4870 assert(token_id != .Invalid);4929 assert(token_id != .Invalid);
4871 const start_index = c.source_buffer.items.len;
4872 errdefer c.source_buffer.shrink(start_index);
48734930
4874 try c.source_buffer.outStream().print(format, args);4931 try c.token_ids.ensureCapacity(c.gpa, c.token_ids.items.len + 1);
4875 const end_index = c.source_buffer.items.len;4932 try c.token_locs.ensureCapacity(c.gpa, c.token_locs.items.len + 1);
4876 const token_index = c.tokens.items.len;
4877 const new_token = try c.tokens.addOne(c.gpa);
4878 errdefer c.tokens.shrink(c.gpa, token_index);
48794933
4880 new_token.* = .{4934 const start_index = c.source_buffer.items.len;
4881 .id = token_id,4935 try c.source_buffer.outStream().print(format ++ " ", args);
4936
4937 c.token_ids.appendAssumeCapacity(token_id);
4938 c.token_locs.appendAssumeCapacity(.{
4882 .start = start_index,4939 .start = start_index,
4883 .end = end_index,4940 .end = c.source_buffer.items.len - 1, // back up before the space
4884 };4941 });
4885 try c.source_buffer.append(' ');
48864942
4887 return token_index;4943 return c.token_ids.items.len - 1;
4888}4944}
48894945
4890// TODO hook up with codegen4946// TODO hook up with codegen
...@@ -5072,7 +5128,8 @@ fn transMacroDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, n...@@ -5072,7 +5128,8 @@ fn transMacroDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, n
5072}5128}
50735129
5074fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void {5130fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void {
5075 const block_scope = try Scope.Block.init(c, &c.global_scope.base, null);5131 var block_scope = try Scope.Block.init(c, &c.global_scope.base, null);
5132 defer block_scope.deinit();
5076 const scope = &block_scope.base;5133 const scope = &block_scope.base;
50775134
5078 const pub_tok = try appendToken(c, .Keyword_pub, "pub");5135 const pub_tok = try appendToken(c, .Keyword_pub, "pub");
...@@ -5142,9 +5199,7 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5142,9 +5199,7 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
51425199
5143 _ = try appendToken(c, .RParen, ")");5200 _ = try appendToken(c, .RParen, ")");
51445201
5145 const type_of = try transCreateNodeBuiltinFnCall(c, "@TypeOf");5202 const type_of = try c.createBuiltinCall("@TypeOf", 1);
5146 type_of.rparen_token = try appendToken(c, .RParen, ")");
5147 var type_of_params = c.llpusher(&type_of.params);
51485203
5149 const fn_proto = try ast.Node.FnProto.alloc(c.arena, fn_params.items.len);5204 const fn_proto = try ast.Node.FnProto.alloc(c.arena, fn_params.items.len);
5150 fn_proto.* = .{5205 fn_proto.* = .{
...@@ -5164,9 +5219,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5164,9 +5219,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5164 };5219 };
5165 mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items);5220 mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items);
51665221
5167 const block = try transCreateNodeBlock(c, null);
5168 var block_statements = c.llpusher(&block.statements);
5169
5170 const return_expr = try transCreateNodeReturnExpr(c);5222 const return_expr = try transCreateNodeReturnExpr(c);
5171 const expr = try parseCExpr(c, it, source, source_loc, scope);5223 const expr = try parseCExpr(c, it, source, source_loc, scope);
5172 const last = it.next().?;5224 const last = it.next().?;
...@@ -5186,12 +5238,13 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5186,12 +5238,13 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5186 const br = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", blk_last);5238 const br = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", blk_last);
5187 break :blk br.rhs.?;5239 break :blk br.rhs.?;
5188 };5240 };
5189 try type_of_params.push(type_of_arg);5241 type_of.params()[0] = type_of_arg;
5242 type_of.rparen_token = try appendToken(c, .RParen, ")");
5190 return_expr.rhs = expr;5243 return_expr.rhs = expr;
51915244
5192 block.rbrace = try appendToken(c, .RBrace, "}");5245 try block_scope.statements.append(&return_expr.base);
5193 try block_statements.push(&return_expr.base);5246 const block_node = try block_scope.complete(c);
5194 fn_proto.body_node = &block.base;5247 fn_proto.body_node = &block_node.base;
5195 _ = try c.global_scope.macro_table.put(name, &fn_proto.base);5248 _ = try c.global_scope.macro_table.put(name, &fn_proto.base);
5196}5249}
51975250
...@@ -5223,8 +5276,8 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_...@@ -5223,8 +5276,8 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_
5223 },5276 },
5224 .Comma => {5277 .Comma => {
5225 _ = try appendToken(c, .Semicolon, ";");5278 _ = try appendToken(c, .Semicolon, ";");
5226 const block_scope = try Scope.Block.init(c, scope, "blk");5279 var block_scope = try Scope.Block.init(c, scope, "blk");
5227 block_scope.setBlockNode(try transCreateNodeBlock(c, block_scope.label));5280 defer block_scope.deinit();
52285281
5229 var last = node;5282 var last = node;
5230 while (true) {5283 while (true) {
...@@ -5238,7 +5291,7 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_...@@ -5238,7 +5291,7 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_
5238 .op = .Assign,5291 .op = .Assign,
5239 .rhs = last,5292 .rhs = last,
5240 };5293 };
5241 try block_scope.block_node.statements.push(&op_node.base);5294 try block_scope.statements.append(&op_node.base);
52425295
5243 last = try parseCPrefixOpExpr(c, it, source, source_loc, scope);5296 last = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
5244 _ = try appendToken(c, .Semicolon, ";");5297 _ = try appendToken(c, .Semicolon, ";");
...@@ -5250,9 +5303,9 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_...@@ -5250,9 +5303,9 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_
52505303
5251 const break_node = try transCreateNodeBreak(c, block_scope.label);5304 const break_node = try transCreateNodeBreak(c, block_scope.label);
5252 break_node.rhs = last;5305 break_node.rhs = last;
5253 try block_scope.block_node.statements.push(&break_node.base);5306 try block_scope.statements.append(&break_node.base);
5254 block_scope.block_node.rbrace = try appendToken(c, .RBrace, "}");5307 const block_node = try block_scope.complete(c);
5255 return &block_scope.block_node.base;5308 return &block_node.base;
5256 },5309 },
5257 else => {5310 else => {
5258 _ = it.prev();5311 _ = it.prev();
...@@ -5283,15 +5336,15 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl...@@ -5283,15 +5336,15 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl
5283 return transCreateNodeInt(c, lit_bytes);5336 return transCreateNodeInt(c, lit_bytes);
5284 }5337 }
52855338
5286 const cast_node = try transCreateNodeBuiltinFnCall(c, "@as");5339 const cast_node = try c.createBuiltinCall("@as", 2);
5287 try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.id.IntegerLiteral) {5340 cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (tok.id.IntegerLiteral) {
5288 .U => "c_uint",5341 .U => "c_uint",
5289 .L => "c_long",5342 .L => "c_long",
5290 .LU => "c_ulong",5343 .LU => "c_ulong",
5291 .LL => "c_longlong",5344 .LL => "c_longlong",
5292 .LLU => "c_ulonglong",5345 .LLU => "c_ulonglong",
5293 else => unreachable,5346 else => unreachable,
5294 }));5347 });
5295 lit_bytes = lit_bytes[0 .. lit_bytes.len - switch (tok.id.IntegerLiteral) {5348 lit_bytes = lit_bytes[0 .. lit_bytes.len - switch (tok.id.IntegerLiteral) {
5296 .U, .L => @as(u8, 1),5349 .U, .L => @as(u8, 1),
5297 .LU, .LL => 2,5350 .LU, .LL => 2,
...@@ -5299,7 +5352,7 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl...@@ -5299,7 +5352,7 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl
5299 else => unreachable,5352 else => unreachable,
5300 }];5353 }];
5301 _ = try appendToken(c, .Comma, ",");5354 _ = try appendToken(c, .Comma, ",");
5302 try cast_node.params.push(try transCreateNodeInt(c, lit_bytes));5355 cast_node.params()[1] = try transCreateNodeInt(c, lit_bytes);
5303 cast_node.rparen_token = try appendToken(c, .RParen, ")");5356 cast_node.rparen_token = try appendToken(c, .RParen, ")");
5304 return &cast_node.base;5357 return &cast_node.base;
5305 } else if (tok.id == .FloatLiteral) {5358 } else if (tok.id == .FloatLiteral) {
...@@ -5308,14 +5361,14 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl...@@ -5308,14 +5361,14 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl
5308 if (tok.id.FloatLiteral == .None) {5361 if (tok.id.FloatLiteral == .None) {
5309 return transCreateNodeFloat(c, lit_bytes);5362 return transCreateNodeFloat(c, lit_bytes);
5310 }5363 }
5311 const cast_node = try transCreateNodeBuiltinFnCall(c, "@as");5364 const cast_node = try c.createBuiltinCall("@as", 2);
5312 try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.id.FloatLiteral) {5365 cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (tok.id.FloatLiteral) {
5313 .F => "f32",5366 .F => "f32",
5314 .L => "c_longdouble",5367 .L => "c_longdouble",
5315 else => unreachable,5368 else => unreachable,
5316 }));5369 });
5317 _ = try appendToken(c, .Comma, ",");5370 _ = try appendToken(c, .Comma, ",");
5318 try cast_node.params.push(try transCreateNodeFloat(c, lit_bytes[0 .. lit_bytes.len - 1]));5371 cast_node.params()[1] = try transCreateNodeFloat(c, lit_bytes[0 .. lit_bytes.len - 1]);
5319 cast_node.rparen_token = try appendToken(c, .RParen, ")");5372 cast_node.rparen_token = try appendToken(c, .RParen, ")");
5320 return &cast_node.base;5373 return &cast_node.base;
5321 } else unreachable;5374 } else unreachable;
...@@ -5585,8 +5638,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5585,8 +5638,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5585 //else5638 //else
5586 // @as(dest, x) )5639 // @as(dest, x) )
5587 const if_node = try transCreateNodeIf(c);5640 const if_node = try transCreateNodeIf(c);
5588 const type_info_node = try transCreateNodeBuiltinFnCall(c, "@typeInfo");5641 const type_info_node = try rp.c.createBuiltinCall("@typeInfo", 1);
5589 try type_info_node.params.push(inner_node);5642 type_info_node.params()[0] = inner_node;
5590 type_info_node.rparen_token = try appendToken(c, .LParen, ")");5643 type_info_node.rparen_token = try appendToken(c, .LParen, ")");
5591 const cmp_node = try c.arena.create(ast.Node.InfixOp);5644 const cmp_node = try c.arena.create(ast.Node.InfixOp);
5592 cmp_node.* = .{5645 cmp_node.* = .{
...@@ -5598,18 +5651,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5598,18 +5651,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5598 if_node.condition = &cmp_node.base;5651 if_node.condition = &cmp_node.base;
5599 _ = try appendToken(c, .RParen, ")");5652 _ = try appendToken(c, .RParen, ")");
56005653
5601 const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr");5654 const int_to_ptr = try c.createBuiltinCall("@intToPtr", 2);
5602 try int_to_ptr.params.push(inner_node);5655 int_to_ptr.params()[0] = inner_node;
5603 try int_to_ptr.params.push(node_to_cast);5656 int_to_ptr.params()[1] = node_to_cast;
5604 int_to_ptr.rparen_token = try appendToken(c, .RParen, ")");5657 int_to_ptr.rparen_token = try appendToken(c, .RParen, ")");
5605 if_node.body = &int_to_ptr.base;5658 if_node.body = &int_to_ptr.base;
56065659
5607 const else_node = try transCreateNodeElse(c);5660 const else_node = try transCreateNodeElse(c);
5608 if_node.@"else" = else_node;5661 if_node.@"else" = else_node;
56095662
5610 const as_node = try transCreateNodeBuiltinFnCall(c, "@as");5663 const as_node = try c.createBuiltinCall("@as", 2);
5611 try as_node.params.push(inner_node);5664 as_node.params()[0] = inner_node;
5612 try as_node.params.push(node_to_cast);5665 as_node.params()[1] = node_to_cast;
5613 as_node.rparen_token = try appendToken(c, .RParen, ")");5666 as_node.rparen_token = try appendToken(c, .RParen, ")");
5614 else_node.body = &as_node.base;5667 else_node.body = &as_node.base;
56155668
...@@ -5630,10 +5683,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5630,10 +5683,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5630 // @as(dest, x) )5683 // @as(dest, x) )
56315684
5632 const if_1 = try transCreateNodeIf(c);5685 const if_1 = try transCreateNodeIf(c);
5633 const type_info_1 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");5686 const type_info_1 = try c.createBuiltinCall("@typeInfo", 1);
5634 const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");5687 const type_of_1 = try c.createBuiltinCall("@TypeOf", 1);
5635 try type_info_1.params.push(&type_of_1.base);5688 type_info_1.params()[0] = &type_of_1.base;
5636 try type_of_1.params.push(node_to_cast);5689 type_of_1.params()[0] = node_to_cast;
5637 type_of_1.rparen_token = try appendToken(c, .RParen, ")");5690 type_of_1.rparen_token = try appendToken(c, .RParen, ")");
5638 type_info_1.rparen_token = try appendToken(c, .RParen, ")");5691 type_info_1.rparen_token = try appendToken(c, .RParen, ")");
56395692
...@@ -5657,20 +5710,20 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5657,20 +5710,20 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5657 .rhs = child_ident,5710 .rhs = child_ident,
5658 };5711 };
56595712
5660 const align_of = try transCreateNodeBuiltinFnCall(c, "@alignOf");5713 const align_of = try rp.c.createBuiltinCall("@alignOf", 1);
5661 try align_of.params.push(&inner_node_child.base);5714 align_of.params()[0] = &inner_node_child.base;
5662 align_of.rparen_token = try appendToken(c, .RParen, ")");5715 align_of.rparen_token = try appendToken(c, .RParen, ")");
5663 // hack to get zig fmt to render a comma in builtin calls5716 // hack to get zig fmt to render a comma in builtin calls
5664 _ = try appendToken(c, .Comma, ",");5717 _ = try appendToken(c, .Comma, ",");
56655718
5666 const align_cast = try transCreateNodeBuiltinFnCall(c, "@alignCast");5719 const align_cast = try c.createBuiltinCall("@alignCast", 2);
5667 try align_cast.params.push(&align_of.base);5720 align_cast.params()[0] = &align_of.base;
5668 try align_cast.params.push(node_to_cast);5721 align_cast.params()[1] = node_to_cast;
5669 align_cast.rparen_token = try appendToken(c, .RParen, ")");5722 align_cast.rparen_token = try appendToken(c, .RParen, ")");
56705723
5671 const ptr_cast = try transCreateNodeBuiltinFnCall(c, "@ptrCast");5724 const ptr_cast = try c.createBuiltinCall("@ptrCast", 2);
5672 try ptr_cast.params.push(inner_node);5725 ptr_cast.params()[0] = inner_node;
5673 try ptr_cast.params.push(&align_cast.base);5726 ptr_cast.params()[1] = &align_cast.base;
5674 ptr_cast.rparen_token = try appendToken(c, .RParen, ")");5727 ptr_cast.rparen_token = try appendToken(c, .RParen, ")");
5675 if_1.body = &ptr_cast.base;5728 if_1.body = &ptr_cast.base;
56765729
...@@ -5678,10 +5731,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5678,10 +5731,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5678 if_1.@"else" = else_1;5731 if_1.@"else" = else_1;
56795732
5680 const if_2 = try transCreateNodeIf(c);5733 const if_2 = try transCreateNodeIf(c);
5681 const type_info_2 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");5734 const type_info_2 = try c.createBuiltinCall("@typeInfo", 1);
5682 const type_of_2 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");5735 const type_of_2 = try c.createBuiltinCall("@TypeOf", 1);
5683 try type_info_2.params.push(&type_of_2.base);5736 type_info_2.params()[0] = &type_of_2.base;
5684 try type_of_2.params.push(node_to_cast);5737 type_of_2.params()[0] = node_to_cast;
5685 type_of_2.rparen_token = try appendToken(c, .RParen, ")");5738 type_of_2.rparen_token = try appendToken(c, .RParen, ")");
5686 type_info_2.rparen_token = try appendToken(c, .RParen, ")");5739 type_info_2.rparen_token = try appendToken(c, .RParen, ")");
56875740
...@@ -5700,8 +5753,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5700,8 +5753,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5700 .op = .BoolAnd,5753 .op = .BoolAnd,
5701 .rhs = undefined,5754 .rhs = undefined,
5702 };5755 };
5703 const type_info_3 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");5756 const type_info_3 = try c.createBuiltinCall("@typeInfo", 1);
5704 try type_info_3.params.push(inner_node);5757 type_info_3.params()[0] = inner_node;
5705 type_info_3.rparen_token = try appendToken(c, .LParen, ")");5758 type_info_3.rparen_token = try appendToken(c, .LParen, ")");
5706 const cmp_3 = try c.arena.create(ast.Node.InfixOp);5759 const cmp_3 = try c.arena.create(ast.Node.InfixOp);
5707 cmp_3.* = .{5760 cmp_3.* = .{
...@@ -5715,18 +5768,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5715,18 +5768,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5715 else_1.body = &if_2.base;5768 else_1.body = &if_2.base;
5716 _ = try appendToken(c, .RParen, ")");5769 _ = try appendToken(c, .RParen, ")");
57175770
5718 const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr");5771 const int_to_ptr = try c.createBuiltinCall("@intToPtr", 2);
5719 try int_to_ptr.params.push(inner_node);5772 int_to_ptr.params()[0] = inner_node;
5720 try int_to_ptr.params.push(node_to_cast);5773 int_to_ptr.params()[1] = node_to_cast;
5721 int_to_ptr.rparen_token = try appendToken(c, .RParen, ")");5774 int_to_ptr.rparen_token = try appendToken(c, .RParen, ")");
5722 if_2.body = &int_to_ptr.base;5775 if_2.body = &int_to_ptr.base;
57235776
5724 const else_2 = try transCreateNodeElse(c);5777 const else_2 = try transCreateNodeElse(c);
5725 if_2.@"else" = else_2;5778 if_2.@"else" = else_2;
57265779
5727 const as = try transCreateNodeBuiltinFnCall(c, "@as");5780 const as = try c.createBuiltinCall("@as", 2);
5728 try as.params.push(inner_node);5781 as.params()[0] = inner_node;
5729 try as.params.push(node_to_cast);5782 as.params()[1] = node_to_cast;
5730 as.rparen_token = try appendToken(c, .RParen, ")");5783 as.rparen_token = try appendToken(c, .RParen, ")");
5731 else_2.body = &as.base;5784 else_2.body = &as.base;
57325785
...@@ -5765,8 +5818,8 @@ fn macroBoolToInt(c: *Context, node: *ast.Node) !*ast.Node {...@@ -5765,8 +5818,8 @@ fn macroBoolToInt(c: *Context, node: *ast.Node) !*ast.Node {
5765 return &group_node.base;5818 return &group_node.base;
5766 }5819 }
57675820
5768 const builtin_node = try transCreateNodeBuiltinFnCall(c, "@boolToInt");5821 const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
5769 try builtin_node.params.push(node);5822 builtin_node.params()[0] = node;
5770 builtin_node.rparen_token = try appendToken(c, .RParen, ")");5823 builtin_node.rparen_token = try appendToken(c, .RParen, ")");
5771 return &builtin_node.base;5824 return &builtin_node.base;
5772}5825}
...@@ -5944,10 +5997,12 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5944,10 +5997,12 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5944 continue;5997 continue;
5945 },5998 },
5946 .LParen => {5999 .LParen => {
5947 const call_node = try transCreateNodeFnCall(c, node);6000 _ = try appendToken(c, .LParen, "(");
6001 var call_params = std.ArrayList(*ast.Node).init(c.gpa);
6002 defer call_params.deinit();
5948 while (true) {6003 while (true) {
5949 const arg = try parseCPrefixOpExpr(c, it, source, source_loc, scope);6004 const arg = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
5950 try call_node.op.Call.params.push(arg);6005 try call_params.append(arg);
5951 const next = it.next().?;6006 const next = it.next().?;
5952 if (next.id == .Comma)6007 if (next.id == .Comma)
5953 _ = try appendToken(c, .Comma, ",")6008 _ = try appendToken(c, .Comma, ",")
...@@ -5965,7 +6020,14 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5965,7 +6020,14 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5965 return error.ParseError;6020 return error.ParseError;
5966 }6021 }
5967 }6022 }
5968 call_node.rtoken = try appendToken(c, .RParen, ")");6023 const call_node = try ast.Node.Call.alloc(c.arena, call_params.items.len);
6024 call_node.* = .{
6025 .lhs = node,
6026 .params_len = call_params.items.len,
6027 .async_token = null,
6028 .rtoken = try appendToken(c, .RParen, ")"),
6029 };
6030 mem.copy(*ast.Node, call_node.params(), call_params.items);
5969 node = &call_node.base;6031 node = &call_node.base;
5970 continue;6032 continue;
5971 },6033 },