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);
6363pub const struct_ZigClangSkipFunctionBodiesScope = @Type(.Opaque);
6464pub const struct_ZigClangSourceManager = @Type(.Opaque);
6565pub const struct_ZigClangSourceRange = @Type(.Opaque);
66pub const struct_ZigClangStmt = @Type(.Opaque);
66pub const ZigClangStmt = @Type(.Opaque);
6767pub const struct_ZigClangStringLiteral = @Type(.Opaque);
6868pub const struct_ZigClangStringRef = @Type(.Opaque);
6969pub const struct_ZigClangSwitchStmt = @Type(.Opaque);
......@@ -842,9 +842,9 @@ pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*
842842pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType;
843843pub extern fn ZigClangType_getAsRecordType(self: *const ZigClangType) ?*const ZigClangRecordType;
844844pub extern fn ZigClangType_getAsUnionType(self: *const ZigClangType) ?*const ZigClangRecordType;
845pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;
846pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;
847pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;
845pub extern fn ZigClangStmt_getBeginLoc(self: *const ZigClangStmt) struct_ZigClangSourceLocation;
846pub extern fn ZigClangStmt_getStmtClass(self: ?*const ZigClangStmt) ZigClangStmtClass;
847pub extern fn ZigClangStmt_classof_Expr(self: ?*const ZigClangStmt) bool;
848848pub extern fn ZigClangExpr_getStmtClass(self: *const struct_ZigClangExpr) ZigClangStmtClass;
849849pub extern fn ZigClangExpr_getType(self: *const struct_ZigClangExpr) struct_ZigClangQualType;
850850pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;
......@@ -873,7 +873,7 @@ pub extern fn ZigClangFunctionDecl_getLocation(self: *const ZigClangFunctionDecl
873873pub extern fn ZigClangFunctionDecl_hasBody(self: *const ZigClangFunctionDecl) bool;
874874pub extern fn ZigClangFunctionDecl_getStorageClass(self: *const ZigClangFunctionDecl) ZigClangStorageClass;
875875pub 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;
877877pub extern fn ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(self: *const ZigClangFunctionDecl) bool;
878878pub extern fn ZigClangFunctionDecl_isThisDeclarationADefinition(self: *const ZigClangFunctionDecl) bool;
879879pub extern fn ZigClangFunctionDecl_doesThisDeclarationHaveABody(self: *const ZigClangFunctionDecl) bool;
......@@ -959,7 +959,6 @@ pub const ZigClangReturnStmt = struct_ZigClangReturnStmt;
959959pub const ZigClangSkipFunctionBodiesScope = struct_ZigClangSkipFunctionBodiesScope;
960960pub const ZigClangSourceManager = struct_ZigClangSourceManager;
961961pub const ZigClangSourceRange = struct_ZigClangSourceRange;
962pub const ZigClangStmt = struct_ZigClangStmt;
963962pub const ZigClangStringLiteral = struct_ZigClangStringLiteral;
964963pub const ZigClangStringRef = struct_ZigClangStringRef;
965964pub const ZigClangSwitchStmt = struct_ZigClangSwitchStmt;
......@@ -1018,7 +1017,7 @@ pub extern fn ZigClangLoadFromCommandLine(
10181017pub extern fn ZigClangDecl_getKind(decl: *const ZigClangDecl) ZigClangDeclKind;
10191018pub 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
10231022pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
10241023pub 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 {
5454 Loop,
5555 };
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.
5760 const Switch = struct {
5861 base: Scope,
59 pending_block: *ast.Node.Block,
60 cases: *ast.Node.Switch.CaseList,
62 pending_block: *Block,
63 cases: []*ast.Node,
64 case_index: usize,
6165 has_default: bool = false,
6266 };
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.
6489 const Block = struct {
6590 base: Scope,
66 block_node: *ast.Node.Block,
67 statements_it: *?*std.SinglyLinkedList(*ast.Node),
91 statements: std.ArrayList(*ast.Node),
6892 variables: AliasList,
69 label: ?[]const u8,
93 label: ?ast.TokenIndex,
7094 mangle_count: u32 = 0,
95 lbrace: ast.TokenIndex,
7196
72 /// Don't forget to set rbrace token and block_node later
73 fn init(c: *Context, parent: *Scope, label: ?[]const u8) !*Block {
74 const block = try c.arena.create(Block);
75 block.* = .{
97 fn init(c: *Context, parent: *Scope, label: ?[]const u8) !Block {
98 return Block{
7699 .base = .{
77100 .id = .Block,
78101 .parent = parent,
79102 },
80 .block_node = undefined,
81 .statements_it = undefined,
82 .variables = AliasList.init(c.arena),
83 .label = label,
103 .statements = std.ArrayList(*ast.Node).init(c.gpa),
104 .variables = AliasList.init(c.gpa),
105 .label = if (self.label) |l| blk: {
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, "{"),
84111 };
85 return block;
86112 }
87113
88 fn pushStatement(self: *Block, c: *Context, stmt: *ast.Node) !void {
89 self.statements_it = c.llpush(*ast.Node, self.statements_it, stmt);
114 fn deinit(self: *Block) void {
115 self.statements.deinit();
116 self.variables.deinit();
117 self.* = undefined;
90118 }
91119
92 fn setBlockNode(self: *Block, block: *ast.Node.Block) void {
93 self.block_node = block;
94 self.statements_it = &block.statements.first;
120 fn complete(self: *Block, c: *Context) !*ast.Node.Block {
121 const node = try ast.Node.Block.alloc(c.arena, self.statements.items.len);
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;
95130 }
96131
97132 /// Given the desired name, return a name that does not shadow anything from outer scopes.
......@@ -102,12 +137,13 @@ const Scope = struct {
102137 scope.mangle_count += 1;
103138 proposed_name = try std.fmt.allocPrint(c.arena, "{}_{}", .{ name, scope.mangle_count });
104139 }
105 try scope.variables.append(.{ .name = name, .alias = proposed_name });
140 try scope.variables.push(.{ .name = name, .alias = proposed_name });
106141 return proposed_name;
107142 }
108143
109144 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| {
111147 if (mem.eql(u8, p.name, name))
112148 return p.alias;
113149 }
......@@ -115,7 +151,8 @@ const Scope = struct {
115151 }
116152
117153 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| {
119156 if (mem.eql(u8, p.name, name))
120157 return true;
121158 }
......@@ -167,10 +204,7 @@ const Scope = struct {
167204 switch (scope.id) {
168205 .Root => unreachable,
169206 .Block => return @fieldParentPtr(Block, "base", scope),
170 .Condition => {
171 // comma operator used
172 return try Block.init(c, scope, "blk");
173 },
207 .Condition => return @fieldParentPtr(Condition, "base", scope).getBlockScope(c),
174208 else => scope = scope.parent.?,
175209 }
176210 }
......@@ -219,7 +253,8 @@ const Scope = struct {
219253pub const Context = struct {
220254 gpa: *mem.Allocator,
221255 arena: *mem.Allocator,
222 tokens: std.ArrayListUnmanaged(Token),
256 token_ids: std.ArrayListUnmanaged(Token.Id),
257 token_locs: std.ArrayListUnmanaged(Token.Loc),
223258 errors: std.ArrayListUnmanaged(ast.Error),
224259 source_buffer: *std.ArrayList(u8),
225260 err: Error,
......@@ -237,16 +272,6 @@ pub const Context = struct {
237272 /// up front in a pre-processing step.
238273 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
250275 fn getMangle(c: *Context) u32 {
251276 c.mangle_count += 1;
252277 return c.mangle_count;
......@@ -267,6 +292,46 @@ pub const Context = struct {
267292 const column = ZigClangSourceManager_getSpellingColumnNumber(c.source_manager, spelling_loc);
268293 return std.fmt.allocPrint(c.arena, "{}:{}:{}", .{ filename, line, column });
269294 }
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 }
270335};
271336
272337pub fn translate(
......@@ -307,14 +372,16 @@ pub fn translate(
307372 .global_scope = try arena.allocator.create(Scope.Root),
308373 .clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
309374 .global_names = std.StringHashMap(void).init(gpa),
310 .tokens = .{},
375 .token_ids = .{},
376 .token_locs = .{},
311377 .errors = .{},
312378 .root_decls = .{},
313379 };
314380 context.global_scope.* = Scope.Root.init(&context);
315381 defer context.decl_table.deinit();
316382 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);
318385 defer context.errors.deinit(gpa);
319386 defer context.global_names.deinit();
320387 defer context.root_decls.deinit(gpa);
......@@ -349,7 +416,8 @@ pub fn translate(
349416 tree.* = .{
350417 .gpa = gpa,
351418 .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),
353421 .errors = context.errors.toOwnedSlice(gpa),
354422 .root_node = root_node,
355423 .arena = arena.state,
......@@ -508,10 +576,9 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
508576
509577 // actual function definition with body
510578 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();
512581 var scope = &block_scope.base;
513 const block_node = try transCreateNodeBlock(rp.c, null);
514 block_scope.setBlockNode(block_node);
515582
516583 var param_id: c_uint = 0;
517584 for (proto_node.params()) |param, i| {
......@@ -541,7 +608,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
541608 node.eq_token = try appendToken(c, .Equal, "=");
542609 node.init_node = try transCreateNodeIdentifier(c, arg_name);
543610 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);
545612 param.name_token = try appendIdentifier(c, arg_name);
546613 _ = try appendToken(c, .Colon, ":");
547614 }
......@@ -549,14 +616,14 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
549616 param_id += 1;
550617 }
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) {
553621 error.OutOfMemory => |e| return e,
554622 error.UnsupportedTranslation,
555623 error.UnsupportedType,
556624 => return failDecl(c, fn_decl_loc, fn_name, "unable to translate function", .{}),
557625 };
558 block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
559 proto_node.body_node = &block_node.base;
626 proto_node.body_node = try block_scope.complete(rp.c);
560627 return addTopLevelDecl(c, fn_name, &proto_node.base);
561628}
562629
......@@ -999,7 +1066,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
9991066 // At this point we can rely on the enum emitting successfully.
10001067 const tld_node = try transCreateNodeVarDecl(c, true, true, enum_val_name);
10011068 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);
10031070 const enum_ident = try transCreateNodeIdentifier(c, name);
10041071 const period_tok = try appendToken(c, .Period, ".");
10051072 const field_ident = try transCreateNodeIdentifier(c, field_name);
......@@ -1010,7 +1077,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
10101077 .op = .Period,
10111078 .rhs = field_ident,
10121079 };
1013 try cast_node.params.push(&field_access_node.base);
1080 cast_node.params()[0] = &field_access_node.base;
10141081 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
10151082 tld_node.init_node = &cast_node.base;
10161083 tld_node.semicolon_token = try appendToken(c, .Semicolon, ";");
......@@ -1104,7 +1171,7 @@ fn transStmt(
11041171 .WhileStmtClass => return transWhileLoop(rp, scope, @ptrCast(*const ZigClangWhileStmt, stmt)),
11051172 .DoStmtClass => return transDoWhileLoop(rp, scope, @ptrCast(*const ZigClangDoStmt, stmt)),
11061173 .NullStmtClass => {
1107 const block = try transCreateNodeBlock(rp.c, null);
1174 const block = try rp.c.createBlock(null, 0);
11081175 block.rbrace = try appendToken(rp.c, .RBrace, "}");
11091176 return &block.base;
11101177 },
......@@ -1170,27 +1237,23 @@ fn transBinaryOperator(
11701237 .Comma => {
11711238 const block_scope = try scope.findBlockScope(rp.c);
11721239 const expr = block_scope.base.parent == scope;
1173 const lparen = if (expr) blk: {
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;
1240 const lparen = if (expr) try appendToken(rp.c, .LParen, "(") else undefined;
11781241
11791242 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
11821245 const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
11831246 if (expr) {
11841247 _ = try appendToken(rp.c, .Semicolon, ";");
11851248 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
11861249 break_node.rhs = rhs;
1187 try block_scope.block_node.statements.push(&break_node.base);
1188 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
1250 try block_scope.statements.append(&break_node.base);
1251 const block_node = try block_scope.complete(rp.c);
11891252 const rparen = try appendToken(rp.c, .RParen, ")");
11901253 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
11911254 grouped_expr.* = .{
11921255 .lparen = lparen,
1193 .expr = &block_scope.block_node.base,
1256 .expr = &block_node.base,
11941257 .rparen = rparen,
11951258 };
11961259 return maybeSuppressResult(rp, scope, result_used, &grouped_expr.base);
......@@ -1201,11 +1264,11 @@ fn transBinaryOperator(
12011264 .Div => {
12021265 if (cIsSignedInteger(qt)) {
12031266 // signed integer division uses @divTrunc
1204 const div_trunc_node = try transCreateNodeBuiltinFnCall(rp.c, "@divTrunc");
1205 try div_trunc_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value));
1267 const div_trunc_node = try rp.c.createBuiltinCall("@divTrunc", 2);
1268 div_trunc_node.params()[0] = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value);
12061269 _ = try appendToken(rp.c, .Comma, ",");
12071270 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;
12091272 div_trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")");
12101273 return maybeSuppressResult(rp, scope, result_used, &div_trunc_node.base);
12111274 }
......@@ -1213,11 +1276,11 @@ fn transBinaryOperator(
12131276 .Rem => {
12141277 if (cIsSignedInteger(qt)) {
12151278 // signed integer division uses @rem
1216 const rem_node = try transCreateNodeBuiltinFnCall(rp.c, "@rem");
1217 try rem_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value));
1279 const rem_node = try rp.c.createBuiltinCall("@rem", 2);
1280 rem_node.params()[0] = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value);
12181281 _ = try appendToken(rp.c, .Comma, ",");
12191282 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;
12211284 rem_node.rparen_token = try appendToken(rp.c, .RParen, ")");
12221285 return maybeSuppressResult(rp, scope, result_used, &rem_node.base);
12231286 }
......@@ -1321,15 +1384,15 @@ fn transBinaryOperator(
13211384 const rhs_node = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
13221385
13231386 const lhs = if (isBoolRes(lhs_node)) init: {
1324 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
1325 try cast_node.params.push(lhs_node);
1387 const cast_node = try rp.c.createBuiltinCall("@boolToInt", 1);
1388 cast_node.params()[0] = lhs_node;
13261389 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
13271390 break :init &cast_node.base;
13281391 } else lhs_node;
13291392
13301393 const rhs = if (isBoolRes(rhs_node)) init: {
1331 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
1332 try cast_node.params.push(rhs_node);
1394 const cast_node = try rp.c.createBuiltinCall("@boolToInt", 1);
1395 cast_node.params()[0] = rhs_node;
13331396 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
13341397 break :init &cast_node.base;
13351398 } else rhs_node;
......@@ -1341,23 +1404,22 @@ fn transCompoundStmtInline(
13411404 rp: RestorePoint,
13421405 parent_scope: *Scope,
13431406 stmt: *const ZigClangCompoundStmt,
1344 block_node: *ast.Node.Block,
1407 block: *Scope.Block,
13451408) TransError!void {
13461409 var it = ZigClangCompoundStmt_body_begin(stmt);
13471410 const end_it = ZigClangCompoundStmt_body_end(stmt);
13481411 while (it != end_it) : (it += 1) {
13491412 const result = try transStmt(rp, parent_scope, it[0], .unused, .r_value);
1350 if (result != &block_node.base)
1351 try block_node.statements.push(result);
1413 try block.statements.append(result);
13521414 }
13531415}
13541416
13551417fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node {
1356 const block_scope = try Scope.Block.init(rp.c, scope, null);
1357 block_scope.setBlockNode(try transCreateNodeBlock(rp.c, null));
1358 try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node);
1359 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
1360 return &block_scope.block_node.base;
1418 var block_scope = try Scope.Block.init(rp.c, scope, null);
1419 defer block_scope.deinit();
1420 try transCompoundStmtInline(rp, &block_scope.base, stmt, &block_scope);
1421 const node = block_scope.complete(c);
1422 return &node.base;
13611423}
13621424
13631425fn transCStyleCastExprClass(
......@@ -1411,14 +1473,14 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
14111473 else
14121474 try transCreateNodeUndefinedLiteral(c);
14131475 if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) {
1414 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
1415 try builtin_node.params.push(init_node);
1476 const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
1477 builtin_node.params()[0] = init_node;
14161478 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
14171479 init_node = &builtin_node.base;
14181480 }
14191481 node.init_node = init_node;
14201482 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);
14221484 },
14231485 .Typedef => {
14241486 const typedef_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]);
......@@ -1437,7 +1499,7 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
14371499 });
14381500 } else {
14391501 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);
14411503 }
14421504 },
14431505 else => |kind| return revertAndWarn(
......@@ -1499,8 +1561,8 @@ fn transImplicitCastExpr(
14991561 },
15001562 .PointerToBoolean => {
15011563 // @ptrToInt(val) != 0
1502 const ptr_to_int = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
1503 try ptr_to_int.params.push(try transExpr(rp, scope, sub_expr, .used, .r_value));
1564 const ptr_to_int = try rp.c.createBuiltinCall("@ptrToInt", 1);
1565 ptr_to_int.params()[0] = try transExpr(rp, scope, sub_expr, .used, .r_value);
15041566 ptr_to_int.rparen_token = try appendToken(rp.c, .RParen, ")");
15051567
15061568 const op_token = try appendToken(rp.c, .BangEqual, "!=");
......@@ -1724,13 +1786,11 @@ fn transIntegerLiteral(
17241786
17251787 // @as(T, x)
17261788 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);
17281790 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;
17301792 _ = try appendToken(rp.c, .Comma, ",");
1731
1732 const int_lit_node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val));
1733 try as_node.params.push(int_lit_node);
1793 as_node.params()[1] = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val));
17341794
17351795 as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
17361796 return maybeSuppressResult(rp, scope, result_used, &as_node.base);
......@@ -1840,35 +1900,35 @@ fn transCCast(
18401900 // 2. Bit-cast to correct signed-ness
18411901
18421902 // @bitCast(dest_type, intermediate_value)
1843 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast");
1844 try cast_node.params.push(try transQualType(rp, dst_type, loc));
1903 const cast_node = try rp.c.createBuiltinCall("@bitCast", 2);
1904 cast_node.params()[0] = try transQualType(rp, dst_type, loc);
18451905 _ = try appendToken(rp.c, .Comma, ",");
18461906
18471907 switch (cIntTypeCmp(dst_type, src_type)) {
18481908 .lt => {
18491909 // @truncate(SameSignSmallerInt, src_type)
1850 const trunc_node = try transCreateNodeBuiltinFnCall(rp.c, "@truncate");
1910 const trunc_node = try rp.c.createBuiltinCall("@truncate", 2);
18511911 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;
18531913 _ = try appendToken(rp.c, .Comma, ",");
1854 try trunc_node.params.push(expr);
1914 trunc_node.params()[1] = expr;
18551915 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;
18581918 },
18591919 .gt => {
18601920 // @as(SameSignBiggerInt, src_type)
1861 const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
1921 const as_node = try rp.c.createBuiltinCall("@as", 2);
18621922 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;
18641924 _ = try appendToken(rp.c, .Comma, ",");
1865 try as_node.params.push(expr);
1925 as_node.params()[1] = expr;
18661926 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;
18691929 },
18701930 .eq => {
1871 try cast_node.params.push(expr);
1931 cast_node.params()[1] = expr;
18721932 },
18731933 }
18741934 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
......@@ -1876,46 +1936,46 @@ fn transCCast(
18761936 }
18771937 if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) {
18781938 // @intCast(dest_type, @ptrToInt(val))
1879 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
1880 try cast_node.params.push(try transQualType(rp, dst_type, loc));
1939 const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
1940 cast_node.params()[0] = try transQualType(rp, dst_type, loc);
18811941 _ = try appendToken(rp.c, .Comma, ",");
1882 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
1883 try builtin_node.params.push(expr);
1942 const builtin_node = try rp.c.createBuiltinCall("@ptrToInt", 1);
1943 builtin_node.params()[0] = expr;
18841944 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;
18861946 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
18871947 return &cast_node.base;
18881948 }
18891949 if (cIsInteger(src_type) and qualTypeIsPtr(dst_type)) {
18901950 // @intToPtr(dest_type, val)
1891 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr");
1892 try builtin_node.params.push(try transQualType(rp, dst_type, loc));
1951 const builtin_node = try rp.c.createBuiltinCall("@intToPtr", 2);
1952 builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
18931953 _ = try appendToken(rp.c, .Comma, ",");
1894 try builtin_node.params.push(expr);
1954 builtin_node.params()[1] = expr;
18951955 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
18961956 return &builtin_node.base;
18971957 }
18981958 if (cIsFloating(src_type) and cIsFloating(dst_type)) {
1899 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@floatCast");
1900 try builtin_node.params.push(try transQualType(rp, dst_type, loc));
1959 const builtin_node = try rp.c.createBuiltinCall("@floatCast", 2);
1960 builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
19011961 _ = try appendToken(rp.c, .Comma, ",");
1902 try builtin_node.params.push(expr);
1962 builtin_node.params()[1] = expr;
19031963 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
19041964 return &builtin_node.base;
19051965 }
19061966 if (cIsFloating(src_type) and !cIsFloating(dst_type)) {
1907 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@floatToInt");
1908 try builtin_node.params.push(try transQualType(rp, dst_type, loc));
1967 const builtin_node = try rp.c.createBuiltinCall("@floatToInt", 2);
1968 builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
19091969 _ = try appendToken(rp.c, .Comma, ",");
1910 try builtin_node.params.push(expr);
1970 builtin_node.params()[1] = expr;
19111971 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
19121972 return &builtin_node.base;
19131973 }
19141974 if (!cIsFloating(src_type) and cIsFloating(dst_type)) {
1915 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToFloat");
1916 try builtin_node.params.push(try transQualType(rp, dst_type, loc));
1975 const builtin_node = try rp.c.createBuiltinCall("@intToFloat", 2);
1976 builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
19171977 _ = try appendToken(rp.c, .Comma, ",");
1918 try builtin_node.params.push(expr);
1978 builtin_node.params()[1] = expr;
19191979 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
19201980 return &builtin_node.base;
19211981 }
......@@ -1923,54 +1983,54 @@ fn transCCast(
19231983 !ZigClangType_isBooleanType(qualTypeCanon(dst_type)))
19241984 {
19251985 // @boolToInt returns either a comptime_int or a u1
1926 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
1927 try builtin_node.params.push(expr);
1986 const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
1987 builtin_node.params()[0] = expr;
19281988 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
19291989
1930 const inner_cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
1931 try inner_cast_node.params.push(try transCreateNodeIdentifier(rp.c, "u1"));
1990 const inner_cast_node = try rp.c.createBuiltinCall("@intCast", 2);
1991 inner_cast_node.params()[0] = try transCreateNodeIdentifier(rp.c, "u1");
19321992 _ = try appendToken(rp.c, .Comma, ",");
1933 try inner_cast_node.params.push(&builtin_node.base);
1993 inner_cast_node.params()[1] = &builtin_node.base;
19341994 inner_cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
19351995
1936 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
1937 try cast_node.params.push(try transQualType(rp, dst_type, loc));
1996 const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
1997 cast_node.params()[0] = try transQualType(rp, dst_type, loc);
19381998 _ = try appendToken(rp.c, .Comma, ",");
19391999
19402000 if (cIsSignedInteger(dst_type)) {
1941 const bitcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast");
1942 try bitcast_node.params.push(try transCreateNodeIdentifier(rp.c, "i1"));
2001 const bitcast_node = try rp.c.createBuiltinCall("@bitCast", 2);
2002 bitcast_node.params()[0] = try transCreateNodeIdentifier(rp.c, "i1");
19432003 _ = try appendToken(rp.c, .Comma, ",");
1944 try bitcast_node.params.push(&inner_cast_node.base);
2004 bitcast_node.params()[1] = &inner_cast_node.base;
19452005 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;
19472007 } else {
1948 try cast_node.params.push(&inner_cast_node.base);
2008 cast_node.params()[1] = &inner_cast_node.base;
19492009 }
19502010 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
19512011
19522012 return &cast_node.base;
19532013 }
19542014 if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) {
1955 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");
1956 try builtin_node.params.push(try transQualType(rp, dst_type, loc));
2015 const builtin_node = try rp.c.createBuiltinCall("@intToEnum", 2);
2016 builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
19572017 _ = try appendToken(rp.c, .Comma, ",");
1958 try builtin_node.params.push(expr);
2018 builtin_node.params()[1] = expr;
19592019 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
19602020 return &builtin_node.base;
19612021 }
19622022 if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(src_type)) == .Enum and
19632023 ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) != .Enum)
19642024 {
1965 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt");
1966 try builtin_node.params.push(expr);
2025 const builtin_node = try rp.c.createBuiltinCall("@enumToInt", 1);
2026 builtin_node.params()[0] = expr;
19672027 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
19682028 return &builtin_node.base;
19692029 }
1970 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
1971 try cast_node.params.push(try transQualType(rp, dst_type, loc));
2030 const cast_node = try rp.c.createBuiltinCall("@as", 2);
2031 cast_node.params()[0] = try transQualType(rp, dst_type, loc);
19722032 _ = try appendToken(rp.c, .Comma, ",");
1973 try cast_node.params.push(expr);
2033 cast_node.params()[1] = expr;
19742034 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
19752035 return &cast_node.base;
19762036}
......@@ -2077,12 +2137,13 @@ fn transInitListExprRecord(
20772137
20782138 _ = 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);
20812141 node.* = .{
20822142 .lhs = ty,
20832143 .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,
20852145 };
2146 mem.copy(*ast.Node, node.list(), field_inits.items);
20862147 return &node.base;
20872148}
20882149
......@@ -2292,11 +2353,15 @@ fn transIfStmt(
22922353 // if (c) t else e
22932354 const if_node = try transCreateNodeIf(rp.c);
22942355
2295 var cond_scope = Scope{
2296 .parent = scope,
2297 .id = .Condition,
2356 var cond_scope = Scope.Condition{
2357 .base = .{
2358 .parent = scope,
2359 .id = .Condition,
2360 },
22982361 };
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);
23002365 _ = try appendToken(rp.c, .RParen, ")");
23012366
23022367 if_node.body = try transStmt(rp, scope, ZigClangIfStmt_getThen(stmt), .unused, .r_value);
......@@ -2316,11 +2381,15 @@ fn transWhileLoop(
23162381) TransError!*ast.Node {
23172382 const while_node = try transCreateNodeWhile(rp.c);
23182383
2319 var cond_scope = Scope{
2320 .parent = scope,
2321 .id = .Condition,
2384 var cond_scope = Scope.Condition{
2385 .base = .{
2386 .parent = scope,
2387 .id = .Condition,
2388 },
23222389 };
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);
23242393 _ = try appendToken(rp.c, .RParen, ")");
23252394
23262395 var loop_scope = Scope{
......@@ -2349,12 +2418,15 @@ fn transDoWhileLoop(
23492418
23502419 // if (!cond) break;
23512420 const if_node = try transCreateNodeIf(rp.c);
2352 var cond_scope = Scope{
2353 .parent = scope,
2354 .id = .Condition,
2421 var cond_scope = Scope.Condition{
2422 .base = .{
2423 .parent = scope,
2424 .id = .Condition,
2425 },
23552426 };
2427 defer cond_scope.deinit();
23562428 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);
23582430 _ = try appendToken(rp.c, .RParen, ")");
23592431 if_node.condition = &prefix_op.base;
23602432 if_node.body = &(try transCreateNodeBreak(rp.c, null)).base;
......@@ -2404,24 +2476,26 @@ fn transForLoop(
24042476 .id = .Loop,
24052477 };
24062478
2407 var block_scope: ?*Scope.Block = null;
2479 var block_scope: ?Scope.Block = null;
2480 defer if (block_scope) |*bs| bs.deinit();
2481
24082482 if (ZigClangForStmt_getInit(stmt)) |init| {
24092483 block_scope = try Scope.Block.init(rp.c, scope, null);
2410 const block = try transCreateNodeBlock(rp.c, null);
2411 block_scope.?.setBlockNode(block);
24122484 loop_scope.parent = &block_scope.?.base;
24132485 const result = try transStmt(rp, &block_scope.?.base, init, .unused, .r_value);
2414 if (result != &block.base)
2415 try block.statements.push(result);
2486 try block_scope.statements.push(result);
24162487 }
2417 var cond_scope = Scope{
2418 .parent = scope,
2419 .id = .Condition,
2488 var cond_scope = Scope.Condition{
2489 .base = .{
2490 .parent = scope,
2491 .id = .Condition,
2492 },
24202493 };
2494 defer cond_scope.deinit();
24212495
24222496 const while_node = try transCreateNodeWhile(rp.c);
24232497 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)
24252499 else
24262500 try transCreateNodeBoolLiteral(rp.c, true);
24272501 _ = try appendToken(rp.c, .RParen, ")");
......@@ -2429,62 +2503,90 @@ fn transForLoop(
24292503 if (ZigClangForStmt_getInc(stmt)) |incr| {
24302504 _ = try appendToken(rp.c, .Colon, ":");
24312505 _ = 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);
24332507 _ = try appendToken(rp.c, .RParen, ")");
24342508 }
24352509
24362510 while_node.body = try transStmt(rp, &loop_scope, ZigClangForStmt_getBody(stmt), .unused, .r_value);
2437 if (block_scope != null) {
2438 try block_scope.?.block_node.statements.push(&while_node.base);
2439 block_scope.?.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
2440 return &block_scope.?.block_node.base;
2511 if (block_scope) |*bs| {
2512 try bs.statements.push(&while_node.base);
2513 const node = bs.complete(rp.c);
2514 return &node.base;
24412515 } else {
24422516 _ = try appendToken(rp.c, .Semicolon, ";");
24432517 return &while_node.base;
24442518 }
24452519}
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
24472527fn transSwitch(
24482528 rp: RestorePoint,
24492529 scope: *Scope,
24502530 stmt: *const ZigClangSwitchStmt,
24512531) 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
24532556 var switch_scope = Scope.Switch{
24542557 .base = .{
24552558 .id = .Switch,
24562559 .parent = scope,
24572560 },
2458 .cases = &switch_node.cases,
2561 .cases = switch_node.cases(),
2562 .case_index = 0,
24592563 .pending_block = undefined,
24602564 };
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);
24722566 // tmp block that all statements will go before being picked up by a case or default
2473 const block = try transCreateNodeBlock(rp.c, null);
2474 block_scope.setBlockNode(block);
2567 var block_scope = try Scope.Block.init(rp.c, &switch_scope.base, null);
2568 defer block_scope.deinit();
24752569
2476 const switch_block = try transCreateNodeBlock(rp.c, null);
2477 try switch_block.statements.push(&switch_node.base);
2478 switch_scope.pending_block = switch_block;
2570 // Note that we do not defer a deinit here; the switch_scope.pending_block field
2571 // has its own memory management. This resource is freed inside `transCase` and
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);
24812578 _ = try appendToken(rp.c, .Semicolon, ";");
24822579
24832580 // take all pending statements
2484 var it = last.cast(ast.Node.Block).?.statements.iterator(0);
2485 while (it.next()) |n| {
2486 try switch_scope.pending_block.statements.push(n.*);
2487 }
2581 try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items);
2582 // TODO delete the following commented out code
2583 //const last_block_stmts = last.cast(ast.Node.Block).?.statements();
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
24892591 switch_scope.pending_block.label = try appendIdentifier(rp.c, "__switch");
24902592 _ = try appendToken(rp.c, .Colon, ":");
......@@ -2492,10 +2594,16 @@ fn transSwitch(
24922594 const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c));
24932595 else_prong.expr = &(try transCreateNodeBreak(rp.c, "__switch")).base;
24942596 _ = 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;
24962599 }
2497 switch_scope.pending_block.rbrace = try appendToken(rp.c, .RBrace, "}");
2498 return &switch_scope.pending_block.base;
2600 // We overallocated in case there was no default, so now we correct
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;
24992607}
25002608
25012609fn transCase(
......@@ -2527,22 +2635,21 @@ fn transCase(
25272635 const switch_prong = try transCreateNodeSwitchCase(rp.c, expr);
25282636 switch_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base;
25292637 _ = 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);
25332641 switch_scope.pending_block.label = try appendIdentifier(rp.c, label);
25342642 _ = 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
25382644 // take all pending statements
2539 var it = block_scope.block_node.statements.iterator(0);
2540 while (it.next()) |n| {
2541 try switch_scope.pending_block.statements.push(n.*);
2542 }
2543 block_scope.block_node.statements.shrink(0);
2645 try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items);
2646 block_scope.statements.shrink(0);
2647
2648 const pending_node = try switch_scope.pending_block.complete(rp.c);
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
25472654 return transStmt(rp, scope, ZigClangCaseStmt_getSubStmt(stmt), .unused, .r_value);
25482655}
......@@ -2561,22 +2668,21 @@ fn transDefault(
25612668 const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c));
25622669 else_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base;
25632670 _ = 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);
25672674 switch_scope.pending_block.label = try appendIdentifier(rp.c, label);
25682675 _ = 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
25722677 // take all pending statements
2573 var it = block_scope.block_node.statements.iterator(0);
2574 while (it.next()) |n| {
2575 try switch_scope.pending_block.statements.push(n.*);
2576 }
2577 block_scope.block_node.statements.shrink(0);
2678 try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items);
2679 block_scope.statements.shrink(0);
2680
2681 const pending_node = try switch_scope.pending_block.complete(rp.c);
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;
25802686 return transStmt(rp, scope, ZigClangDefaultStmt_getSubStmt(stmt), .unused, .r_value);
25812687}
25822688
......@@ -2591,13 +2697,13 @@ fn transConstantExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangExpr,
25912697 // See comment in `transIntegerLiteral` for why this code is here.
25922698 // @as(T, x)
25932699 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);
25952701 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;
25972703 _ = try appendToken(rp.c, .Comma, ",");
25982704
25992705 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
26022708 as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
26032709
......@@ -2653,12 +2759,11 @@ fn transCharLiteral(
26532759 // See comment in `transIntegerLiteral` for why this code is here.
26542760 // @as(T, x)
26552761 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);
26572763 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;
26592765 _ = try appendToken(rp.c, .Comma, ",");
2660
2661 try as_node.params.push(int_lit_node);
2766 as_node.params()[1] = int_lit_node;
26622767
26632768 as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
26642769 return maybeSuppressResult(rp, scope, result_used, &as_node.base);
......@@ -2671,26 +2776,24 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr,
26712776 }
26722777 const lparen = try appendToken(rp.c, .LParen, "(");
26732778 const block_scope = try Scope.Block.init(rp.c, scope, "blk");
2674 const block = try transCreateNodeBlock(rp.c, "blk");
2675 block_scope.setBlockNode(block);
2779 defer block_scope.deinit();
26762780
26772781 var it = ZigClangCompoundStmt_body_begin(comp);
26782782 const end_it = ZigClangCompoundStmt_body_end(comp);
26792783 while (it != end_it - 1) : (it += 1) {
26802784 const result = try transStmt(rp, &block_scope.base, it[0], .unused, .r_value);
2681 if (result != &block.base)
2682 try block.statements.push(result);
2785 try block_scope.statements.append(result);
26832786 }
26842787 const break_node = try transCreateNodeBreak(rp.c, "blk");
26852788 break_node.rhs = try transStmt(rp, &block_scope.base, it[0], .used, .r_value);
26862789 _ = try appendToken(rp.c, .Semicolon, ";");
2687 try block.statements.push(&break_node.base);
2688 block.rbrace = try appendToken(rp.c, .RBrace, "}");
2790 try block_scope.statements.append(&break_node.base);
2791 const block_node = try block_scope.complete(rp.c);
26892792 const rparen = try appendToken(rp.c, .RParen, ")");
26902793 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
26912794 grouped_expr.* = .{
26922795 .lparen = lparen,
2693 .expr = &block.base,
2796 .expr = &block_node.base,
26942797 .rparen = rparen,
26952798 };
26962799 return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
......@@ -2746,12 +2849,12 @@ fn transArrayAccess(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangArrayS
27462849 const is_signed = cIsSignedInteger(qt);
27472850
27482851 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);
27502853 // check if long long first so that signed long long doesn't just become unsigned long long
27512854 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;
27532856 _ = 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);
27552858 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
27562859 node.rtoken = try appendToken(rp.c, .RBrace, "]");
27572860 node.op.ArrayAccess = &cast_node.base;
......@@ -2787,17 +2890,18 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr,
27872890 break :blk try transCreateNodeUnwrapNull(rp.c, raw_fn_expr);
27882891 } else
27892892 raw_fn_expr;
2790 const node = try transCreateNodeFnCall(rp.c, fn_expr);
27912893
27922894 const num_args = ZigClangCallExpr_getNumArgs(stmt);
2895 const node = try c.createCall(fn_expr, num_args);
2896 const call_params = node.params();
2897
27932898 const args = ZigClangCallExpr_getArgs(stmt);
27942899 var i: usize = 0;
27952900 while (i < num_args) : (i += 1) {
27962901 if (i != 0) {
27972902 _ = try appendToken(rp.c, .Comma, ",");
27982903 }
2799 const arg = try transExpr(rp, scope, args[i], .used, .r_value);
2800 try node.op.Call.params.push(arg);
2904 call_params[i] = try transExpr(rp, scope, args[i], .used, .r_value);
28012905 }
28022906 node.rtoken = try appendToken(rp.c, .RParen, ")");
28032907
......@@ -2856,8 +2960,8 @@ fn transUnaryExprOrTypeTraitExpr(
28562960 ZigClangUnaryExprOrTypeTraitExpr_getBeginLoc(stmt),
28572961 );
28582962
2859 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@sizeOf");
2860 try builtin_node.params.push(type_node);
2963 const builtin_node = try rp.c.createBuiltinCall("@sizeOf", 1);
2964 builtin_node.params()[0] = type_node;
28612965 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
28622966 return maybeSuppressResult(rp, scope, result_used, &builtin_node.base);
28632967}
......@@ -2966,8 +3070,8 @@ fn transCreatePreCrement(
29663070 // zig: _ref.* += 1;
29673071 // zig: break :blk _ref.*
29683072 // zig: })
2969 const block_scope = try Scope.Block.init(rp.c, scope, "blk");
2970 block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
3073 var block_scope = try Scope.Block.init(rp.c, scope, "blk");
3074 defer block_scope.deinit();
29713075 const ref = try block_scope.makeMangledName(rp.c, "ref");
29723076
29733077 const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
......@@ -2976,7 +3080,7 @@ fn transCreatePreCrement(
29763080 rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value);
29773081 node.init_node = &rhs_node.base;
29783082 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
29813085 const lhs_node = try transCreateNodeIdentifier(rp.c, ref);
29823086 const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);
......@@ -2985,18 +3089,18 @@ fn transCreatePreCrement(
29853089 const one = try transCreateNodeInt(rp.c, 1);
29863090 _ = try appendToken(rp.c, .Semicolon, ";");
29873091 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
29903094 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
29913095 break_node.rhs = ref_node;
2992 try block_scope.block_node.statements.push(&break_node.base);
2993 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
3096 try block_scope.statements.push(&break_node.base);
3097 const block_node = try block_scope.complete(rp.c);
29943098 // semicolon must immediately follow rbrace because it is the last token in a block
29953099 _ = try appendToken(rp.c, .Semicolon, ";");
29963100 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
29973101 grouped_expr.* = .{
29983102 .lparen = try appendToken(rp.c, .LParen, "("),
2999 .expr = &block_scope.block_node.base,
3103 .expr = &block_node.base,
30003104 .rparen = try appendToken(rp.c, .RParen, ")"),
30013105 };
30023106 return &grouped_expr.base;
......@@ -3032,8 +3136,8 @@ fn transCreatePostCrement(
30323136 // zig: _ref.* += 1;
30333137 // zig: break :blk _tmp
30343138 // zig: })
3035 const block_scope = try Scope.Block.init(rp.c, scope, "blk");
3036 block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
3139 var block_scope = try Scope.Block.init(rp.c, scope, "blk");
3140 defer block_scope.deinit();
30373141 const ref = try block_scope.makeMangledName(rp.c, "ref");
30383142
30393143 const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
......@@ -3042,7 +3146,7 @@ fn transCreatePostCrement(
30423146 rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value);
30433147 node.init_node = &rhs_node.base;
30443148 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
30473151 const lhs_node = try transCreateNodeIdentifier(rp.c, ref);
30483152 const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);
......@@ -3053,23 +3157,23 @@ fn transCreatePostCrement(
30533157 tmp_node.eq_token = try appendToken(rp.c, .Equal, "=");
30543158 tmp_node.init_node = ref_node;
30553159 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
30583162 const token = try appendToken(rp.c, op_tok_id, bytes);
30593163 const one = try transCreateNodeInt(rp.c, 1);
30603164 _ = try appendToken(rp.c, .Semicolon, ";");
30613165 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
30643168 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
30653169 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);
30673171 _ = 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);
30693173 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
30703174 grouped_expr.* = .{
30713175 .lparen = try appendToken(rp.c, .LParen, "("),
3072 .expr = &block_scope.block_node.base,
3176 .expr = &block_node.base,
30733177 .rparen = try appendToken(rp.c, .RParen, ")"),
30743178 };
30753179 return &grouped_expr.base;
......@@ -3134,11 +3238,11 @@ fn transCreateCompoundAssign(
31343238 const op_token = try appendToken(rp.c, .Equal, "=");
31353239 const op_node = try rp.c.arena.create(ast.Node.InfixOp);
31363240 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);
31383242 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;
31403244 _ = 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);
31423246 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
31433247 op_node.* = .{
31443248 .op_token = op_token,
......@@ -3158,11 +3262,11 @@ fn transCreateCompoundAssign(
31583262 try transExpr(rp, scope, rhs, .used, .r_value);
31593263
31603264 if (is_shift) {
3161 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
3265 const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
31623266 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;
31643268 _ = try appendToken(rp.c, .Comma, ",");
3165 try cast_node.params.push(rhs_node);
3269 cast_node.params()[1] = rhs_node;
31663270 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
31673271 rhs_node = &cast_node.base;
31683272 }
......@@ -3177,8 +3281,8 @@ fn transCreateCompoundAssign(
31773281 // zig: _ref.* = _ref.* + rhs;
31783282 // zig: break :blk _ref.*
31793283 // zig: })
3180 const block_scope = try Scope.Block.init(rp.c, scope, "blk");
3181 block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
3284 var block_scope = try Scope.Block.init(rp.c, scope, "blk");
3285 defer block_scope.deinit();
31823286 const ref = try block_scope.makeMangledName(rp.c, "ref");
31833287
31843288 const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
......@@ -3187,7 +3291,7 @@ fn transCreateCompoundAssign(
31873291 addr_node.rhs = try transExpr(rp, scope, lhs, .used, .l_value);
31883292 node.init_node = &addr_node.base;
31893293 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
31923296 const lhs_node = try transCreateNodeIdentifier(rp.c, ref);
31933297 const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);
......@@ -3197,10 +3301,10 @@ fn transCreateCompoundAssign(
31973301 const op_token = try appendToken(rp.c, .Equal, "=");
31983302 const op_node = try rp.c.arena.create(ast.Node.InfixOp);
31993303 const builtin = if (is_mod) "@rem" else "@divTrunc";
3200 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, builtin);
3201 try builtin_node.params.push(try transCreateNodePtrDeref(rp.c, lhs_node));
3304 const builtin_node = try rp.c.createBuiltinCall(builtin, 2);
3305 builtin_node.params()[0] = try transCreateNodePtrDeref(rp.c, lhs_node);
32023306 _ = 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);
32043308 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
32053309 _ = try appendToken(rp.c, .Semicolon, ";");
32063310 op_node.* = .{
......@@ -3210,17 +3314,17 @@ fn transCreateCompoundAssign(
32103314 .rhs = &builtin_node.base,
32113315 };
32123316 _ = 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);
32143318 } else {
32153319 const bin_token = try appendToken(rp.c, bin_tok_id, bin_bytes);
32163320 var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
32173321
32183322 if (is_shift) {
3219 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
3323 const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
32203324 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;
32223326 _ = try appendToken(rp.c, .Comma, ",");
3223 try cast_node.params.push(rhs_node);
3327 cast_node.params()[1] = rhs_node;
32243328 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
32253329 rhs_node = &cast_node.base;
32263330 }
......@@ -3230,17 +3334,17 @@ fn transCreateCompoundAssign(
32303334
32313335 const eq_token = try appendToken(rp.c, .Equal, "=");
32323336 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);
32343338 }
32353339
32363340 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
32373341 break_node.rhs = ref_node;
3238 try block_scope.block_node.statements.push(&break_node.base);
3239 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
3342 try block_scope.statements.append(&break_node.base);
3343 const block_node = try block_scope.complete(rp.c);
32403344 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
32413345 grouped_expr.* = .{
32423346 .lparen = try appendToken(rp.c, .LParen, "("),
3243 .expr = &block_scope.block_node.base,
3347 .expr = &block_node.base,
32443348 .rparen = try appendToken(rp.c, .RParen, ")"),
32453349 };
32463350 return &grouped_expr.base;
......@@ -3264,43 +3368,43 @@ fn transCPtrCast(
32643368 !ZigClangQualType_isVolatileQualified(child_type)))
32653369 {
32663370 // 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);
32683372 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;
32703374 _ = try appendToken(rp.c, .Comma, ",");
32713375
3272 const ptrtoint_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
3273 try ptrtoint_node.params.push(expr);
3376 const ptrtoint_node = try rp.c.createBuiltinCall("@ptrToInt", 1);
3377 ptrtoint_node.params()[0] = expr;
32743378 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;
32773381 inttoptr_node.rparen_token = try appendToken(rp.c, .RParen, ")");
32783382 return &inttoptr_node.base;
32793383 } else {
32803384 // Implicit downcasting from higher to lower alignment values is forbidden,
32813385 // 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);
32833387 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;
32853389 _ = try appendToken(rp.c, .Comma, ",");
32863390
32873391 if (ZigClangType_isVoidType(qualTypeCanon(child_type))) {
32883392 // void has 1-byte alignment, so @alignCast is not needed
3289 try ptrcast_node.params.push(expr);
3393 ptrcast_node.params()[1] = expr;
32903394 } else if (typeIsOpaque(rp.c, qualTypeCanon(child_type), loc)) {
32913395 // For opaque types a ptrCast is enough
3292 try ptrcast_node.params.push(expr);
3396 ptrcast_node.params()[1] = expr;
32933397 } else {
3294 const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast");
3295 const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf");
3398 const aligncast_node = try rp.c.createBuiltinCall("@alignCast", 2);
3399 const alignof_node = try rp.c.createBuiltinCall("@alignOf", 1);
32963400 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;
32983402 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;
33003404 _ = try appendToken(rp.c, .Comma, ",");
3301 try aligncast_node.params.push(expr);
3405 aligncast_node.params()[1] = expr;
33023406 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;
33043408 }
33053409 ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
33063410
......@@ -3343,27 +3447,30 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const
33433447 // })
33443448 const lparen = try appendToken(rp.c, .LParen, "(");
33453449
3346 const block_scope = try Scope.Block.init(rp.c, scope, "blk");
3347 block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
3450 var block_scope = try Scope.Block.init(rp.c, scope, "blk");
3451 defer block_scope.deinit();
33483452
33493453 const mangled_name = try block_scope.makeMangledName(rp.c, "cond_temp");
33503454 const tmp_var = try transCreateNodeVarDecl(rp.c, false, true, mangled_name);
33513455 tmp_var.eq_token = try appendToken(rp.c, .Equal, "=");
33523456 tmp_var.init_node = try transExpr(rp, &block_scope.base, cond_expr, .used, .r_value);
33533457 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
33563460 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
33573461
33583462 const if_node = try transCreateNodeIf(rp.c);
3359 var cond_scope = Scope{
3360 .parent = &block_scope.base,
3361 .id = .Condition,
3463 var cond_scope = Scope.Condition{
3464 .base = .{
3465 .parent = &block_scope.base,
3466 .id = .Condition,
3467 },
33623468 };
3469 defer cond_scope.deinit();
33633470 const tmp_var_node = try transCreateNodeIdentifier(rp.c, mangled_name);
33643471
33653472 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);
33673474 if_node.condition = cond_node;
33683475 _ = try appendToken(rp.c, .RParen, ")");
33693476
......@@ -3374,13 +3481,13 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const
33743481
33753482 break_node.rhs = &if_node.base;
33763483 _ = try appendToken(rp.c, .Semicolon, ";");
3377 try block_scope.block_node.statements.push(&break_node.base);
3378 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
3484 try block_scope.statements.append(&break_node.base);
3485 const block_node = block_scope.complete(rp.c);
33793486
33803487 const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
33813488 grouped_expr.* = .{
33823489 .lparen = lparen,
3383 .expr = &block_scope.block_node.base,
3490 .expr = &block_node.base,
33843491 .rparen = try appendToken(rp.c, .RParen, ")"),
33853492 };
33863493 return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
......@@ -3390,17 +3497,20 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla
33903497 const grouped = scope.id == .Condition;
33913498 const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined;
33923499 const if_node = try transCreateNodeIf(rp.c);
3393 var cond_scope = Scope{
3394 .parent = scope,
3395 .id = .Condition,
3500 var cond_scope = Scope.Condition{
3501 .base = .{
3502 .parent = scope,
3503 .id = .Condition,
3504 },
33963505 };
3506 defer cond_scope.deinit();
33973507
33983508 const casted_stmt = @ptrCast(*const ZigClangAbstractConditionalOperator, stmt);
33993509 const cond_expr = ZigClangAbstractConditionalOperator_getCond(casted_stmt);
34003510 const true_expr = ZigClangAbstractConditionalOperator_getTrueExpr(casted_stmt);
34013511 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);
34043514 _ = try appendToken(rp.c, .RParen, ")");
34053515
34063516 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
35713681 // Symbol "Log2Int"
35723682 // 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);
35753685 const std_token = try appendToken(rp.c, .StringLiteral, "\"std\"");
35763686 const std_node = try rp.c.arena.create(ast.Node.StringLiteral);
35773687 std_node.* = .{
35783688 .token = std_token,
35793689 };
3580 try import_fn_call.params.push(&std_node.base);
3690 import_fn_call.params()[0] = &std_node.base;
35813691 import_fn_call.rparen_token = try appendToken(rp.c, .RParen, ")");
35823692
35833693 const inner_field_access = try transCreateNodeFieldAccess(rp.c, &import_fn_call.base, "math");
35843694 const outer_field_access = try transCreateNodeFieldAccess(rp.c, inner_field_access, "Log2Int");
3585 const log2int_fn_call = try transCreateNodeFnCall(rp.c, outer_field_access);
3586 try @fieldParentPtr(ast.Node.SuffixOp, "base", &log2int_fn_call.base).op.Call.params.push(zig_type_node);
3695 const log2int_fn_call = try rp.c.createCall(outer_field_access, 1);
3696 log2int_fn_call.params()[0] = zig_type_node;
35873697 log2int_fn_call.rtoken = try appendToken(rp.c, .RParen, ")");
35883698
35893699 return &log2int_fn_call.base;
......@@ -3757,8 +3867,8 @@ fn transCreateNodeAssign(
37573867 const eq_token = try appendToken(rp.c, .Equal, "=");
37583868 var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value);
37593869 if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {
3760 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
3761 try builtin_node.params.push(rhs_node);
3870 const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
3871 builtin_node.params()[0] = rhs_node;
37623872 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
37633873 rhs_node = &builtin_node.base;
37643874 }
......@@ -3774,22 +3884,23 @@ fn transCreateNodeAssign(
37743884 // zig: lhs = _tmp;
37753885 // zig: break :blk _tmp
37763886 // zig: })
3777 const block_scope = try Scope.Block.init(rp.c, scope, "blk");
3778 block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
3887 var block_scope = try Scope.Block.init(rp.c, scope, "blk");
3888 defer block_scope.deinit();
3889
37793890 const tmp = try block_scope.makeMangledName(rp.c, "tmp");
37803891
37813892 const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);
37823893 node.eq_token = try appendToken(rp.c, .Equal, "=");
37833894 var rhs_node = try transExpr(rp, &block_scope.base, rhs, .used, .r_value);
37843895 if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {
3785 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
3786 try builtin_node.params.push(rhs_node);
3896 const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
3897 builtin_node.params()[0] = rhs_node;
37873898 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
37883899 rhs_node = &builtin_node.base;
37893900 }
37903901 node.init_node = rhs_node;
37913902 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
37943905 const lhs_node = try transExpr(rp, &block_scope.base, lhs, .used, .l_value);
37953906 const eq_token = try appendToken(rp.c, .Equal, "=");
......@@ -3797,44 +3908,16 @@ fn transCreateNodeAssign(
37973908 _ = try appendToken(rp.c, .Semicolon, ";");
37983909
37993910 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
38023913 const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
38033914 break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp);
38043915 _ = try appendToken(rp.c, .Semicolon, ";");
3805 try block_scope.block_node.statements.push(&break_node.base);
3806 block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
3916 try block_scope.statements.append(&break_node.base);
3917 const block_node = try block_scope.complete(rp.c);
38073918 // semicolon must immediately follow rbrace because it is the last token in a block
38083919 _ = try appendToken(rp.c, .Semicolon, ";");
3809 return &block_scope.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;
3920 return &block_node.base;
38383921}
38393922
38403923fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []const u8) !*ast.Node {
......@@ -4083,8 +4166,8 @@ fn transCreateNodeFloat(c: *Context, int: var) !*ast.Node {
40834166}
40844167
40854168fn transCreateNodeOpaqueType(c: *Context) !*ast.Node {
4086 const call_node = try transCreateNodeBuiltinFnCall(c, "@Type");
4087 try call_node.params.push(try transCreateNodeEnumLiteral(c, "Opaque"));
4169 const call_node = try c.createBuiltinCall("@Type", 1);
4170 call_node.params()[0] = try transCreateNodeEnumLiteral(c, "Opaque");
40884171 call_node.rparen_token = try appendToken(c, .RParen, ")");
40894172 return &call_node.base;
40904173}
......@@ -4139,26 +4222,33 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
41394222 };
41404223 mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items);
41414224
4142 const block = try transCreateNodeBlock(c, null);
4143 var block_statements_it = &block.statements.first;
4225 const block_lbrace = try appendToken(c, .LBrace, "{");
41444226
41454227 const return_expr = try transCreateNodeReturnExpr(c);
41464228 const unwrap_expr = try transCreateNodeUnwrapNull(c, ref.cast(ast.Node.VarDecl).?.init_node.?);
4147 const call_expr = try transCreateNodeFnCall(c, unwrap_expr);
4148 var call_params_it = &call_expr.op.Call.params.first;
4229
4230 const call_expr = try c.createCall(unwrap_expr, fn_params.items.len);
4231 const call_params = call_expr.params();
41494232
41504233 for (fn_params.items) |param, i| {
41514234 if (i != 0) {
41524235 _ = try appendToken(c, .Comma, ",");
41534236 }
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.?));
41554238 }
41564239 call_expr.rtoken = try appendToken(c, .RParen, ")");
4240
41574241 return_expr.rhs = &call_expr.base;
41584242 _ = try appendToken(c, .Semicolon, ";");
41594243
4160 block.rbrace = try appendToken(c, .RBrace, "}");
4161 block_statements_it = try c.llpush(*ast.Node, block_statements_it, &return_expr.base);
4244 const block = try ast.Node.Block.alloc(c.arena, 1);
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;
41624252 fn_proto.body_node = &block.base;
41634253 return &fn_proto.base;
41644254}
......@@ -4216,22 +4306,6 @@ fn transCreateNodeElse(c: *Context) !*ast.Node.Else {
42164306 return node;
42174307}
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
42354309fn transCreateNodeBreak(c: *Context, label: ?[]const u8) !*ast.Node.ControlFlowExpression {
42364310 const ltoken = try appendToken(c, .Keyword_break, "break");
42374311 const label_node = if (label) |l| blk: {
......@@ -4302,20 +4376,6 @@ fn transCreateNodeContinue(c: *Context) !*ast.Node {
43024376 return &node.base;
43034377}
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
43194379fn transCreateNodeSwitchCase(c: *Context, lhs: *ast.Node) !*ast.Node.SwitchCase {
43204380 const arrow_tok = try appendToken(c, .EqualAngleBracketRight, "=>");
43214381
......@@ -4356,12 +4416,12 @@ fn transCreateNodeShiftOp(
43564416 const lhs = try transExpr(rp, scope, lhs_expr, .used, .l_value);
43574417 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);
43604420 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;
43624422 _ = try appendToken(rp.c, .Comma, ",");
43634423 const rhs = try transExprCoercing(rp, scope, rhs_expr, .used, .r_value);
4364 try cast_node.params.push(rhs);
4424 cast_node.params()[1] = rhs;
43654425 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
43664426
43674427 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
48324892 .token = msg_tok,
48334893 };
48344894
4835 const call_node = try c.arena.create(ast.Node.BuiltinCall);
4895 const call_node = try ast.Node.BuiltinCall.alloc(c.arena, 1);
48364896 call_node.* = .{
48374897 .builtin_token = builtin_tok,
4838 .params = ast.Node.BuiltinCall.ParamList{},
4898 .params_len = 1,
48394899 .rparen_token = rparen_tok,
48404900 };
4841 var call_params_it = &call_node.params.first;
4842 call_params_it = try c.llpush(*ast.Node, call_params_it, &msg_node.base);
4901 call_node.params()[0] = &msg_node.base;
48434902
48444903 const var_decl_node = try c.arena.create(ast.Node.VarDecl);
48454904 var_decl_node.* = .{
......@@ -4868,23 +4927,20 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd
48684927
48694928fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex {
48704929 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);
4875 const end_index = c.source_buffer.items.len;
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);
4931 try c.token_ids.ensureCapacity(c.gpa, c.token_ids.items.len + 1);
4932 try c.token_locs.ensureCapacity(c.gpa, c.token_locs.items.len + 1);
48794933
4880 new_token.* = .{
4881 .id = token_id,
4934 const start_index = c.source_buffer.items.len;
4935 try c.source_buffer.outStream().print(format ++ " ", args);
4936
4937 c.token_ids.appendAssumeCapacity(token_id);
4938 c.token_locs.appendAssumeCapacity(.{
48824939 .start = start_index,
4883 .end = end_index,
4884 };
4885 try c.source_buffer.append(' ');
4940 .end = c.source_buffer.items.len - 1, // back up before the space
4941 });
48864942
4887 return token_index;
4943 return c.token_ids.items.len - 1;
48884944}
48894945
48904946// TODO hook up with codegen
......@@ -5072,7 +5128,8 @@ fn transMacroDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, n
50725128}
50735129
50745130fn 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();
50765133 const scope = &block_scope.base;
50775134
50785135 const pub_tok = try appendToken(c, .Keyword_pub, "pub");
......@@ -5142,9 +5199,7 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
51425199
51435200 _ = try appendToken(c, .RParen, ")");
51445201
5145 const type_of = try transCreateNodeBuiltinFnCall(c, "@TypeOf");
5146 type_of.rparen_token = try appendToken(c, .RParen, ")");
5147 var type_of_params = c.llpusher(&type_of.params);
5202 const type_of = try c.createBuiltinCall("@TypeOf", 1);
51485203
51495204 const fn_proto = try ast.Node.FnProto.alloc(c.arena, fn_params.items.len);
51505205 fn_proto.* = .{
......@@ -5164,9 +5219,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
51645219 };
51655220 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
51705222 const return_expr = try transCreateNodeReturnExpr(c);
51715223 const expr = try parseCExpr(c, it, source, source_loc, scope);
51725224 const last = it.next().?;
......@@ -5186,12 +5238,13 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
51865238 const br = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", blk_last);
51875239 break :blk br.rhs.?;
51885240 };
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, ")");
51905243 return_expr.rhs = expr;
51915244
5192 block.rbrace = try appendToken(c, .RBrace, "}");
5193 try block_statements.push(&return_expr.base);
5194 fn_proto.body_node = &block.base;
5245 try block_scope.statements.append(&return_expr.base);
5246 const block_node = try block_scope.complete(c);
5247 fn_proto.body_node = &block_node.base;
51955248 _ = try c.global_scope.macro_table.put(name, &fn_proto.base);
51965249}
51975250
......@@ -5223,8 +5276,8 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_
52235276 },
52245277 .Comma => {
52255278 _ = try appendToken(c, .Semicolon, ";");
5226 const block_scope = try Scope.Block.init(c, scope, "blk");
5227 block_scope.setBlockNode(try transCreateNodeBlock(c, block_scope.label));
5279 var block_scope = try Scope.Block.init(c, scope, "blk");
5280 defer block_scope.deinit();
52285281
52295282 var last = node;
52305283 while (true) {
......@@ -5238,7 +5291,7 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_
52385291 .op = .Assign,
52395292 .rhs = last,
52405293 };
5241 try block_scope.block_node.statements.push(&op_node.base);
5294 try block_scope.statements.append(&op_node.base);
52425295
52435296 last = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
52445297 _ = try appendToken(c, .Semicolon, ";");
......@@ -5250,9 +5303,9 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_
52505303
52515304 const break_node = try transCreateNodeBreak(c, block_scope.label);
52525305 break_node.rhs = last;
5253 try block_scope.block_node.statements.push(&break_node.base);
5254 block_scope.block_node.rbrace = try appendToken(c, .RBrace, "}");
5255 return &block_scope.block_node.base;
5306 try block_scope.statements.append(&break_node.base);
5307 const block_node = try block_scope.complete(c);
5308 return &block_node.base;
52565309 },
52575310 else => {
52585311 _ = it.prev();
......@@ -5283,15 +5336,15 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl
52835336 return transCreateNodeInt(c, lit_bytes);
52845337 }
52855338
5286 const cast_node = try transCreateNodeBuiltinFnCall(c, "@as");
5287 try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.id.IntegerLiteral) {
5339 const cast_node = try c.createBuiltinCall("@as", 2);
5340 cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (tok.id.IntegerLiteral) {
52885341 .U => "c_uint",
52895342 .L => "c_long",
52905343 .LU => "c_ulong",
52915344 .LL => "c_longlong",
52925345 .LLU => "c_ulonglong",
52935346 else => unreachable,
5294 }));
5347 });
52955348 lit_bytes = lit_bytes[0 .. lit_bytes.len - switch (tok.id.IntegerLiteral) {
52965349 .U, .L => @as(u8, 1),
52975350 .LU, .LL => 2,
......@@ -5299,7 +5352,7 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl
52995352 else => unreachable,
53005353 }];
53015354 _ = 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);
53035356 cast_node.rparen_token = try appendToken(c, .RParen, ")");
53045357 return &cast_node.base;
53055358 } else if (tok.id == .FloatLiteral) {
......@@ -5308,14 +5361,14 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl
53085361 if (tok.id.FloatLiteral == .None) {
53095362 return transCreateNodeFloat(c, lit_bytes);
53105363 }
5311 const cast_node = try transCreateNodeBuiltinFnCall(c, "@as");
5312 try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.id.FloatLiteral) {
5364 const cast_node = try c.createBuiltinCall("@as", 2);
5365 cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (tok.id.FloatLiteral) {
53135366 .F => "f32",
53145367 .L => "c_longdouble",
53155368 else => unreachable,
5316 }));
5369 });
53175370 _ = 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]);
53195372 cast_node.rparen_token = try appendToken(c, .RParen, ")");
53205373 return &cast_node.base;
53215374 } else unreachable;
......@@ -5585,8 +5638,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
55855638 //else
55865639 // @as(dest, x) )
55875640 const if_node = try transCreateNodeIf(c);
5588 const type_info_node = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
5589 try type_info_node.params.push(inner_node);
5641 const type_info_node = try rp.c.createBuiltinCall("@typeInfo", 1);
5642 type_info_node.params()[0] = inner_node;
55905643 type_info_node.rparen_token = try appendToken(c, .LParen, ")");
55915644 const cmp_node = try c.arena.create(ast.Node.InfixOp);
55925645 cmp_node.* = .{
......@@ -5598,18 +5651,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
55985651 if_node.condition = &cmp_node.base;
55995652 _ = try appendToken(c, .RParen, ")");
56005653
5601 const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr");
5602 try int_to_ptr.params.push(inner_node);
5603 try int_to_ptr.params.push(node_to_cast);
5654 const int_to_ptr = try c.createBuiltinCall("@intToPtr", 2);
5655 int_to_ptr.params()[0] = inner_node;
5656 int_to_ptr.params()[1] = node_to_cast;
56045657 int_to_ptr.rparen_token = try appendToken(c, .RParen, ")");
56055658 if_node.body = &int_to_ptr.base;
56065659
56075660 const else_node = try transCreateNodeElse(c);
56085661 if_node.@"else" = else_node;
56095662
5610 const as_node = try transCreateNodeBuiltinFnCall(c, "@as");
5611 try as_node.params.push(inner_node);
5612 try as_node.params.push(node_to_cast);
5663 const as_node = try c.createBuiltinCall("@as", 2);
5664 as_node.params()[0] = inner_node;
5665 as_node.params()[1] = node_to_cast;
56135666 as_node.rparen_token = try appendToken(c, .RParen, ")");
56145667 else_node.body = &as_node.base;
56155668
......@@ -5630,10 +5683,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
56305683 // @as(dest, x) )
56315684
56325685 const if_1 = try transCreateNodeIf(c);
5633 const type_info_1 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
5634 const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");
5635 try type_info_1.params.push(&type_of_1.base);
5636 try type_of_1.params.push(node_to_cast);
5686 const type_info_1 = try c.createBuiltinCall("@typeInfo", 1);
5687 const type_of_1 = try c.createBuiltinCall("@TypeOf", 1);
5688 type_info_1.params()[0] = &type_of_1.base;
5689 type_of_1.params()[0] = node_to_cast;
56375690 type_of_1.rparen_token = try appendToken(c, .RParen, ")");
56385691 type_info_1.rparen_token = try appendToken(c, .RParen, ")");
56395692
......@@ -5657,20 +5710,20 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
56575710 .rhs = child_ident,
56585711 };
56595712
5660 const align_of = try transCreateNodeBuiltinFnCall(c, "@alignOf");
5661 try align_of.params.push(&inner_node_child.base);
5713 const align_of = try rp.c.createBuiltinCall("@alignOf", 1);
5714 align_of.params()[0] = &inner_node_child.base;
56625715 align_of.rparen_token = try appendToken(c, .RParen, ")");
56635716 // hack to get zig fmt to render a comma in builtin calls
56645717 _ = try appendToken(c, .Comma, ",");
56655718
5666 const align_cast = try transCreateNodeBuiltinFnCall(c, "@alignCast");
5667 try align_cast.params.push(&align_of.base);
5668 try align_cast.params.push(node_to_cast);
5719 const align_cast = try c.createBuiltinCall("@alignCast", 2);
5720 align_cast.params()[0] = &align_of.base;
5721 align_cast.params()[1] = node_to_cast;
56695722 align_cast.rparen_token = try appendToken(c, .RParen, ")");
56705723
5671 const ptr_cast = try transCreateNodeBuiltinFnCall(c, "@ptrCast");
5672 try ptr_cast.params.push(inner_node);
5673 try ptr_cast.params.push(&align_cast.base);
5724 const ptr_cast = try c.createBuiltinCall("@ptrCast", 2);
5725 ptr_cast.params()[0] = inner_node;
5726 ptr_cast.params()[1] = &align_cast.base;
56745727 ptr_cast.rparen_token = try appendToken(c, .RParen, ")");
56755728 if_1.body = &ptr_cast.base;
56765729
......@@ -5678,10 +5731,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
56785731 if_1.@"else" = else_1;
56795732
56805733 const if_2 = try transCreateNodeIf(c);
5681 const type_info_2 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
5682 const type_of_2 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");
5683 try type_info_2.params.push(&type_of_2.base);
5684 try type_of_2.params.push(node_to_cast);
5734 const type_info_2 = try c.createBuiltinCall("@typeInfo", 1);
5735 const type_of_2 = try c.createBuiltinCall("@TypeOf", 1);
5736 type_info_2.params()[0] = &type_of_2.base;
5737 type_of_2.params()[0] = node_to_cast;
56855738 type_of_2.rparen_token = try appendToken(c, .RParen, ")");
56865739 type_info_2.rparen_token = try appendToken(c, .RParen, ")");
56875740
......@@ -5700,8 +5753,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
57005753 .op = .BoolAnd,
57015754 .rhs = undefined,
57025755 };
5703 const type_info_3 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
5704 try type_info_3.params.push(inner_node);
5756 const type_info_3 = try c.createBuiltinCall("@typeInfo", 1);
5757 type_info_3.params()[0] = inner_node;
57055758 type_info_3.rparen_token = try appendToken(c, .LParen, ")");
57065759 const cmp_3 = try c.arena.create(ast.Node.InfixOp);
57075760 cmp_3.* = .{
......@@ -5715,18 +5768,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
57155768 else_1.body = &if_2.base;
57165769 _ = try appendToken(c, .RParen, ")");
57175770
5718 const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr");
5719 try int_to_ptr.params.push(inner_node);
5720 try int_to_ptr.params.push(node_to_cast);
5771 const int_to_ptr = try c.createBuiltinCall("@intToPtr", 2);
5772 int_to_ptr.params()[0] = inner_node;
5773 int_to_ptr.params()[1] = node_to_cast;
57215774 int_to_ptr.rparen_token = try appendToken(c, .RParen, ")");
57225775 if_2.body = &int_to_ptr.base;
57235776
57245777 const else_2 = try transCreateNodeElse(c);
57255778 if_2.@"else" = else_2;
57265779
5727 const as = try transCreateNodeBuiltinFnCall(c, "@as");
5728 try as.params.push(inner_node);
5729 try as.params.push(node_to_cast);
5780 const as = try c.createBuiltinCall("@as", 2);
5781 as.params()[0] = inner_node;
5782 as.params()[1] = node_to_cast;
57305783 as.rparen_token = try appendToken(c, .RParen, ")");
57315784 else_2.body = &as.base;
57325785
......@@ -5765,8 +5818,8 @@ fn macroBoolToInt(c: *Context, node: *ast.Node) !*ast.Node {
57655818 return &group_node.base;
57665819 }
57675820
5768 const builtin_node = try transCreateNodeBuiltinFnCall(c, "@boolToInt");
5769 try builtin_node.params.push(node);
5821 const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
5822 builtin_node.params()[0] = node;
57705823 builtin_node.rparen_token = try appendToken(c, .RParen, ")");
57715824 return &builtin_node.base;
57725825}
......@@ -5944,10 +5997,12 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
59445997 continue;
59455998 },
59465999 .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();
59486003 while (true) {
59496004 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);
59516006 const next = it.next().?;
59526007 if (next.id == .Comma)
59536008 _ = try appendToken(c, .Comma, ",")
......@@ -5965,7 +6020,14 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
59656020 return error.ParseError;
59666021 }
59676022 }
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);
59696031 node = &call_node.base;
59706032 continue;
59716033 },