Commit e072692e1f
Changed files (2)
src-self-hosted
src-self-hosted/clang.zig
@@ -63,7 +63,7 @@ pub const struct_ZigClangReturnStmt = @Type(.Opaque);
pub const struct_ZigClangSkipFunctionBodiesScope = @Type(.Opaque);
pub const struct_ZigClangSourceManager = @Type(.Opaque);
pub const struct_ZigClangSourceRange = @Type(.Opaque);
-pub const struct_ZigClangStmt = @Type(.Opaque);
+pub const ZigClangStmt = @Type(.Opaque);
pub const struct_ZigClangStringLiteral = @Type(.Opaque);
pub const struct_ZigClangStringRef = @Type(.Opaque);
pub const struct_ZigClangSwitchStmt = @Type(.Opaque);
@@ -842,9 +842,9 @@ pub extern fn ZigClangType_getTypeClassName(self: *const struct_ZigClangType) [*
pub extern fn ZigClangType_getAsArrayTypeUnsafe(self: *const ZigClangType) *const ZigClangArrayType;
pub extern fn ZigClangType_getAsRecordType(self: *const ZigClangType) ?*const ZigClangRecordType;
pub extern fn ZigClangType_getAsUnionType(self: *const ZigClangType) ?*const ZigClangRecordType;
-pub extern fn ZigClangStmt_getBeginLoc(self: *const struct_ZigClangStmt) struct_ZigClangSourceLocation;
-pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) ZigClangStmtClass;
-pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;
+pub extern fn ZigClangStmt_getBeginLoc(self: *const ZigClangStmt) struct_ZigClangSourceLocation;
+pub extern fn ZigClangStmt_getStmtClass(self: ?*const ZigClangStmt) ZigClangStmtClass;
+pub extern fn ZigClangStmt_classof_Expr(self: ?*const ZigClangStmt) bool;
pub extern fn ZigClangExpr_getStmtClass(self: *const struct_ZigClangExpr) ZigClangStmtClass;
pub extern fn ZigClangExpr_getType(self: *const struct_ZigClangExpr) struct_ZigClangQualType;
pub extern fn ZigClangExpr_getBeginLoc(self: *const struct_ZigClangExpr) struct_ZigClangSourceLocation;
@@ -873,7 +873,7 @@ pub extern fn ZigClangFunctionDecl_getLocation(self: *const ZigClangFunctionDecl
pub extern fn ZigClangFunctionDecl_hasBody(self: *const ZigClangFunctionDecl) bool;
pub extern fn ZigClangFunctionDecl_getStorageClass(self: *const ZigClangFunctionDecl) ZigClangStorageClass;
pub extern fn ZigClangFunctionDecl_getParamDecl(self: *const ZigClangFunctionDecl, i: c_uint) *const struct_ZigClangParmVarDecl;
-pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const struct_ZigClangStmt;
+pub extern fn ZigClangFunctionDecl_getBody(self: *const ZigClangFunctionDecl) *const ZigClangStmt;
pub extern fn ZigClangFunctionDecl_doesDeclarationForceExternallyVisibleDefinition(self: *const ZigClangFunctionDecl) bool;
pub extern fn ZigClangFunctionDecl_isThisDeclarationADefinition(self: *const ZigClangFunctionDecl) bool;
pub extern fn ZigClangFunctionDecl_doesThisDeclarationHaveABody(self: *const ZigClangFunctionDecl) bool;
@@ -959,7 +959,6 @@ pub const ZigClangReturnStmt = struct_ZigClangReturnStmt;
pub const ZigClangSkipFunctionBodiesScope = struct_ZigClangSkipFunctionBodiesScope;
pub const ZigClangSourceManager = struct_ZigClangSourceManager;
pub const ZigClangSourceRange = struct_ZigClangSourceRange;
-pub const ZigClangStmt = struct_ZigClangStmt;
pub const ZigClangStringLiteral = struct_ZigClangStringLiteral;
pub const ZigClangStringRef = struct_ZigClangStringRef;
pub const ZigClangSwitchStmt = struct_ZigClangSwitchStmt;
@@ -1018,7 +1017,7 @@ pub extern fn ZigClangLoadFromCommandLine(
pub extern fn ZigClangDecl_getKind(decl: *const ZigClangDecl) ZigClangDeclKind;
pub extern fn ZigClangDecl_getDeclKindName(decl: *const struct_ZigClangDecl) [*:0]const u8;
-pub const ZigClangCompoundStmt_const_body_iterator = [*]const *struct_ZigClangStmt;
+pub const ZigClangCompoundStmt_const_body_iterator = [*]const *ZigClangStmt;
pub extern fn ZigClangCompoundStmt_body_begin(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
pub extern fn ZigClangCompoundStmt_body_end(self: *const ZigClangCompoundStmt) ZigClangCompoundStmt_const_body_iterator;
src-self-hosted/translate_c.zig
@@ -54,44 +54,79 @@ const Scope = struct {
Loop,
};
+ /// Represents an in-progress ast.Node.Switch. This struct is stack-allocated.
+ /// When it is deinitialized, it produces an ast.Node.Switch which is allocated
+ /// into the main arena.
const Switch = struct {
base: Scope,
- pending_block: *ast.Node.Block,
- cases: *ast.Node.Switch.CaseList,
+ pending_block: *Block,
+ cases: []*ast.Node,
+ case_index: usize,
has_default: bool = false,
};
+ /// Used for the scope of condition expressions, for example `if (cond)`.
+ /// The block is lazily initialised because it is only needed for rare
+ /// cases of comma operators being used.
+ const Condition = struct {
+ base: Scope,
+ block: ?Block = null,
+
+ fn getBlockScope(self: *Condition, c: *Context) !*Block {
+ if (self.block) |*b| return b;
+ self.block = try Block.init(c, &self.base, "blk");
+ return &self.block.?;
+ }
+
+ fn deinit(self: *Condition) void {
+ if (self.block) |*b| b.deinit();
+ }
+ };
+
+ /// Represents an in-progress ast.Node.Block. This struct is stack-allocated.
+ /// When it is deinitialized, it produces an ast.Node.Block which is allocated
+ /// into the main arena.
const Block = struct {
base: Scope,
- block_node: *ast.Node.Block,
- statements_it: *?*std.SinglyLinkedList(*ast.Node),
+ statements: std.ArrayList(*ast.Node),
variables: AliasList,
- label: ?[]const u8,
+ label: ?ast.TokenIndex,
mangle_count: u32 = 0,
+ lbrace: ast.TokenIndex,
- /// Don't forget to set rbrace token and block_node later
- fn init(c: *Context, parent: *Scope, label: ?[]const u8) !*Block {
- const block = try c.arena.create(Block);
- block.* = .{
+ fn init(c: *Context, parent: *Scope, label: ?[]const u8) !Block {
+ return Block{
.base = .{
.id = .Block,
.parent = parent,
},
- .block_node = undefined,
- .statements_it = undefined,
- .variables = AliasList.init(c.arena),
- .label = label,
+ .statements = std.ArrayList(*ast.Node).init(c.gpa),
+ .variables = AliasList.init(c.gpa),
+ .label = if (self.label) |l| blk: {
+ const ll = try appendIdentifier(c, l);
+ _ = try appendToken(c, .Colon, ":");
+ break :blk ll;
+ } else null,
+ .lbrace = try appendToken(c, .LBrace, "{"),
};
- return block;
}
- fn pushStatement(self: *Block, c: *Context, stmt: *ast.Node) !void {
- self.statements_it = c.llpush(*ast.Node, self.statements_it, stmt);
+ fn deinit(self: *Block) void {
+ self.statements.deinit();
+ self.variables.deinit();
+ self.* = undefined;
}
- fn setBlockNode(self: *Block, block: *ast.Node.Block) void {
- self.block_node = block;
- self.statements_it = &block.statements.first;
+ fn complete(self: *Block, c: *Context) !*ast.Node.Block {
+ const node = try ast.Node.Block.alloc(c.arena, self.statements.items.len);
+ node.* = .{
+ .statements_len = self.statements.items.len,
+ .lbrace = self.lbrace,
+ .rbrace = try appendToken(c, .RBrace, "}"),
+ .label = self.label,
+ };
+ mem.copy(*ast.Node, node.statements(), self.statements.items);
+ return node;
}
/// Given the desired name, return a name that does not shadow anything from outer scopes.
@@ -102,12 +137,13 @@ const Scope = struct {
scope.mangle_count += 1;
proposed_name = try std.fmt.allocPrint(c.arena, "{}_{}", .{ name, scope.mangle_count });
}
- try scope.variables.append(.{ .name = name, .alias = proposed_name });
+ try scope.variables.push(.{ .name = name, .alias = proposed_name });
return proposed_name;
}
fn getAlias(scope: *Block, name: []const u8) []const u8 {
- for (scope.variables.items) |p| {
+ var it = scope.variables.iterator(0);
+ while (it.next()) |p| {
if (mem.eql(u8, p.name, name))
return p.alias;
}
@@ -115,7 +151,8 @@ const Scope = struct {
}
fn localContains(scope: *Block, name: []const u8) bool {
- for (scope.variables.items) |p| {
+ var it = scope.variables.iterator(0);
+ while (it.next()) |p| {
if (mem.eql(u8, p.name, name))
return true;
}
@@ -167,10 +204,7 @@ const Scope = struct {
switch (scope.id) {
.Root => unreachable,
.Block => return @fieldParentPtr(Block, "base", scope),
- .Condition => {
- // comma operator used
- return try Block.init(c, scope, "blk");
- },
+ .Condition => return @fieldParentPtr(Condition, "base", scope).getBlockScope(c),
else => scope = scope.parent.?,
}
}
@@ -219,7 +253,8 @@ const Scope = struct {
pub const Context = struct {
gpa: *mem.Allocator,
arena: *mem.Allocator,
- tokens: std.ArrayListUnmanaged(Token),
+ token_ids: std.ArrayListUnmanaged(Token.Id),
+ token_locs: std.ArrayListUnmanaged(Token.Loc),
errors: std.ArrayListUnmanaged(ast.Error),
source_buffer: *std.ArrayList(u8),
err: Error,
@@ -237,16 +272,6 @@ pub const Context = struct {
/// up front in a pre-processing step.
global_names: std.StringHashMap(void),
- /// Helper type to append elements to a singly linked list.
- const LinkedListPusher = struct {
- c: *Context,
- it: *?*std.SinglyLinkedList(*ast.Node).Node,
-
- fn push(self: *LinkedListPusher, element: *ast.Node) !void {
- self.it = try self.c.llpush(*ast.Node, self.it, element);
- }
- };
-
fn getMangle(c: *Context) u32 {
c.mangle_count += 1;
return c.mangle_count;
@@ -267,6 +292,46 @@ pub const Context = struct {
const column = ZigClangSourceManager_getSpellingColumnNumber(c.source_manager, spelling_loc);
return std.fmt.allocPrint(c.arena, "{}:{}:{}", .{ filename, line, column });
}
+
+ fn createCall(c: *Context, fn_expr: *ast.Node, params_len: ast.NodeIndex) !*ast.Node.Call {
+ _ = try appendToken(c, .LParen, "(");
+ const node = try ast.Node.Call.alloc(c.arena, params_len);
+ node.* = .{
+ .lhs = fn_expr,
+ .params_len = params_len,
+ .async_token = null,
+ .rtoken = undefined, // set after appending args
+ };
+ return node;
+ }
+
+ fn createBuiltinCall(c: *Context, name: []const u8, params_len: ast.NodeIndex) !*ast.Node.BuiltinCall {
+ const builtin_token = try appendToken(c, .Builtin, name);
+ _ = try appendToken(c, .LParen, "(");
+ const node = try ast.Node.BuiltinCall.alloc(c.arena, params_len);
+ node.* = .{
+ .builtin_token = builtin_token,
+ .params_len = params_len,
+ .rparen_token = undefined, // set after appending args
+ };
+ return node;
+ }
+
+ fn createBlock(c: *Context, label: ?[]const u8, statements_len: ast.NodeIndex) !*ast.Node.Block {
+ const label_node = if (label) |l| blk: {
+ const ll = try appendIdentifier(c, l);
+ _ = try appendToken(c, .Colon, ":");
+ break :blk ll;
+ } else null;
+ const block_node = try ast.Node.Block.alloc(c.arena, statements_len);
+ block_node.* = .{
+ .label = label_node,
+ .lbrace = try appendToken(c, .LBrace, "{"),
+ .statements_len = statements_len,
+ .rbrace = undefined,
+ };
+ return block_node;
+ }
};
pub fn translate(
@@ -307,14 +372,16 @@ pub fn translate(
.global_scope = try arena.allocator.create(Scope.Root),
.clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
.global_names = std.StringHashMap(void).init(gpa),
- .tokens = .{},
+ .token_ids = .{},
+ .token_locs = .{},
.errors = .{},
.root_decls = .{},
};
context.global_scope.* = Scope.Root.init(&context);
defer context.decl_table.deinit();
defer context.alias_list.deinit();
- defer context.tokens.deinit(gpa);
+ defer context.token_ids.deinit(gpa);
+ defer context.token_locs.deinit(gpa);
defer context.errors.deinit(gpa);
defer context.global_names.deinit();
defer context.root_decls.deinit(gpa);
@@ -349,7 +416,8 @@ pub fn translate(
tree.* = .{
.gpa = gpa,
.source = try arena.allocator.dupe(u8, source_buffer.items),
- .tokens = context.tokens.toOwnedSlice(gpa),
+ .token_ids = context.token_ids.toOwnedSlice(gpa),
+ .token_locs = context.token_locs.toOwnedSlice(gpa),
.errors = context.errors.toOwnedSlice(gpa),
.root_node = root_node,
.arena = arena.state,
@@ -508,10 +576,9 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
// actual function definition with body
const body_stmt = ZigClangFunctionDecl_getBody(fn_decl);
- const block_scope = try Scope.Block.init(rp.c, &c.global_scope.base, null);
+ var block_scope = try Scope.Block.init(rp.c, &c.global_scope.base, null);
+ defer block_scope.deinit();
var scope = &block_scope.base;
- const block_node = try transCreateNodeBlock(rp.c, null);
- block_scope.setBlockNode(block_node);
var param_id: c_uint = 0;
for (proto_node.params()) |param, i| {
@@ -541,7 +608,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
node.eq_token = try appendToken(c, .Equal, "=");
node.init_node = try transCreateNodeIdentifier(c, arg_name);
node.semicolon_token = try appendToken(c, .Semicolon, ";");
- block_scope.block_statements_it = try c.llpush(*ast.Node, block_scope.block_statements_it, &node.base);
+ try block_scope.statements.append(&node.base);
param.name_token = try appendIdentifier(c, arg_name);
_ = try appendToken(c, .Colon, ":");
}
@@ -549,14 +616,14 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
param_id += 1;
}
- transCompoundStmtInline(rp, &block_scope.base, @ptrCast(*const ZigClangCompoundStmt, body_stmt), block_node) catch |err| switch (err) {
+ const casted_body = @ptrCast(*const ZigClangCompoundStmt, body_stmt);
+ transCompoundStmtInline(rp, &block_scope.base, casted_body, &block_scope) catch |err| switch (err) {
error.OutOfMemory => |e| return e,
error.UnsupportedTranslation,
error.UnsupportedType,
=> return failDecl(c, fn_decl_loc, fn_name, "unable to translate function", .{}),
};
- block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
- proto_node.body_node = &block_node.base;
+ proto_node.body_node = try block_scope.complete(rp.c);
return addTopLevelDecl(c, fn_name, &proto_node.base);
}
@@ -999,7 +1066,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
// At this point we can rely on the enum emitting successfully.
const tld_node = try transCreateNodeVarDecl(c, true, true, enum_val_name);
tld_node.eq_token = try appendToken(c, .Equal, "=");
- const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt");
+ const cast_node = try rp.c.createBuiltinCall("@enumToInt", 1);
const enum_ident = try transCreateNodeIdentifier(c, name);
const period_tok = try appendToken(c, .Period, ".");
const field_ident = try transCreateNodeIdentifier(c, field_name);
@@ -1010,7 +1077,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
.op = .Period,
.rhs = field_ident,
};
- try cast_node.params.push(&field_access_node.base);
+ cast_node.params()[0] = &field_access_node.base;
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
tld_node.init_node = &cast_node.base;
tld_node.semicolon_token = try appendToken(c, .Semicolon, ";");
@@ -1104,7 +1171,7 @@ fn transStmt(
.WhileStmtClass => return transWhileLoop(rp, scope, @ptrCast(*const ZigClangWhileStmt, stmt)),
.DoStmtClass => return transDoWhileLoop(rp, scope, @ptrCast(*const ZigClangDoStmt, stmt)),
.NullStmtClass => {
- const block = try transCreateNodeBlock(rp.c, null);
+ const block = try rp.c.createBlock(null, 0);
block.rbrace = try appendToken(rp.c, .RBrace, "}");
return &block.base;
},
@@ -1170,27 +1237,23 @@ fn transBinaryOperator(
.Comma => {
const block_scope = try scope.findBlockScope(rp.c);
const expr = block_scope.base.parent == scope;
- const lparen = if (expr) blk: {
- const l = try appendToken(rp.c, .LParen, "(");
- block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
- break :blk l;
- } else undefined;
+ const lparen = if (expr) try appendToken(rp.c, .LParen, "(") else undefined;
const lhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getLHS(stmt), .unused, .r_value);
- try block_scope.statements.push(lhs);
+ try block_scope.statements.append(lhs);
const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
if (expr) {
_ = try appendToken(rp.c, .Semicolon, ";");
const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
break_node.rhs = rhs;
- try block_scope.block_node.statements.push(&break_node.base);
- block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
+ try block_scope.statements.append(&break_node.base);
+ const block_node = try block_scope.complete(rp.c);
const rparen = try appendToken(rp.c, .RParen, ")");
const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
grouped_expr.* = .{
.lparen = lparen,
- .expr = &block_scope.block_node.base,
+ .expr = &block_node.base,
.rparen = rparen,
};
return maybeSuppressResult(rp, scope, result_used, &grouped_expr.base);
@@ -1201,11 +1264,11 @@ fn transBinaryOperator(
.Div => {
if (cIsSignedInteger(qt)) {
// signed integer division uses @divTrunc
- const div_trunc_node = try transCreateNodeBuiltinFnCall(rp.c, "@divTrunc");
- try div_trunc_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value));
+ const div_trunc_node = try rp.c.createBuiltinCall("@divTrunc", 2);
+ div_trunc_node.params()[0] = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value);
_ = try appendToken(rp.c, .Comma, ",");
const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
- try div_trunc_node.params.push(rhs);
+ div_trunc_node.params()[1] = rhs;
div_trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return maybeSuppressResult(rp, scope, result_used, &div_trunc_node.base);
}
@@ -1213,11 +1276,11 @@ fn transBinaryOperator(
.Rem => {
if (cIsSignedInteger(qt)) {
// signed integer division uses @rem
- const rem_node = try transCreateNodeBuiltinFnCall(rp.c, "@rem");
- try rem_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value));
+ const rem_node = try rp.c.createBuiltinCall("@rem", 2);
+ rem_node.params()[0] = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value);
_ = try appendToken(rp.c, .Comma, ",");
const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
- try rem_node.params.push(rhs);
+ rem_node.params()[1] = rhs;
rem_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return maybeSuppressResult(rp, scope, result_used, &rem_node.base);
}
@@ -1321,15 +1384,15 @@ fn transBinaryOperator(
const rhs_node = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
const lhs = if (isBoolRes(lhs_node)) init: {
- const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
- try cast_node.params.push(lhs_node);
+ const cast_node = try rp.c.createBuiltinCall("@boolToInt", 1);
+ cast_node.params()[0] = lhs_node;
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
break :init &cast_node.base;
} else lhs_node;
const rhs = if (isBoolRes(rhs_node)) init: {
- const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
- try cast_node.params.push(rhs_node);
+ const cast_node = try rp.c.createBuiltinCall("@boolToInt", 1);
+ cast_node.params()[0] = rhs_node;
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
break :init &cast_node.base;
} else rhs_node;
@@ -1341,23 +1404,22 @@ fn transCompoundStmtInline(
rp: RestorePoint,
parent_scope: *Scope,
stmt: *const ZigClangCompoundStmt,
- block_node: *ast.Node.Block,
+ block: *Scope.Block,
) TransError!void {
var it = ZigClangCompoundStmt_body_begin(stmt);
const end_it = ZigClangCompoundStmt_body_end(stmt);
while (it != end_it) : (it += 1) {
const result = try transStmt(rp, parent_scope, it[0], .unused, .r_value);
- if (result != &block_node.base)
- try block_node.statements.push(result);
+ try block.statements.append(result);
}
}
fn transCompoundStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundStmt) TransError!*ast.Node {
- const block_scope = try Scope.Block.init(rp.c, scope, null);
- block_scope.setBlockNode(try transCreateNodeBlock(rp.c, null));
- try transCompoundStmtInline(rp, &block_scope.base, stmt, block_scope.block_node);
- block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
- return &block_scope.block_node.base;
+ var block_scope = try Scope.Block.init(rp.c, scope, null);
+ defer block_scope.deinit();
+ try transCompoundStmtInline(rp, &block_scope.base, stmt, &block_scope);
+ const node = block_scope.complete(c);
+ return &node.base;
}
fn transCStyleCastExprClass(
@@ -1411,14 +1473,14 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
else
try transCreateNodeUndefinedLiteral(c);
if (!qualTypeIsBoolean(qual_type) and isBoolRes(init_node)) {
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
- try builtin_node.params.push(init_node);
+ const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
+ builtin_node.params()[0] = init_node;
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
init_node = &builtin_node.base;
}
node.init_node = init_node;
node.semicolon_token = try appendToken(c, .Semicolon, ";");
- try block_scope.block_node.statements.push(&node.base);
+ try block_scope.statements.append(&node.base);
},
.Typedef => {
const typedef_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]);
@@ -1437,7 +1499,7 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
});
} else {
const node = (try transCreateNodeTypedef(rp, typedef_decl, false, mangled_name)) orelse return error.UnsupportedTranslation;
- try block_scope.block_node.statements.push(&node.base);
+ try block_scope.statements.append(&node.base);
}
},
else => |kind| return revertAndWarn(
@@ -1499,8 +1561,8 @@ fn transImplicitCastExpr(
},
.PointerToBoolean => {
// @ptrToInt(val) != 0
- const ptr_to_int = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
- try ptr_to_int.params.push(try transExpr(rp, scope, sub_expr, .used, .r_value));
+ const ptr_to_int = try rp.c.createBuiltinCall("@ptrToInt", 1);
+ ptr_to_int.params()[0] = try transExpr(rp, scope, sub_expr, .used, .r_value);
ptr_to_int.rparen_token = try appendToken(rp.c, .RParen, ")");
const op_token = try appendToken(rp.c, .BangEqual, "!=");
@@ -1724,13 +1786,11 @@ fn transIntegerLiteral(
// @as(T, x)
const expr_base = @ptrCast(*const ZigClangExpr, expr);
- const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
+ const as_node = try rp.c.createBuiltinCall("@as", 2);
const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base));
- try as_node.params.push(ty_node);
+ as_node.params()[0] = ty_node;
_ = try appendToken(rp.c, .Comma, ",");
-
- const int_lit_node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val));
- try as_node.params.push(int_lit_node);
+ as_node.params()[1] = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&eval_result.Val));
as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return maybeSuppressResult(rp, scope, result_used, &as_node.base);
@@ -1840,35 +1900,35 @@ fn transCCast(
// 2. Bit-cast to correct signed-ness
// @bitCast(dest_type, intermediate_value)
- const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast");
- try cast_node.params.push(try transQualType(rp, dst_type, loc));
+ const cast_node = try rp.c.createBuiltinCall("@bitCast", 2);
+ cast_node.params()[0] = try transQualType(rp, dst_type, loc);
_ = try appendToken(rp.c, .Comma, ",");
switch (cIntTypeCmp(dst_type, src_type)) {
.lt => {
// @truncate(SameSignSmallerInt, src_type)
- const trunc_node = try transCreateNodeBuiltinFnCall(rp.c, "@truncate");
+ const trunc_node = try rp.c.createBuiltinCall("@truncate", 2);
const ty_node = try transQualTypeIntWidthOf(rp.c, dst_type, cIsSignedInteger(src_type));
- try trunc_node.params.push(ty_node);
+ trunc_node.params()[0] = ty_node;
_ = try appendToken(rp.c, .Comma, ",");
- try trunc_node.params.push(expr);
+ trunc_node.params()[1] = expr;
trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")");
- try cast_node.params.push(&trunc_node.base);
+ cast_node.params()[1] = &trunc_node.base;
},
.gt => {
// @as(SameSignBiggerInt, src_type)
- const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
+ const as_node = try rp.c.createBuiltinCall("@as", 2);
const ty_node = try transQualTypeIntWidthOf(rp.c, dst_type, cIsSignedInteger(src_type));
- try as_node.params.push(ty_node);
+ as_node.params()[0] = ty_node;
_ = try appendToken(rp.c, .Comma, ",");
- try as_node.params.push(expr);
+ as_node.params()[1] = expr;
as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
- try cast_node.params.push(&as_node.base);
+ cast_node.params()[1] = &as_node.base;
},
.eq => {
- try cast_node.params.push(expr);
+ cast_node.params()[1] = expr;
},
}
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
@@ -1876,46 +1936,46 @@ fn transCCast(
}
if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) {
// @intCast(dest_type, @ptrToInt(val))
- const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
- try cast_node.params.push(try transQualType(rp, dst_type, loc));
+ const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
+ cast_node.params()[0] = try transQualType(rp, dst_type, loc);
_ = try appendToken(rp.c, .Comma, ",");
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
- try builtin_node.params.push(expr);
+ const builtin_node = try rp.c.createBuiltinCall("@ptrToInt", 1);
+ builtin_node.params()[0] = expr;
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
- try cast_node.params.push(&builtin_node.base);
+ cast_node.params()[1] = &builtin_node.base;
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &cast_node.base;
}
if (cIsInteger(src_type) and qualTypeIsPtr(dst_type)) {
// @intToPtr(dest_type, val)
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr");
- try builtin_node.params.push(try transQualType(rp, dst_type, loc));
+ const builtin_node = try rp.c.createBuiltinCall("@intToPtr", 2);
+ builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
_ = try appendToken(rp.c, .Comma, ",");
- try builtin_node.params.push(expr);
+ builtin_node.params()[1] = expr;
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &builtin_node.base;
}
if (cIsFloating(src_type) and cIsFloating(dst_type)) {
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@floatCast");
- try builtin_node.params.push(try transQualType(rp, dst_type, loc));
+ const builtin_node = try rp.c.createBuiltinCall("@floatCast", 2);
+ builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
_ = try appendToken(rp.c, .Comma, ",");
- try builtin_node.params.push(expr);
+ builtin_node.params()[1] = expr;
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &builtin_node.base;
}
if (cIsFloating(src_type) and !cIsFloating(dst_type)) {
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@floatToInt");
- try builtin_node.params.push(try transQualType(rp, dst_type, loc));
+ const builtin_node = try rp.c.createBuiltinCall("@floatToInt", 2);
+ builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
_ = try appendToken(rp.c, .Comma, ",");
- try builtin_node.params.push(expr);
+ builtin_node.params()[1] = expr;
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &builtin_node.base;
}
if (!cIsFloating(src_type) and cIsFloating(dst_type)) {
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToFloat");
- try builtin_node.params.push(try transQualType(rp, dst_type, loc));
+ const builtin_node = try rp.c.createBuiltinCall("@intToFloat", 2);
+ builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
_ = try appendToken(rp.c, .Comma, ",");
- try builtin_node.params.push(expr);
+ builtin_node.params()[1] = expr;
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &builtin_node.base;
}
@@ -1923,54 +1983,54 @@ fn transCCast(
!ZigClangType_isBooleanType(qualTypeCanon(dst_type)))
{
// @boolToInt returns either a comptime_int or a u1
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
- try builtin_node.params.push(expr);
+ const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
+ builtin_node.params()[0] = expr;
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
- const inner_cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
- try inner_cast_node.params.push(try transCreateNodeIdentifier(rp.c, "u1"));
+ const inner_cast_node = try rp.c.createBuiltinCall("@intCast", 2);
+ inner_cast_node.params()[0] = try transCreateNodeIdentifier(rp.c, "u1");
_ = try appendToken(rp.c, .Comma, ",");
- try inner_cast_node.params.push(&builtin_node.base);
+ inner_cast_node.params()[1] = &builtin_node.base;
inner_cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
- const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
- try cast_node.params.push(try transQualType(rp, dst_type, loc));
+ const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
+ cast_node.params()[0] = try transQualType(rp, dst_type, loc);
_ = try appendToken(rp.c, .Comma, ",");
if (cIsSignedInteger(dst_type)) {
- const bitcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast");
- try bitcast_node.params.push(try transCreateNodeIdentifier(rp.c, "i1"));
+ const bitcast_node = try rp.c.createBuiltinCall("@bitCast", 2);
+ bitcast_node.params()[0] = try transCreateNodeIdentifier(rp.c, "i1");
_ = try appendToken(rp.c, .Comma, ",");
- try bitcast_node.params.push(&inner_cast_node.base);
+ bitcast_node.params()[1] = &inner_cast_node.base;
bitcast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
- try cast_node.params.push(&bitcast_node.base);
+ cast_node.params()[1] = &bitcast_node.base;
} else {
- try cast_node.params.push(&inner_cast_node.base);
+ cast_node.params()[1] = &inner_cast_node.base;
}
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &cast_node.base;
}
if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) {
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");
- try builtin_node.params.push(try transQualType(rp, dst_type, loc));
+ const builtin_node = try rp.c.createBuiltinCall("@intToEnum", 2);
+ builtin_node.params()[0] = try transQualType(rp, dst_type, loc);
_ = try appendToken(rp.c, .Comma, ",");
- try builtin_node.params.push(expr);
+ builtin_node.params()[1] = expr;
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &builtin_node.base;
}
if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(src_type)) == .Enum and
ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) != .Enum)
{
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt");
- try builtin_node.params.push(expr);
+ const builtin_node = try rp.c.createBuiltinCall("@enumToInt", 1);
+ builtin_node.params()[0] = expr;
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &builtin_node.base;
}
- const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
- try cast_node.params.push(try transQualType(rp, dst_type, loc));
+ const cast_node = try rp.c.createBuiltinCall("@as", 2);
+ cast_node.params()[0] = try transQualType(rp, dst_type, loc);
_ = try appendToken(rp.c, .Comma, ",");
- try cast_node.params.push(expr);
+ cast_node.params()[1] = expr;
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &cast_node.base;
}
@@ -2077,12 +2137,13 @@ fn transInitListExprRecord(
_ = try appendToken(c, .LBrace, "{");
- const node = try rp.c.arena.create(ast.Node.StructInitializer);
+ const node = try ast.Node.StructInitializer.alloc(rp.c.arena, field_inits.items.len);
node.* = .{
.lhs = ty,
.rtoken = try appendToken(rp.c, .RBrace, "}"),
- .list = try rp.c.arena.dupe(*ast.Node, field_inits.items),
+ .list_len = field_inits.items.len,
};
+ mem.copy(*ast.Node, node.list(), field_inits.items);
return &node.base;
}
@@ -2292,11 +2353,15 @@ fn transIfStmt(
// if (c) t else e
const if_node = try transCreateNodeIf(rp.c);
- var cond_scope = Scope{
- .parent = scope,
- .id = .Condition,
+ var cond_scope = Scope.Condition{
+ .base = .{
+ .parent = scope,
+ .id = .Condition,
+ },
};
- if_node.condition = try transBoolExpr(rp, &cond_scope, @ptrCast(*const ZigClangExpr, ZigClangIfStmt_getCond(stmt)), .used, .r_value, false);
+ defer cond_scope.deinit();
+ const cond_expr = @ptrCast(*const ZigClangExpr, ZigClangIfStmt_getCond(stmt));
+ if_node.condition = try transBoolExpr(rp, &cond_scope.base, cond_expr, .used, .r_value, false);
_ = try appendToken(rp.c, .RParen, ")");
if_node.body = try transStmt(rp, scope, ZigClangIfStmt_getThen(stmt), .unused, .r_value);
@@ -2316,11 +2381,15 @@ fn transWhileLoop(
) TransError!*ast.Node {
const while_node = try transCreateNodeWhile(rp.c);
- var cond_scope = Scope{
- .parent = scope,
- .id = .Condition,
+ var cond_scope = Scope.Condition{
+ .base = .{
+ .parent = scope,
+ .id = .Condition,
+ },
};
- while_node.condition = try transBoolExpr(rp, &cond_scope, @ptrCast(*const ZigClangExpr, ZigClangWhileStmt_getCond(stmt)), .used, .r_value, false);
+ defer cond_scope.deinit();
+ const cond_expr = @ptrCast(*const ZigClangExpr, ZigClangWhileStmt_getCond(stmt));
+ while_node.condition = try transBoolExpr(rp, &cond_scope.base, cond_expr, .used, .r_value, false);
_ = try appendToken(rp.c, .RParen, ")");
var loop_scope = Scope{
@@ -2349,12 +2418,15 @@ fn transDoWhileLoop(
// if (!cond) break;
const if_node = try transCreateNodeIf(rp.c);
- var cond_scope = Scope{
- .parent = scope,
- .id = .Condition,
+ var cond_scope = Scope.Condition{
+ .base = .{
+ .parent = scope,
+ .id = .Condition,
+ },
};
+ defer cond_scope.deinit();
const prefix_op = try transCreateNodePrefixOp(rp.c, .BoolNot, .Bang, "!");
- prefix_op.rhs = try transBoolExpr(rp, &cond_scope, @ptrCast(*const ZigClangExpr, ZigClangDoStmt_getCond(stmt)), .used, .r_value, true);
+ prefix_op.rhs = try transBoolExpr(rp, &cond_scope.base, @ptrCast(*const ZigClangExpr, ZigClangDoStmt_getCond(stmt)), .used, .r_value, true);
_ = try appendToken(rp.c, .RParen, ")");
if_node.condition = &prefix_op.base;
if_node.body = &(try transCreateNodeBreak(rp.c, null)).base;
@@ -2404,24 +2476,26 @@ fn transForLoop(
.id = .Loop,
};
- var block_scope: ?*Scope.Block = null;
+ var block_scope: ?Scope.Block = null;
+ defer if (block_scope) |*bs| bs.deinit();
+
if (ZigClangForStmt_getInit(stmt)) |init| {
block_scope = try Scope.Block.init(rp.c, scope, null);
- const block = try transCreateNodeBlock(rp.c, null);
- block_scope.?.setBlockNode(block);
loop_scope.parent = &block_scope.?.base;
const result = try transStmt(rp, &block_scope.?.base, init, .unused, .r_value);
- if (result != &block.base)
- try block.statements.push(result);
+ try block_scope.statements.push(result);
}
- var cond_scope = Scope{
- .parent = scope,
- .id = .Condition,
+ var cond_scope = Scope.Condition{
+ .base = .{
+ .parent = scope,
+ .id = .Condition,
+ },
};
+ defer cond_scope.deinit();
const while_node = try transCreateNodeWhile(rp.c);
while_node.condition = if (ZigClangForStmt_getCond(stmt)) |cond|
- try transBoolExpr(rp, &cond_scope, cond, .used, .r_value, false)
+ try transBoolExpr(rp, &cond_scope.base, cond, .used, .r_value, false)
else
try transCreateNodeBoolLiteral(rp.c, true);
_ = try appendToken(rp.c, .RParen, ")");
@@ -2429,62 +2503,90 @@ fn transForLoop(
if (ZigClangForStmt_getInc(stmt)) |incr| {
_ = try appendToken(rp.c, .Colon, ":");
_ = try appendToken(rp.c, .LParen, "(");
- while_node.continue_expr = try transExpr(rp, &cond_scope, incr, .unused, .r_value);
+ while_node.continue_expr = try transExpr(rp, &cond_scope.base, incr, .unused, .r_value);
_ = try appendToken(rp.c, .RParen, ")");
}
while_node.body = try transStmt(rp, &loop_scope, ZigClangForStmt_getBody(stmt), .unused, .r_value);
- if (block_scope != null) {
- try block_scope.?.block_node.statements.push(&while_node.base);
- block_scope.?.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
- return &block_scope.?.block_node.base;
+ if (block_scope) |*bs| {
+ try bs.statements.push(&while_node.base);
+ const node = bs.complete(rp.c);
+ return &node.base;
} else {
_ = try appendToken(rp.c, .Semicolon, ";");
return &while_node.base;
}
}
+fn getSwitchCaseCount(stmt: *const ZigClangSwitchStmt) usize {
+ const stmt = ZigClangSwitchStmt_getBody(stmt);
+ const comp = ZigClangStmtExpr_getSubStmt(stmt);
+ return ZigClangCompoundStmt_body_end(comp) - ZigClangCompoundStmt_body_begin(comp);
+}
+
fn transSwitch(
rp: RestorePoint,
scope: *Scope,
stmt: *const ZigClangSwitchStmt,
) TransError!*ast.Node {
- const switch_node = try transCreateNodeSwitch(rp.c);
+ const switch_tok = try appendToken(rp.c, .Keyword_switch, "switch");
+ _ = try appendToken(rp.c, .LParen, "(");
+
+ const cases_len = getSwitchCaseCount(ZigClangSwitchStmt_getBody(stmt));
+
+ var cond_scope = Scope.Condition{
+ .base = .{
+ .parent = scope,
+ .id = .Condition,
+ },
+ };
+ defer cond_scope.deinit();
+ const switch_expr = try transExpr(rp, &cond_scope.base, ZigClangSwitchStmt_getCond(stmt), .used, .r_value);
+ _ = try appendToken(rp.c, .RParen, ")");
+ _ = try appendToken(rp.c, .LBrace, "{");
+ // reserve +1 case in case there is no default case
+ const switch_node = try ast.Node.Switch.alloc(rp.c.arena, cases_len + 1);
+ switch_node.* = .{
+ .switch_token = switch_tok,
+ .expr = switch_expr,
+ .cases_len = cases_len + 1,
+ .rbrace = try appendToken(rp.c, .RBrace, "}"),
+ };
+
var switch_scope = Scope.Switch{
.base = .{
.id = .Switch,
.parent = scope,
},
- .cases = &switch_node.cases,
+ .cases = switch_node.cases(),
+ .case_index = 0,
.pending_block = undefined,
};
- var cond_scope = Scope{
- .parent = scope,
- .id = .Condition,
- };
- switch_node.expr = try transExpr(rp, &cond_scope, ZigClangSwitchStmt_getCond(stmt), .used, .r_value);
- _ = try appendToken(rp.c, .RParen, ")");
- _ = try appendToken(rp.c, .LBrace, "{");
- switch_node.rbrace = try appendToken(rp.c, .RBrace, "}");
-
- const block_scope = try Scope.Block.init(rp.c, &switch_scope.base, null);
// tmp block that all statements will go before being picked up by a case or default
- const block = try transCreateNodeBlock(rp.c, null);
- block_scope.setBlockNode(block);
+ var block_scope = try Scope.Block.init(rp.c, &switch_scope.base, null);
+ defer block_scope.deinit();
- const switch_block = try transCreateNodeBlock(rp.c, null);
- try switch_block.statements.push(&switch_node.base);
- switch_scope.pending_block = switch_block;
+ // Note that we do not defer a deinit here; the switch_scope.pending_block field
+ // has its own memory management. This resource is freed inside `transCase` and
+ // then the final pending_block is freed at the bottom of this function with
+ // pending_block.deinit().
+ switch_scope.pending_block = try Scope.Block.init(rp.c, scope, null);
+ try switch_scope.pending_block.statements.append(&switch_node.base);
- const last = try transStmt(rp, &block_scope.base, ZigClangSwitchStmt_getBody(stmt), .unused, .r_value);
+ _ = try transStmt(rp, &block_scope.base, ZigClangSwitchStmt_getBody(stmt), .unused, .r_value);
_ = try appendToken(rp.c, .Semicolon, ";");
// take all pending statements
- var it = last.cast(ast.Node.Block).?.statements.iterator(0);
- while (it.next()) |n| {
- try switch_scope.pending_block.statements.push(n.*);
- }
+ try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items);
+ // TODO delete the following commented out code
+ //const last_block_stmts = last.cast(ast.Node.Block).?.statements();
+ //switch_scope.pending_block.statements.ensureCapacity(
+ // switch_scope.pending_block.statements.items.len + last_block_stmts.len,
+ //);
+ //for (last_block_stmts) |n| {
+ // switch_scope.pending_block.statements.appendAssumeCapacity(n);
+ //}
switch_scope.pending_block.label = try appendIdentifier(rp.c, "__switch");
_ = try appendToken(rp.c, .Colon, ":");
@@ -2492,10 +2594,16 @@ fn transSwitch(
const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c));
else_prong.expr = &(try transCreateNodeBreak(rp.c, "__switch")).base;
_ = try appendToken(rp.c, .Comma, ",");
- try switch_node.cases.push(&else_prong.base);
+ switch_node.cases[switch_node.case_index] = &else_prong.base;
+ switch_node.case_index += 1;
}
- switch_scope.pending_block.rbrace = try appendToken(rp.c, .RBrace, "}");
- return &switch_scope.pending_block.base;
+ // We overallocated in case there was no default, so now we correct
+ // the number of cases in the AST node.
+ switch_node.cases_len = switch_scope.case_index;
+
+ const result_node = try switch_scope.pending_block.complete(rp.c);
+ switch_scope.pending_block.deinit();
+ return &result_node.base;
}
fn transCase(
@@ -2527,22 +2635,21 @@ fn transCase(
const switch_prong = try transCreateNodeSwitchCase(rp.c, expr);
switch_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base;
_ = try appendToken(rp.c, .Comma, ",");
- try switch_scope.cases.push(&switch_prong.base);
+ switch_scope.cases[switch_scope.case_index] = &switch_prong.base;
+ switch_scope.case_index += 1;
- const block = try transCreateNodeBlock(rp.c, null);
switch_scope.pending_block.label = try appendIdentifier(rp.c, label);
_ = try appendToken(rp.c, .Colon, ":");
- switch_scope.pending_block.rbrace = try appendToken(rp.c, .RBrace, "}");
- try block.statements.push(&switch_scope.pending_block.base);
// take all pending statements
- var it = block_scope.block_node.statements.iterator(0);
- while (it.next()) |n| {
- try switch_scope.pending_block.statements.push(n.*);
- }
- block_scope.block_node.statements.shrink(0);
+ try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items);
+ block_scope.statements.shrink(0);
+
+ const pending_node = try switch_scope.pending_block.complete(rp.c);
+ switch_scope.pending_block.deinit();
+ switch_scope.pending_block = try Scope.Block.init(rp.c, scope, null);
- switch_scope.pending_block = block;
+ try switch_scope.pending_block.statements.append(&pending_node.base);
return transStmt(rp, scope, ZigClangCaseStmt_getSubStmt(stmt), .unused, .r_value);
}
@@ -2561,22 +2668,21 @@ fn transDefault(
const else_prong = try transCreateNodeSwitchCase(rp.c, try transCreateNodeSwitchElse(rp.c));
else_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base;
_ = try appendToken(rp.c, .Comma, ",");
- try switch_scope.cases.push(&else_prong.base);
+ switch_scope.cases[switch_scope.case_index] = &else_prong.base;
+ switch_scope.case_index += 1;
- const block = try transCreateNodeBlock(rp.c, null);
switch_scope.pending_block.label = try appendIdentifier(rp.c, label);
_ = try appendToken(rp.c, .Colon, ":");
- switch_scope.pending_block.rbrace = try appendToken(rp.c, .RBrace, "}");
- try block.statements.push(&switch_scope.pending_block.base);
// take all pending statements
- var it = block_scope.block_node.statements.iterator(0);
- while (it.next()) |n| {
- try switch_scope.pending_block.statements.push(n.*);
- }
- block_scope.block_node.statements.shrink(0);
+ try switch_scope.pending_block.statements.appendSlice(block_scope.statements.items);
+ block_scope.statements.shrink(0);
+
+ const pending_node = try switch_scope.pending_block.complete(rp.c);
+ switch_scope.pending_block.deinit();
+ switch_scope.pending_block = try Scope.Block.init(rp.c, scope, null);
+ try switch_scope.pending_block.statements.append(&pending_node.base);
- switch_scope.pending_block = block;
return transStmt(rp, scope, ZigClangDefaultStmt_getSubStmt(stmt), .unused, .r_value);
}
@@ -2591,13 +2697,13 @@ fn transConstantExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangExpr,
// See comment in `transIntegerLiteral` for why this code is here.
// @as(T, x)
const expr_base = @ptrCast(*const ZigClangExpr, expr);
- const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
+ const as_node = try rp.c.createBuiltinCall("@as", 2);
const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base));
- try as_node.params.push(ty_node);
+ as_node.params()[0] = ty_node;
_ = try appendToken(rp.c, .Comma, ",");
const int_lit_node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&result.Val));
- try as_node.params.push(int_lit_node);
+ as_node.params()[1] = int_lit_node;
as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
@@ -2653,12 +2759,11 @@ fn transCharLiteral(
// See comment in `transIntegerLiteral` for why this code is here.
// @as(T, x)
const expr_base = @ptrCast(*const ZigClangExpr, stmt);
- const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
+ const as_node = try rp.c.createBuiltinCall("@as", 2);
const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base));
- try as_node.params.push(ty_node);
+ as_node.params()[0] = ty_node;
_ = try appendToken(rp.c, .Comma, ",");
-
- try as_node.params.push(int_lit_node);
+ as_node.params()[1] = int_lit_node;
as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return maybeSuppressResult(rp, scope, result_used, &as_node.base);
@@ -2671,26 +2776,24 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr,
}
const lparen = try appendToken(rp.c, .LParen, "(");
const block_scope = try Scope.Block.init(rp.c, scope, "blk");
- const block = try transCreateNodeBlock(rp.c, "blk");
- block_scope.setBlockNode(block);
+ defer block_scope.deinit();
var it = ZigClangCompoundStmt_body_begin(comp);
const end_it = ZigClangCompoundStmt_body_end(comp);
while (it != end_it - 1) : (it += 1) {
const result = try transStmt(rp, &block_scope.base, it[0], .unused, .r_value);
- if (result != &block.base)
- try block.statements.push(result);
+ try block_scope.statements.append(result);
}
const break_node = try transCreateNodeBreak(rp.c, "blk");
break_node.rhs = try transStmt(rp, &block_scope.base, it[0], .used, .r_value);
_ = try appendToken(rp.c, .Semicolon, ";");
- try block.statements.push(&break_node.base);
- block.rbrace = try appendToken(rp.c, .RBrace, "}");
+ try block_scope.statements.append(&break_node.base);
+ const block_node = try block_scope.complete(rp.c);
const rparen = try appendToken(rp.c, .RParen, ")");
const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
grouped_expr.* = .{
.lparen = lparen,
- .expr = &block.base,
+ .expr = &block_node.base,
.rparen = rparen,
};
return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
@@ -2746,12 +2849,12 @@ fn transArrayAccess(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangArrayS
const is_signed = cIsSignedInteger(qt);
if (is_longlong or is_signed) {
- const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
+ const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
// check if long long first so that signed long long doesn't just become unsigned long long
var typeid_node = if (is_longlong) try transCreateNodeIdentifier(rp.c, "usize") else try transQualTypeIntWidthOf(rp.c, qt, false);
- try cast_node.params.push(typeid_node);
+ cast_node.params()[0] = typeid_node;
_ = try appendToken(rp.c, .Comma, ",");
- try cast_node.params.push(try transExpr(rp, scope, subscr_expr, .used, .r_value));
+ cast_node.params()[1] = try transExpr(rp, scope, subscr_expr, .used, .r_value);
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
node.rtoken = try appendToken(rp.c, .RBrace, "]");
node.op.ArrayAccess = &cast_node.base;
@@ -2787,17 +2890,18 @@ fn transCallExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCallExpr,
break :blk try transCreateNodeUnwrapNull(rp.c, raw_fn_expr);
} else
raw_fn_expr;
- const node = try transCreateNodeFnCall(rp.c, fn_expr);
const num_args = ZigClangCallExpr_getNumArgs(stmt);
+ const node = try c.createCall(fn_expr, num_args);
+ const call_params = node.params();
+
const args = ZigClangCallExpr_getArgs(stmt);
var i: usize = 0;
while (i < num_args) : (i += 1) {
if (i != 0) {
_ = try appendToken(rp.c, .Comma, ",");
}
- const arg = try transExpr(rp, scope, args[i], .used, .r_value);
- try node.op.Call.params.push(arg);
+ call_params[i] = try transExpr(rp, scope, args[i], .used, .r_value);
}
node.rtoken = try appendToken(rp.c, .RParen, ")");
@@ -2856,8 +2960,8 @@ fn transUnaryExprOrTypeTraitExpr(
ZigClangUnaryExprOrTypeTraitExpr_getBeginLoc(stmt),
);
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@sizeOf");
- try builtin_node.params.push(type_node);
+ const builtin_node = try rp.c.createBuiltinCall("@sizeOf", 1);
+ builtin_node.params()[0] = type_node;
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return maybeSuppressResult(rp, scope, result_used, &builtin_node.base);
}
@@ -2966,8 +3070,8 @@ fn transCreatePreCrement(
// zig: _ref.* += 1;
// zig: break :blk _ref.*
// zig: })
- const block_scope = try Scope.Block.init(rp.c, scope, "blk");
- block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
+ var block_scope = try Scope.Block.init(rp.c, scope, "blk");
+ defer block_scope.deinit();
const ref = try block_scope.makeMangledName(rp.c, "ref");
const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
@@ -2976,7 +3080,7 @@ fn transCreatePreCrement(
rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value);
node.init_node = &rhs_node.base;
node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
- try block_scope.block_node.statements.push(&node.base);
+ try block_scope.statements.append(&node.base);
const lhs_node = try transCreateNodeIdentifier(rp.c, ref);
const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);
@@ -2985,18 +3089,18 @@ fn transCreatePreCrement(
const one = try transCreateNodeInt(rp.c, 1);
_ = try appendToken(rp.c, .Semicolon, ";");
const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false);
- try block_scope.block_node.statements.push(assign);
+ try block_scope.statements.append(assign);
const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
break_node.rhs = ref_node;
- try block_scope.block_node.statements.push(&break_node.base);
- block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
+ try block_scope.statements.push(&break_node.base);
+ const block_node = try block_scope.complete(rp.c);
// semicolon must immediately follow rbrace because it is the last token in a block
_ = try appendToken(rp.c, .Semicolon, ";");
const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
grouped_expr.* = .{
.lparen = try appendToken(rp.c, .LParen, "("),
- .expr = &block_scope.block_node.base,
+ .expr = &block_node.base,
.rparen = try appendToken(rp.c, .RParen, ")"),
};
return &grouped_expr.base;
@@ -3032,8 +3136,8 @@ fn transCreatePostCrement(
// zig: _ref.* += 1;
// zig: break :blk _tmp
// zig: })
- const block_scope = try Scope.Block.init(rp.c, scope, "blk");
- block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
+ var block_scope = try Scope.Block.init(rp.c, scope, "blk");
+ defer block_scope.deinit();
const ref = try block_scope.makeMangledName(rp.c, "ref");
const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
@@ -3042,7 +3146,7 @@ fn transCreatePostCrement(
rhs_node.rhs = try transExpr(rp, scope, op_expr, .used, .r_value);
node.init_node = &rhs_node.base;
node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
- try block_scope.block_node.statements.push(&node.base);
+ try block_scope.statements.push(&node.base);
const lhs_node = try transCreateNodeIdentifier(rp.c, ref);
const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);
@@ -3053,23 +3157,23 @@ fn transCreatePostCrement(
tmp_node.eq_token = try appendToken(rp.c, .Equal, "=");
tmp_node.init_node = ref_node;
tmp_node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
- try block_scope.block_node.statements.push(&tmp_node.base);
+ try block_scope.statements.push(&tmp_node.base);
const token = try appendToken(rp.c, op_tok_id, bytes);
const one = try transCreateNodeInt(rp.c, 1);
_ = try appendToken(rp.c, .Semicolon, ";");
const assign = try transCreateNodeInfixOp(rp, scope, ref_node, op, token, one, .used, false);
- try block_scope.block_node.statements.push(assign);
+ try block_scope.statements.push(assign);
const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp);
- try block_scope.block_node.statements.push(&break_node.base);
+ try block_scope.statements.push(&break_node.base);
_ = try appendToken(rp.c, .Semicolon, ";");
- block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
+ const block_node = try block_scope.complete(rp.c);
const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
grouped_expr.* = .{
.lparen = try appendToken(rp.c, .LParen, "("),
- .expr = &block_scope.block_node.base,
+ .expr = &block_node.base,
.rparen = try appendToken(rp.c, .RParen, ")"),
};
return &grouped_expr.base;
@@ -3134,11 +3238,11 @@ fn transCreateCompoundAssign(
const op_token = try appendToken(rp.c, .Equal, "=");
const op_node = try rp.c.arena.create(ast.Node.InfixOp);
const builtin = if (is_mod) "@rem" else "@divTrunc";
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, builtin);
+ const builtin_node = try rp.c.createBuiltinCall(builtin, 2);
const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
- try builtin_node.params.push(lhs_node);
+ builtin_node.params()[0] = lhs_node;
_ = try appendToken(rp.c, .Comma, ",");
- try builtin_node.params.push(try transExpr(rp, scope, rhs, .used, .r_value));
+ builtin_node.params()[1] = try transExpr(rp, scope, rhs, .used, .r_value);
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
op_node.* = .{
.op_token = op_token,
@@ -3158,11 +3262,11 @@ fn transCreateCompoundAssign(
try transExpr(rp, scope, rhs, .used, .r_value);
if (is_shift) {
- const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
+ const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc);
- try cast_node.params.push(rhs_type);
+ cast_node.params()[0] = rhs_type;
_ = try appendToken(rp.c, .Comma, ",");
- try cast_node.params.push(rhs_node);
+ cast_node.params()[1] = rhs_node;
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
rhs_node = &cast_node.base;
}
@@ -3177,8 +3281,8 @@ fn transCreateCompoundAssign(
// zig: _ref.* = _ref.* + rhs;
// zig: break :blk _ref.*
// zig: })
- const block_scope = try Scope.Block.init(rp.c, scope, "blk");
- block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
+ var block_scope = try Scope.Block.init(rp.c, scope, "blk");
+ defer block_scope.deinit();
const ref = try block_scope.makeMangledName(rp.c, "ref");
const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
@@ -3187,7 +3291,7 @@ fn transCreateCompoundAssign(
addr_node.rhs = try transExpr(rp, scope, lhs, .used, .l_value);
node.init_node = &addr_node.base;
node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
- try block_scope.block_node.statements.push(&node.base);
+ try block_scope.statements.append(&node.base);
const lhs_node = try transCreateNodeIdentifier(rp.c, ref);
const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);
@@ -3197,10 +3301,10 @@ fn transCreateCompoundAssign(
const op_token = try appendToken(rp.c, .Equal, "=");
const op_node = try rp.c.arena.create(ast.Node.InfixOp);
const builtin = if (is_mod) "@rem" else "@divTrunc";
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, builtin);
- try builtin_node.params.push(try transCreateNodePtrDeref(rp.c, lhs_node));
+ const builtin_node = try rp.c.createBuiltinCall(builtin, 2);
+ builtin_node.params()[0] = try transCreateNodePtrDeref(rp.c, lhs_node);
_ = try appendToken(rp.c, .Comma, ",");
- try builtin_node.params.push(try transExpr(rp, scope, rhs, .used, .r_value));
+ builtin_node.params()[1] = try transExpr(rp, scope, rhs, .used, .r_value);
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
_ = try appendToken(rp.c, .Semicolon, ";");
op_node.* = .{
@@ -3210,17 +3314,17 @@ fn transCreateCompoundAssign(
.rhs = &builtin_node.base,
};
_ = try appendToken(rp.c, .Semicolon, ";");
- try block_scope.block_node.statements.push(&op_node.base);
+ try block_scope.statements.append(&op_node.base);
} else {
const bin_token = try appendToken(rp.c, bin_tok_id, bin_bytes);
var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
if (is_shift) {
- const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
+ const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc);
- try cast_node.params.push(rhs_type);
+ cast_node.params()[0] = rhs_type;
_ = try appendToken(rp.c, .Comma, ",");
- try cast_node.params.push(rhs_node);
+ cast_node.params()[1] = rhs_node;
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
rhs_node = &cast_node.base;
}
@@ -3230,17 +3334,17 @@ fn transCreateCompoundAssign(
const eq_token = try appendToken(rp.c, .Equal, "=");
const assign = try transCreateNodeInfixOp(rp, scope, ref_node, .Assign, eq_token, rhs_bin, .used, false);
- try block_scope.block_node.statements.push(assign);
+ try block_scope.statements.append(assign);
}
const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
break_node.rhs = ref_node;
- try block_scope.block_node.statements.push(&break_node.base);
- block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
+ try block_scope.statements.append(&break_node.base);
+ const block_node = try block_scope.complete(rp.c);
const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
grouped_expr.* = .{
.lparen = try appendToken(rp.c, .LParen, "("),
- .expr = &block_scope.block_node.base,
+ .expr = &block_node.base,
.rparen = try appendToken(rp.c, .RParen, ")"),
};
return &grouped_expr.base;
@@ -3264,43 +3368,43 @@ fn transCPtrCast(
!ZigClangQualType_isVolatileQualified(child_type)))
{
// Casting away const or volatile requires us to use @intToPtr
- const inttoptr_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToPtr");
+ const inttoptr_node = try rp.c.createBuiltinCall("@intToPtr", 2);
const dst_type_node = try transType(rp, ty, loc);
- try inttoptr_node.params.push(dst_type_node);
+ inttoptr_node.params()[0] = dst_type_node;
_ = try appendToken(rp.c, .Comma, ",");
- const ptrtoint_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
- try ptrtoint_node.params.push(expr);
+ const ptrtoint_node = try rp.c.createBuiltinCall("@ptrToInt", 1);
+ ptrtoint_node.params()[0] = expr;
ptrtoint_node.rparen_token = try appendToken(rp.c, .RParen, ")");
- try inttoptr_node.params.push(&ptrtoint_node.base);
+ inttoptr_node.params()[1] = &ptrtoint_node.base;
inttoptr_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &inttoptr_node.base;
} else {
// Implicit downcasting from higher to lower alignment values is forbidden,
// use @alignCast to side-step this problem
- const ptrcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrCast");
+ const ptrcast_node = try rp.c.createBuiltinCall("@ptrCast", 2);
const dst_type_node = try transType(rp, ty, loc);
- try ptrcast_node.params.push(dst_type_node);
+ ptrcast_node.params()[0] = dst_type_node;
_ = try appendToken(rp.c, .Comma, ",");
if (ZigClangType_isVoidType(qualTypeCanon(child_type))) {
// void has 1-byte alignment, so @alignCast is not needed
- try ptrcast_node.params.push(expr);
+ ptrcast_node.params()[1] = expr;
} else if (typeIsOpaque(rp.c, qualTypeCanon(child_type), loc)) {
// For opaque types a ptrCast is enough
- try ptrcast_node.params.push(expr);
+ ptrcast_node.params()[1] = expr;
} else {
- const aligncast_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignCast");
- const alignof_node = try transCreateNodeBuiltinFnCall(rp.c, "@alignOf");
+ const aligncast_node = try rp.c.createBuiltinCall("@alignCast", 2);
+ const alignof_node = try rp.c.createBuiltinCall("@alignOf", 1);
const child_type_node = try transQualType(rp, child_type, loc);
- try alignof_node.params.push(child_type_node);
+ alignof_node.params()[0] = child_type_node;
alignof_node.rparen_token = try appendToken(rp.c, .RParen, ")");
- try aligncast_node.params.push(&alignof_node.base);
+ aligncast_node.params()[0] = &alignof_node.base;
_ = try appendToken(rp.c, .Comma, ",");
- try aligncast_node.params.push(expr);
+ aligncast_node.params()[1] = expr;
aligncast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
- try ptrcast_node.params.push(&aligncast_node.base);
+ ptrcast_node.params()[1] = &aligncast_node.base;
}
ptrcast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
@@ -3343,27 +3447,30 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const
// })
const lparen = try appendToken(rp.c, .LParen, "(");
- const block_scope = try Scope.Block.init(rp.c, scope, "blk");
- block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
+ var block_scope = try Scope.Block.init(rp.c, scope, "blk");
+ defer block_scope.deinit();
const mangled_name = try block_scope.makeMangledName(rp.c, "cond_temp");
const tmp_var = try transCreateNodeVarDecl(rp.c, false, true, mangled_name);
tmp_var.eq_token = try appendToken(rp.c, .Equal, "=");
tmp_var.init_node = try transExpr(rp, &block_scope.base, cond_expr, .used, .r_value);
tmp_var.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
- try block_scope.block_node.statements.push(&tmp_var.base);
+ try block_scope.statements.append(&tmp_var.base);
const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
const if_node = try transCreateNodeIf(rp.c);
- var cond_scope = Scope{
- .parent = &block_scope.base,
- .id = .Condition,
+ var cond_scope = Scope.Condition{
+ .base = .{
+ .parent = &block_scope.base,
+ .id = .Condition,
+ },
};
+ defer cond_scope.deinit();
const tmp_var_node = try transCreateNodeIdentifier(rp.c, mangled_name);
const ty = ZigClangQualType_getTypePtr(getExprQualType(rp.c, cond_expr));
- const cond_node = try finishBoolExpr(rp, &block_scope.base, ZigClangExpr_getBeginLoc(cond_expr), ty, tmp_var_node, used);
+ const cond_node = try finishBoolExpr(rp, &cond_scope.base, ZigClangExpr_getBeginLoc(cond_expr), ty, tmp_var_node, used);
if_node.condition = cond_node;
_ = try appendToken(rp.c, .RParen, ")");
@@ -3374,13 +3481,13 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const
break_node.rhs = &if_node.base;
_ = try appendToken(rp.c, .Semicolon, ";");
- try block_scope.block_node.statements.push(&break_node.base);
- block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
+ try block_scope.statements.append(&break_node.base);
+ const block_node = block_scope.complete(rp.c);
const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
grouped_expr.* = .{
.lparen = lparen,
- .expr = &block_scope.block_node.base,
+ .expr = &block_node.base,
.rparen = try appendToken(rp.c, .RParen, ")"),
};
return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
@@ -3390,17 +3497,20 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla
const grouped = scope.id == .Condition;
const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined;
const if_node = try transCreateNodeIf(rp.c);
- var cond_scope = Scope{
- .parent = scope,
- .id = .Condition,
+ var cond_scope = Scope.Condition{
+ .base = .{
+ .parent = scope,
+ .id = .Condition,
+ },
};
+ defer cond_scope.deinit();
const casted_stmt = @ptrCast(*const ZigClangAbstractConditionalOperator, stmt);
const cond_expr = ZigClangAbstractConditionalOperator_getCond(casted_stmt);
const true_expr = ZigClangAbstractConditionalOperator_getTrueExpr(casted_stmt);
const false_expr = ZigClangAbstractConditionalOperator_getFalseExpr(casted_stmt);
- if_node.condition = try transBoolExpr(rp, &cond_scope, cond_expr, .used, .r_value, false);
+ if_node.condition = try transBoolExpr(rp, &cond_scope.base, cond_expr, .used, .r_value, false);
_ = try appendToken(rp.c, .RParen, ")");
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
// Symbol "Log2Int"
// Symbol <zig_type_node> (var from above)
- const import_fn_call = try transCreateNodeBuiltinFnCall(rp.c, "@import");
+ const import_fn_call = try rp.c.createBuiltinCall("@import", 1);
const std_token = try appendToken(rp.c, .StringLiteral, "\"std\"");
const std_node = try rp.c.arena.create(ast.Node.StringLiteral);
std_node.* = .{
.token = std_token,
};
- try import_fn_call.params.push(&std_node.base);
+ import_fn_call.params()[0] = &std_node.base;
import_fn_call.rparen_token = try appendToken(rp.c, .RParen, ")");
const inner_field_access = try transCreateNodeFieldAccess(rp.c, &import_fn_call.base, "math");
const outer_field_access = try transCreateNodeFieldAccess(rp.c, inner_field_access, "Log2Int");
- const log2int_fn_call = try transCreateNodeFnCall(rp.c, outer_field_access);
- try @fieldParentPtr(ast.Node.SuffixOp, "base", &log2int_fn_call.base).op.Call.params.push(zig_type_node);
+ const log2int_fn_call = try rp.c.createCall(outer_field_access, 1);
+ log2int_fn_call.params()[0] = zig_type_node;
log2int_fn_call.rtoken = try appendToken(rp.c, .RParen, ")");
return &log2int_fn_call.base;
@@ -3757,8 +3867,8 @@ fn transCreateNodeAssign(
const eq_token = try appendToken(rp.c, .Equal, "=");
var rhs_node = try transExprCoercing(rp, scope, rhs, .used, .r_value);
if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
- try builtin_node.params.push(rhs_node);
+ const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
+ builtin_node.params()[0] = rhs_node;
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
rhs_node = &builtin_node.base;
}
@@ -3774,22 +3884,23 @@ fn transCreateNodeAssign(
// zig: lhs = _tmp;
// zig: break :blk _tmp
// zig: })
- const block_scope = try Scope.Block.init(rp.c, scope, "blk");
- block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
+ var block_scope = try Scope.Block.init(rp.c, scope, "blk");
+ defer block_scope.deinit();
+
const tmp = try block_scope.makeMangledName(rp.c, "tmp");
const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);
node.eq_token = try appendToken(rp.c, .Equal, "=");
var rhs_node = try transExpr(rp, &block_scope.base, rhs, .used, .r_value);
if (!exprIsBooleanType(lhs) and isBoolRes(rhs_node)) {
- const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
- try builtin_node.params.push(rhs_node);
+ const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
+ builtin_node.params()[0] = rhs_node;
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
rhs_node = &builtin_node.base;
}
node.init_node = rhs_node;
node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
- try block_scope.block_node.statements.push(&node.base);
+ try block_scope.statements.append(&node.base);
const lhs_node = try transExpr(rp, &block_scope.base, lhs, .used, .l_value);
const eq_token = try appendToken(rp.c, .Equal, "=");
@@ -3797,44 +3908,16 @@ fn transCreateNodeAssign(
_ = try appendToken(rp.c, .Semicolon, ";");
const assign = try transCreateNodeInfixOp(rp, &block_scope.base, lhs_node, .Assign, eq_token, ident, .used, false);
- try block_scope.block_node.statements.push(assign);
+ try block_scope.statements.append(assign);
const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp);
_ = try appendToken(rp.c, .Semicolon, ";");
- try block_scope.block_node.statements.push(&break_node.base);
- block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
+ try block_scope.statements.append(&break_node.base);
+ const block_node = try block_scope.complete(rp.c);
// semicolon must immediately follow rbrace because it is the last token in a block
_ = try appendToken(rp.c, .Semicolon, ";");
- return &block_scope.block_node.base;
-}
-
-fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.BuiltinCall {
- const builtin_token = try appendToken(c, .Builtin, name);
- _ = try appendToken(c, .LParen, "(");
- const node = try c.arena.create(ast.Node.BuiltinCall);
- node.* = .{
- .builtin_token = builtin_token,
- .params = ast.Node.BuiltinCall.ParamList{},
- .rparen_token = undefined, // set after appending args
- };
- return node;
-}
-
-fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp {
- _ = try appendToken(c, .LParen, "(");
- const node = try c.arena.create(ast.Node.SuffixOp);
- node.* = .{
- .lhs = fn_expr,
- .op = .{
- .Call = .{
- .params = ast.Node.SuffixOp.Op.Call.ParamList{},
- .async_token = null,
- },
- },
- .rtoken = undefined, // set after appending args
- };
- return node;
+ return &block_node.base;
}
fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []const u8) !*ast.Node {
@@ -4083,8 +4166,8 @@ fn transCreateNodeFloat(c: *Context, int: var) !*ast.Node {
}
fn transCreateNodeOpaqueType(c: *Context) !*ast.Node {
- const call_node = try transCreateNodeBuiltinFnCall(c, "@Type");
- try call_node.params.push(try transCreateNodeEnumLiteral(c, "Opaque"));
+ const call_node = try c.createBuiltinCall("@Type", 1);
+ call_node.params()[0] = try transCreateNodeEnumLiteral(c, "Opaque");
call_node.rparen_token = try appendToken(c, .RParen, ")");
return &call_node.base;
}
@@ -4139,26 +4222,33 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
};
mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items);
- const block = try transCreateNodeBlock(c, null);
- var block_statements_it = &block.statements.first;
+ const block_lbrace = try appendToken(c, .LBrace, "{");
const return_expr = try transCreateNodeReturnExpr(c);
const unwrap_expr = try transCreateNodeUnwrapNull(c, ref.cast(ast.Node.VarDecl).?.init_node.?);
- const call_expr = try transCreateNodeFnCall(c, unwrap_expr);
- var call_params_it = &call_expr.op.Call.params.first;
+
+ const call_expr = try c.createCall(unwrap_expr, fn_params.items.len);
+ const call_params = call_expr.params();
for (fn_params.items) |param, i| {
if (i != 0) {
_ = try appendToken(c, .Comma, ",");
}
- call_params_it = try c.llpush(*ast.Node, call_params_it, try transCreateNodeIdentifier(c, tokenSlice(c, param.name_token.?)),);
+ call_params[i] = try transCreateNodeIdentifier(c, tokenSlice(c, param.name_token.?));
}
call_expr.rtoken = try appendToken(c, .RParen, ")");
+
return_expr.rhs = &call_expr.base;
_ = try appendToken(c, .Semicolon, ";");
- block.rbrace = try appendToken(c, .RBrace, "}");
- block_statements_it = try c.llpush(*ast.Node, block_statements_it, &return_expr.base);
+ const block = try ast.Node.Block.alloc(c.arena, 1);
+ block.* = .{
+ .label = null,
+ .lbrace = block_lbrace,
+ .statements_len = 1,
+ .rbrace = try appendToken(c, .RBrace, "}"),
+ };
+ block.statements()[0] = &return_expr.base;
fn_proto.body_node = &block.base;
return &fn_proto.base;
}
@@ -4216,22 +4306,6 @@ fn transCreateNodeElse(c: *Context) !*ast.Node.Else {
return node;
}
-fn transCreateNodeBlock(c: *Context, label: ?[]const u8) !*ast.Node.Block {
- const label_node = if (label) |l| blk: {
- const ll = try appendIdentifier(c, l);
- _ = try appendToken(c, .Colon, ":");
- break :blk ll;
- } else null;
- const block_node = try c.arena.create(ast.Node.Block);
- block_node.* = .{
- .label = label_node,
- .lbrace = try appendToken(c, .LBrace, "{"),
- .statements = ast.Node.Block.StatementList{},
- .rbrace = undefined,
- };
- return block_node;
-}
-
fn transCreateNodeBreak(c: *Context, label: ?[]const u8) !*ast.Node.ControlFlowExpression {
const ltoken = try appendToken(c, .Keyword_break, "break");
const label_node = if (label) |l| blk: {
@@ -4302,20 +4376,6 @@ fn transCreateNodeContinue(c: *Context) !*ast.Node {
return &node.base;
}
-fn transCreateNodeSwitch(c: *Context) !*ast.Node.Switch {
- const switch_tok = try appendToken(c, .Keyword_switch, "switch");
- _ = try appendToken(c, .LParen, "(");
-
- const node = try c.arena.create(ast.Node.Switch);
- node.* = .{
- .switch_token = switch_tok,
- .expr = undefined,
- .cases = ast.Node.Switch.CaseList{},
- .rbrace = undefined,
- };
- return node;
-}
-
fn transCreateNodeSwitchCase(c: *Context, lhs: *ast.Node) !*ast.Node.SwitchCase {
const arrow_tok = try appendToken(c, .EqualAngleBracketRight, "=>");
@@ -4356,12 +4416,12 @@ fn transCreateNodeShiftOp(
const lhs = try transExpr(rp, scope, lhs_expr, .used, .l_value);
const op_token = try appendToken(rp.c, op_tok_id, bytes);
- const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
+ const cast_node = try rp.c.createBuiltinCall("@intCast", 2);
const rhs_type = try qualTypeToLog2IntRef(rp, ZigClangBinaryOperator_getType(stmt), rhs_location);
- try cast_node.params.push(rhs_type);
+ cast_node.params()[0] = rhs_type;
_ = try appendToken(rp.c, .Comma, ",");
const rhs = try transExprCoercing(rp, scope, rhs_expr, .used, .r_value);
- try cast_node.params.push(rhs);
+ cast_node.params()[1] = rhs;
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
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
.token = msg_tok,
};
- const call_node = try c.arena.create(ast.Node.BuiltinCall);
+ const call_node = try ast.Node.BuiltinCall.alloc(c.arena, 1);
call_node.* = .{
.builtin_token = builtin_tok,
- .params = ast.Node.BuiltinCall.ParamList{},
+ .params_len = 1,
.rparen_token = rparen_tok,
};
- var call_params_it = &call_node.params.first;
- call_params_it = try c.llpush(*ast.Node, call_params_it, &msg_node.base);
+ call_node.params()[0] = &msg_node.base;
const var_decl_node = try c.arena.create(ast.Node.VarDecl);
var_decl_node.* = .{
@@ -4868,23 +4927,20 @@ fn appendToken(c: *Context, token_id: Token.Id, bytes: []const u8) !ast.TokenInd
fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8, args: var) !ast.TokenIndex {
assert(token_id != .Invalid);
- const start_index = c.source_buffer.items.len;
- errdefer c.source_buffer.shrink(start_index);
- try c.source_buffer.outStream().print(format, args);
- const end_index = c.source_buffer.items.len;
- const token_index = c.tokens.items.len;
- const new_token = try c.tokens.addOne(c.gpa);
- errdefer c.tokens.shrink(c.gpa, token_index);
+ try c.token_ids.ensureCapacity(c.gpa, c.token_ids.items.len + 1);
+ try c.token_locs.ensureCapacity(c.gpa, c.token_locs.items.len + 1);
- new_token.* = .{
- .id = token_id,
+ const start_index = c.source_buffer.items.len;
+ try c.source_buffer.outStream().print(format ++ " ", args);
+
+ c.token_ids.appendAssumeCapacity(token_id);
+ c.token_locs.appendAssumeCapacity(.{
.start = start_index,
- .end = end_index,
- };
- try c.source_buffer.append(' ');
+ .end = c.source_buffer.items.len - 1, // back up before the space
+ });
- return token_index;
+ return c.token_ids.items.len - 1;
}
// TODO hook up with codegen
@@ -5072,7 +5128,8 @@ fn transMacroDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, n
}
fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8, name: []const u8, source_loc: ZigClangSourceLocation) ParseError!void {
- const block_scope = try Scope.Block.init(c, &c.global_scope.base, null);
+ var block_scope = try Scope.Block.init(c, &c.global_scope.base, null);
+ defer block_scope.deinit();
const scope = &block_scope.base;
const pub_tok = try appendToken(c, .Keyword_pub, "pub");
@@ -5142,9 +5199,7 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
_ = try appendToken(c, .RParen, ")");
- const type_of = try transCreateNodeBuiltinFnCall(c, "@TypeOf");
- type_of.rparen_token = try appendToken(c, .RParen, ")");
- var type_of_params = c.llpusher(&type_of.params);
+ const type_of = try c.createBuiltinCall("@TypeOf", 1);
const fn_proto = try ast.Node.FnProto.alloc(c.arena, fn_params.items.len);
fn_proto.* = .{
@@ -5164,9 +5219,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
};
mem.copy(ast.Node.FnProto.ParamDecl, fn_proto.params(), fn_params.items);
- const block = try transCreateNodeBlock(c, null);
- var block_statements = c.llpusher(&block.statements);
-
const return_expr = try transCreateNodeReturnExpr(c);
const expr = try parseCExpr(c, it, source, source_loc, scope);
const last = it.next().?;
@@ -5186,12 +5238,13 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
const br = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", blk_last);
break :blk br.rhs.?;
};
- try type_of_params.push(type_of_arg);
+ type_of.params()[0] = type_of_arg;
+ type_of.rparen_token = try appendToken(c, .RParen, ")");
return_expr.rhs = expr;
- block.rbrace = try appendToken(c, .RBrace, "}");
- try block_statements.push(&return_expr.base);
- fn_proto.body_node = &block.base;
+ try block_scope.statements.append(&return_expr.base);
+ const block_node = try block_scope.complete(c);
+ fn_proto.body_node = &block_node.base;
_ = try c.global_scope.macro_table.put(name, &fn_proto.base);
}
@@ -5223,8 +5276,8 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_
},
.Comma => {
_ = try appendToken(c, .Semicolon, ";");
- const block_scope = try Scope.Block.init(c, scope, "blk");
- block_scope.setBlockNode(try transCreateNodeBlock(c, block_scope.label));
+ var block_scope = try Scope.Block.init(c, scope, "blk");
+ defer block_scope.deinit();
var last = node;
while (true) {
@@ -5238,7 +5291,7 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_
.op = .Assign,
.rhs = last,
};
- try block_scope.block_node.statements.push(&op_node.base);
+ try block_scope.statements.append(&op_node.base);
last = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
_ = try appendToken(c, .Semicolon, ";");
@@ -5250,9 +5303,9 @@ fn parseCExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8, source_
const break_node = try transCreateNodeBreak(c, block_scope.label);
break_node.rhs = last;
- try block_scope.block_node.statements.push(&break_node.base);
- block_scope.block_node.rbrace = try appendToken(c, .RBrace, "}");
- return &block_scope.block_node.base;
+ try block_scope.statements.append(&break_node.base);
+ const block_node = try block_scope.complete(c);
+ return &block_node.base;
},
else => {
_ = it.prev();
@@ -5283,15 +5336,15 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl
return transCreateNodeInt(c, lit_bytes);
}
- const cast_node = try transCreateNodeBuiltinFnCall(c, "@as");
- try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.id.IntegerLiteral) {
+ const cast_node = try c.createBuiltinCall("@as", 2);
+ cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (tok.id.IntegerLiteral) {
.U => "c_uint",
.L => "c_long",
.LU => "c_ulong",
.LL => "c_longlong",
.LLU => "c_ulonglong",
else => unreachable,
- }));
+ });
lit_bytes = lit_bytes[0 .. lit_bytes.len - switch (tok.id.IntegerLiteral) {
.U, .L => @as(u8, 1),
.LU, .LL => 2,
@@ -5299,7 +5352,7 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl
else => unreachable,
}];
_ = try appendToken(c, .Comma, ",");
- try cast_node.params.push(try transCreateNodeInt(c, lit_bytes));
+ cast_node.params()[1] = try transCreateNodeInt(c, lit_bytes);
cast_node.rparen_token = try appendToken(c, .RParen, ")");
return &cast_node.base;
} else if (tok.id == .FloatLiteral) {
@@ -5308,14 +5361,14 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl
if (tok.id.FloatLiteral == .None) {
return transCreateNodeFloat(c, lit_bytes);
}
- const cast_node = try transCreateNodeBuiltinFnCall(c, "@as");
- try cast_node.params.push(try transCreateNodeIdentifier(c, switch (tok.id.FloatLiteral) {
+ const cast_node = try c.createBuiltinCall("@as", 2);
+ cast_node.params()[0] = try transCreateNodeIdentifier(c, switch (tok.id.FloatLiteral) {
.F => "f32",
.L => "c_longdouble",
else => unreachable,
- }));
+ });
_ = try appendToken(c, .Comma, ",");
- try cast_node.params.push(try transCreateNodeFloat(c, lit_bytes[0 .. lit_bytes.len - 1]));
+ cast_node.params()[1] = try transCreateNodeFloat(c, lit_bytes[0 .. lit_bytes.len - 1]);
cast_node.rparen_token = try appendToken(c, .RParen, ")");
return &cast_node.base;
} else unreachable;
@@ -5585,8 +5638,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
//else
// @as(dest, x) )
const if_node = try transCreateNodeIf(c);
- const type_info_node = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
- try type_info_node.params.push(inner_node);
+ const type_info_node = try rp.c.createBuiltinCall("@typeInfo", 1);
+ type_info_node.params()[0] = inner_node;
type_info_node.rparen_token = try appendToken(c, .LParen, ")");
const cmp_node = try c.arena.create(ast.Node.InfixOp);
cmp_node.* = .{
@@ -5598,18 +5651,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
if_node.condition = &cmp_node.base;
_ = try appendToken(c, .RParen, ")");
- const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr");
- try int_to_ptr.params.push(inner_node);
- try int_to_ptr.params.push(node_to_cast);
+ const int_to_ptr = try c.createBuiltinCall("@intToPtr", 2);
+ int_to_ptr.params()[0] = inner_node;
+ int_to_ptr.params()[1] = node_to_cast;
int_to_ptr.rparen_token = try appendToken(c, .RParen, ")");
if_node.body = &int_to_ptr.base;
const else_node = try transCreateNodeElse(c);
if_node.@"else" = else_node;
- const as_node = try transCreateNodeBuiltinFnCall(c, "@as");
- try as_node.params.push(inner_node);
- try as_node.params.push(node_to_cast);
+ const as_node = try c.createBuiltinCall("@as", 2);
+ as_node.params()[0] = inner_node;
+ as_node.params()[1] = node_to_cast;
as_node.rparen_token = try appendToken(c, .RParen, ")");
else_node.body = &as_node.base;
@@ -5630,10 +5683,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
// @as(dest, x) )
const if_1 = try transCreateNodeIf(c);
- const type_info_1 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
- const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");
- try type_info_1.params.push(&type_of_1.base);
- try type_of_1.params.push(node_to_cast);
+ const type_info_1 = try c.createBuiltinCall("@typeInfo", 1);
+ const type_of_1 = try c.createBuiltinCall("@TypeOf", 1);
+ type_info_1.params()[0] = &type_of_1.base;
+ type_of_1.params()[0] = node_to_cast;
type_of_1.rparen_token = try appendToken(c, .RParen, ")");
type_info_1.rparen_token = try appendToken(c, .RParen, ")");
@@ -5657,20 +5710,20 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
.rhs = child_ident,
};
- const align_of = try transCreateNodeBuiltinFnCall(c, "@alignOf");
- try align_of.params.push(&inner_node_child.base);
+ const align_of = try rp.c.createBuiltinCall("@alignOf", 1);
+ align_of.params()[0] = &inner_node_child.base;
align_of.rparen_token = try appendToken(c, .RParen, ")");
// hack to get zig fmt to render a comma in builtin calls
_ = try appendToken(c, .Comma, ",");
- const align_cast = try transCreateNodeBuiltinFnCall(c, "@alignCast");
- try align_cast.params.push(&align_of.base);
- try align_cast.params.push(node_to_cast);
+ const align_cast = try c.createBuiltinCall("@alignCast", 2);
+ align_cast.params()[0] = &align_of.base;
+ align_cast.params()[1] = node_to_cast;
align_cast.rparen_token = try appendToken(c, .RParen, ")");
- const ptr_cast = try transCreateNodeBuiltinFnCall(c, "@ptrCast");
- try ptr_cast.params.push(inner_node);
- try ptr_cast.params.push(&align_cast.base);
+ const ptr_cast = try c.createBuiltinCall("@ptrCast", 2);
+ ptr_cast.params()[0] = inner_node;
+ ptr_cast.params()[1] = &align_cast.base;
ptr_cast.rparen_token = try appendToken(c, .RParen, ")");
if_1.body = &ptr_cast.base;
@@ -5678,10 +5731,10 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
if_1.@"else" = else_1;
const if_2 = try transCreateNodeIf(c);
- const type_info_2 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
- const type_of_2 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");
- try type_info_2.params.push(&type_of_2.base);
- try type_of_2.params.push(node_to_cast);
+ const type_info_2 = try c.createBuiltinCall("@typeInfo", 1);
+ const type_of_2 = try c.createBuiltinCall("@TypeOf", 1);
+ type_info_2.params()[0] = &type_of_2.base;
+ type_of_2.params()[0] = node_to_cast;
type_of_2.rparen_token = try appendToken(c, .RParen, ")");
type_info_2.rparen_token = try appendToken(c, .RParen, ")");
@@ -5700,8 +5753,8 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
.op = .BoolAnd,
.rhs = undefined,
};
- const type_info_3 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
- try type_info_3.params.push(inner_node);
+ const type_info_3 = try c.createBuiltinCall("@typeInfo", 1);
+ type_info_3.params()[0] = inner_node;
type_info_3.rparen_token = try appendToken(c, .LParen, ")");
const cmp_3 = try c.arena.create(ast.Node.InfixOp);
cmp_3.* = .{
@@ -5715,18 +5768,18 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
else_1.body = &if_2.base;
_ = try appendToken(c, .RParen, ")");
- const int_to_ptr = try transCreateNodeBuiltinFnCall(c, "@intToPtr");
- try int_to_ptr.params.push(inner_node);
- try int_to_ptr.params.push(node_to_cast);
+ const int_to_ptr = try c.createBuiltinCall("@intToPtr", 2);
+ int_to_ptr.params()[0] = inner_node;
+ int_to_ptr.params()[1] = node_to_cast;
int_to_ptr.rparen_token = try appendToken(c, .RParen, ")");
if_2.body = &int_to_ptr.base;
const else_2 = try transCreateNodeElse(c);
if_2.@"else" = else_2;
- const as = try transCreateNodeBuiltinFnCall(c, "@as");
- try as.params.push(inner_node);
- try as.params.push(node_to_cast);
+ const as = try c.createBuiltinCall("@as", 2);
+ as.params()[0] = inner_node;
+ as.params()[1] = node_to_cast;
as.rparen_token = try appendToken(c, .RParen, ")");
else_2.body = &as.base;
@@ -5765,8 +5818,8 @@ fn macroBoolToInt(c: *Context, node: *ast.Node) !*ast.Node {
return &group_node.base;
}
- const builtin_node = try transCreateNodeBuiltinFnCall(c, "@boolToInt");
- try builtin_node.params.push(node);
+ const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
+ builtin_node.params()[0] = node;
builtin_node.rparen_token = try appendToken(c, .RParen, ")");
return &builtin_node.base;
}
@@ -5944,10 +5997,12 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
continue;
},
.LParen => {
- const call_node = try transCreateNodeFnCall(c, node);
+ _ = try appendToken(c, .LParen, "(");
+ var call_params = std.ArrayList(*ast.Node).init(c.gpa);
+ defer call_params.deinit();
while (true) {
const arg = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- try call_node.op.Call.params.push(arg);
+ try call_params.append(arg);
const next = it.next().?;
if (next.id == .Comma)
_ = try appendToken(c, .Comma, ",")
@@ -5965,7 +6020,14 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
return error.ParseError;
}
}
- call_node.rtoken = try appendToken(c, .RParen, ")");
+ const call_node = try ast.Node.Call.alloc(c.arena, call_params.items.len);
+ call_node.* = .{
+ .lhs = node,
+ .params_len = call_params.items.len,
+ .async_token = null,
+ .rtoken = try appendToken(c, .RParen, ")"),
+ };
+ mem.copy(*ast.Node, call_node.params(), call_params.items);
node = &call_node.base;
continue;
},