Commit 8c10178a1e
Changed files (4)
lib
std
src-self-hosted
lib/std/zig/render.zig
@@ -915,8 +915,7 @@ fn renderExpression(
if (maybe_row_size) |row_size| {
// A place to store the width of each expression and its column's maximum
- const exprs_len = countLen(exprs.first);
- var widths = try allocator.alloc(usize, exprs_len + row_size);
+ var widths = try allocator.alloc(usize, exprs.len() + row_size);
defer allocator.free(widths);
mem.set(usize, widths, 0);
@@ -1391,7 +1390,7 @@ fn renderExpression(
{
break :blk false;
}
- const last_node = findLast(builtin_call.params.first.?).data;
+ const last_node = builtin_call.params.first.?.findLast().data;
const maybe_comma = tree.nextToken(last_node.lastToken());
break :blk tree.tokens[maybe_comma].id == .Comma;
};
@@ -1615,7 +1614,7 @@ fn renderExpression(
assert(switch_case.items.first != null);
const src_has_trailing_comma = blk: {
- const last_node = findLast(switch_case.items.first.?).data;
+ const last_node = switch_case.items.first.?.findLast().data;
const maybe_comma = tree.nextToken(last_node.lastToken());
break :blk tree.tokens[maybe_comma].id == .Comma;
};
@@ -2510,19 +2509,3 @@ fn copyFixingWhitespace(stream: var, slice: []const u8) @TypeOf(stream).Error!vo
else => try stream.writeByte(byte),
};
}
-
-fn countLen(node: ?*std.SinglyLinkedList(*ast.Node).Node) usize {
- var count: usize = 0;
- var it = node;
- while (it) |n| : (it = n.next) {
- count += 1;
- }
- return count;
-}
-
-fn findLast(node: *std.SinglyLinkedList(*ast.Node).Node) *std.SinglyLinkedList(*ast.Node).Node {
- var it = node;
- while (true) {
- it = it.next orelse return it;
- }
-}
lib/std/linked_list.zig
@@ -49,6 +49,26 @@ pub fn SinglyLinkedList(comptime T: type) type {
node.next = next_node.next;
return next_node;
}
+
+ /// Iterate over the singly-linked list from this node, until the final node is found.
+ /// This operation is O(N).
+ pub fn findLast(node: *Node) *Node {
+ var it = node;
+ while (true) {
+ it = it.next orelse return it;
+ }
+ }
+
+ /// Iterate over each next node, returning the count of all nodes except the starting one.
+ /// This operation is O(N).
+ pub fn countChildren(node: *const Node) usize {
+ var count: usize = 0;
+ var it: ?*const Node = node;
+ while (it) |n| : (it = n.next) {
+ count += 1;
+ }
+ return count;
+ }
};
first: ?*Node = null,
@@ -87,6 +107,16 @@ pub fn SinglyLinkedList(comptime T: type) type {
list.first = first.next;
return first;
}
+
+ /// Iterate over all nodes, returning the count.
+ /// This operation is O(N).
+ pub fn len(list: Self) usize {
+ if (list.first) |n| {
+ return 1 + n.countChildren();
+ } else {
+ return 0;
+ }
+ }
};
}
src-self-hosted/main.zig
@@ -600,8 +600,7 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void {
};
defer tree.deinit();
- var error_it = tree.errors.iterator(0);
- while (error_it.next()) |parse_error| {
+ for (tree.errors) |parse_error| {
try printErrMsgToFile(gpa, parse_error, tree, "<stdin>", stderr_file, color);
}
if (tree.errors.len != 0) {
@@ -701,8 +700,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
};
defer tree.deinit();
- var error_it = tree.errors.iterator(0);
- while (error_it.next()) |parse_error| {
+ for (tree.errors) |parse_error| {
try printErrMsgToFile(fmt.gpa, parse_error, tree, file_path, std.io.getStdErr(), fmt.color);
}
if (tree.errors.len != 0) {
@@ -730,7 +728,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
fn printErrMsgToFile(
gpa: *mem.Allocator,
- parse_error: *const ast.Error,
+ parse_error: ast.Error,
tree: *ast.Tree,
path: []const u8,
file: fs.File,
@@ -745,15 +743,15 @@ fn printErrMsgToFile(
const span_first = lok_token;
const span_last = lok_token;
- const first_token = tree.tokens.at(span_first);
- const last_token = tree.tokens.at(span_last);
+ const first_token = tree.tokens[span_first];
+ const last_token = tree.tokens[span_last];
const start_loc = tree.tokenLocationPtr(0, first_token);
const end_loc = tree.tokenLocationPtr(first_token.end, last_token);
var text_buf = std.ArrayList(u8).init(gpa);
defer text_buf.deinit();
const out_stream = text_buf.outStream();
- try parse_error.render(&tree.tokens, out_stream);
+ try parse_error.render(tree.tokens, out_stream);
const text = text_buf.span();
const stream = file.outStream();
src-self-hosted/translate_c.zig
@@ -37,10 +37,10 @@ fn addrEql(a: usize, b: usize) bool {
}
const SymbolTable = std.StringHashMap(*ast.Node);
-const AliasList = std.SegmentedList(struct {
+const AliasList = std.ArrayList(struct {
alias: []const u8,
name: []const u8,
-}, 4);
+});
const Scope = struct {
id: Id,
@@ -64,40 +64,50 @@ const Scope = struct {
const Block = struct {
base: Scope,
block_node: *ast.Node.Block,
+ statements_it: *?*std.SinglyLinkedList(*ast.Node),
variables: AliasList,
label: ?[]const u8,
mangle_count: u32 = 0,
/// 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.a().create(Block);
+ const block = try c.arena.create(Block);
block.* = .{
.base = .{
.id = .Block,
.parent = parent,
},
.block_node = undefined,
- .variables = AliasList.init(c.a()),
+ .statements_it = undefined,
+ .variables = AliasList.init(c.arena),
.label = label,
};
return block;
}
+ fn pushStatement(self: *Block, c: *Context, stmt: *ast.Node) !void {
+ self.statements_it = c.llpush(*ast.Node, self.statements_it, stmt);
+ }
+
+ fn setBlockNode(self: *Block, block: *ast.Node.Block) void {
+ self.block_node = block;
+ self.statements_it = &block.statements.first;
+ }
+
/// Given the desired name, return a name that does not shadow anything from outer scopes.
/// Inserts the returned name into the scope.
fn makeMangledName(scope: *Block, c: *Context, name: []const u8) ![]const u8 {
var proposed_name = name;
while (scope.contains(proposed_name)) {
scope.mangle_count += 1;
- proposed_name = try std.fmt.allocPrint(c.a(), "{}_{}", .{ name, scope.mangle_count });
+ proposed_name = try std.fmt.allocPrint(c.arena, "{}_{}", .{ name, scope.mangle_count });
}
- try scope.variables.push(.{ .name = name, .alias = proposed_name });
+ try scope.variables.append(.{ .name = name, .alias = proposed_name });
return proposed_name;
}
fn getAlias(scope: *Block, name: []const u8) []const u8 {
- var it = scope.variables.iterator(0);
- while (it.next()) |p| {
+ for (scope.variables.items) |p| {
if (mem.eql(u8, p.name, name))
return p.alias;
}
@@ -105,8 +115,7 @@ const Scope = struct {
}
fn localContains(scope: *Block, name: []const u8) bool {
- var it = scope.variables.iterator(0);
- while (it.next()) |p| {
+ for (scope.variables.items) |p| {
if (mem.eql(u8, p.name, name))
return true;
}
@@ -132,8 +141,8 @@ const Scope = struct {
.id = .Root,
.parent = null,
},
- .sym_table = SymbolTable.init(c.a()),
- .macro_table = SymbolTable.init(c.a()),
+ .sym_table = SymbolTable.init(c.arena),
+ .macro_table = SymbolTable.init(c.arena),
.context = c,
};
}
@@ -208,7 +217,10 @@ const Scope = struct {
};
pub const Context = struct {
- tree: *ast.Tree,
+ gpa: *mem.Allocator,
+ arena: *mem.Allocator,
+ tokens: std.ArrayListUnmanaged(Token),
+ errors: std.ArrayListUnmanaged(ast.Error),
source_buffer: *std.ArrayList(u8),
err: Error,
source_manager: *ZigClangSourceManager,
@@ -217,6 +229,8 @@ pub const Context = struct {
global_scope: *Scope.Root,
clang_context: *ZigClangASTContext,
mangle_count: u32 = 0,
+ root_node: *ast.Node.Root,
+ root_decls_it: *?*std.SinglyLinkedList(*ast.Node).Node,
/// This one is different than the root scope's name table. This contains
/// a list of names that we found by visiting all the top level decls without
@@ -224,18 +238,45 @@ 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);
+ }
+ };
+
+ /// Helper function to append items to a singly linked list.
+ fn llpusher(c: *Context, list: *std.SinglyLinkedList(*ast.Node)) LinkedListPusher {
+ assert(list.first == null);
+ return .{
+ .c = c,
+ .it = &list.first,
+ };
+ }
+
+ fn llpush(
+ c: *Context,
+ comptime T: type,
+ it: *?*std.SinglyLinkedList(T).Node,
+ data: T,
+ ) !*?*std.SinglyLinkedList(T).Node {
+ const llnode = try c.arena.create(std.SinglyLinkedList(T).Node);
+ llnode.* = .{ .data = data };
+ it.* = llnode;
+ return &llnode.next;
+ }
+
fn getMangle(c: *Context) u32 {
c.mangle_count += 1;
return c.mangle_count;
}
- fn a(c: *Context) *mem.Allocator {
- return &c.tree.arena_allocator.allocator;
- }
-
/// Convert a null-terminated C string to a slice allocated in the arena
fn str(c: *Context, s: [*:0]const u8) ![]u8 {
- return mem.dupe(c.a(), u8, mem.spanZ(s));
+ return mem.dupe(c.arena, u8, mem.spanZ(s));
}
/// Convert a clang source location to a file:line:column string
@@ -246,12 +287,12 @@ pub const Context = struct {
const line = ZigClangSourceManager_getSpellingLineNumber(c.source_manager, spelling_loc);
const column = ZigClangSourceManager_getSpellingColumnNumber(c.source_manager, spelling_loc);
- return std.fmt.allocPrint(c.a(), "{}:{}:{}", .{ filename, line, column });
+ return std.fmt.allocPrint(c.arena, "{}:{}:{}", .{ filename, line, column });
}
};
pub fn translate(
- backing_allocator: *mem.Allocator,
+ gpa: *mem.Allocator,
args_begin: [*]?[*]const u8,
args_end: [*]?[*]const u8,
errors: *[]ClangErrMsg,
@@ -269,47 +310,43 @@ pub fn translate(
};
defer ZigClangASTUnit_delete(ast_unit);
- const tree = blk: {
- var tree_arena = std.heap.ArenaAllocator.init(backing_allocator);
- errdefer tree_arena.deinit();
-
- const tree = try tree_arena.allocator.create(ast.Tree);
- tree.* = .{
- .source = undefined, // need to use toOwnedSlice later
- .root_node = undefined,
- .arena_allocator = tree_arena,
- .tokens = undefined, // can't reference the allocator yet
- .errors = undefined, // can't reference the allocator yet
- .generated = true,
- };
- break :blk tree;
- };
- const arena = &tree.arena_allocator.allocator; // now we can reference the allocator
- errdefer tree.arena_allocator.deinit();
- tree.tokens = ast.Tree.TokenList.init(arena);
- tree.errors = ast.Tree.ErrorList.init(arena);
-
- tree.root_node = try arena.create(ast.Node.Root);
- tree.root_node.* = .{
- .decls = ast.Node.Root.DeclList.init(arena),
+ var source_buffer = std.ArrayList(u8).init(gpa);
+ defer source_buffer.deinit();
+
+ // For memory that has the same lifetime as the Tree that we return
+ // from this function.
+ var arena = std.heap.ArenaAllocator.init(gpa);
+ errdefer arena.deinit();
+
+ const root_node = try arena.allocator.create(ast.Node.Root);
+ root_node.* = .{
+ .decls = ast.Node.Root.DeclList{},
// initialized with the eof token at the end
.eof_token = undefined,
};
- var source_buffer = std.ArrayList(u8).init(arena);
-
var context = Context{
- .tree = tree,
+ .gpa = gpa,
+ .arena = &arena.allocator,
.source_buffer = &source_buffer,
.source_manager = ZigClangASTUnit_getSourceManager(ast_unit),
.err = undefined,
- .decl_table = DeclTable.init(arena),
- .alias_list = AliasList.init(arena),
- .global_scope = try arena.create(Scope.Root),
+ .decl_table = DeclTable.init(gpa),
+ .alias_list = AliasList.init(gpa),
+ .global_scope = try arena.allocator.create(Scope.Root),
.clang_context = ZigClangASTUnit_getASTContext(ast_unit).?,
- .global_names = std.StringHashMap(void).init(arena),
+ .global_names = std.StringHashMap(void).init(gpa),
+ .tokens = .{},
+ .errors = .{},
+ .root_node = root_node,
+ .root_decls_it = &root_node.decls.first,
};
context.global_scope.* = Scope.Root.init(&context);
+ defer context.decl_table.deinit();
+ defer context.alias_list.deinit();
+ defer context.tokens.deinit(gpa);
+ defer context.errors.deinit(gpa);
+ defer context.global_names.deinit();
try prepopulateGlobalNameTable(ast_unit, &context);
@@ -320,23 +357,30 @@ pub fn translate(
try transPreprocessorEntities(&context, ast_unit);
try addMacros(&context);
- var it = context.alias_list.iterator(0);
- while (it.next()) |alias| {
+ for (context.alias_list.items) |alias| {
if (!context.global_scope.sym_table.contains(alias.alias)) {
try createAlias(&context, alias);
}
}
- tree.root_node.eof_token = try appendToken(&context, .Eof, "");
- tree.source = source_buffer.toOwnedSlice();
+ root_node.eof_token = try appendToken(&context, .Eof, "");
if (false) {
- std.debug.warn("debug source:\n{}\n==EOF==\ntokens:\n", .{tree.source});
- var i: usize = 0;
- while (i < tree.tokens.len) : (i += 1) {
- const token = tree.tokens.at(i);
+ std.debug.warn("debug source:\n{}\n==EOF==\ntokens:\n", .{source_buffer.items});
+ for (context.tokens.items) |token| {
std.debug.warn("{}\n", .{token});
}
}
+
+ const tree = try arena.allocator.create(ast.Tree);
+ tree.* = .{
+ .gpa = gpa,
+ .source = try arena.allocator.dupe(u8, source_buffer.items),
+ .tokens = context.tokens.toOwnedSlice(gpa),
+ .errors = context.errors.toOwnedSlice(gpa),
+ .root_node = root_node,
+ .arena = arena.state,
+ .generated = true,
+ };
return tree;
}
@@ -493,17 +537,19 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
const block_scope = try Scope.Block.init(rp.c, &c.global_scope.base, null);
var scope = &block_scope.base;
const block_node = try transCreateNodeBlock(rp.c, null);
- block_scope.block_node = block_node;
+ block_scope.setBlockNode(block_node);
- var it = proto_node.params.iterator(0);
+ var it = proto_node.params.first;
var param_id: c_uint = 0;
- while (it.next()) |p| {
- const param = @fieldParentPtr(ast.Node.ParamDecl, "base", p.*);
+ var prev_node_link = &proto_node.params_first;
+ while (it) |p_node| : ({prev_node_link = &p_node.next; it = p_node.next;}) {
+ const p = p_node.data;
+ const param = @fieldParentPtr(ast.Node.ParamDecl, "base", p);
const param_name = if (param.name_token) |name_tok|
tokenSlice(c, name_tok)
else if (param.param_type == .var_args) {
- assert(it.next() == null);
- _ = proto_node.params.pop();
+ assert(p_node.next == null);
+ prev_node_link.* = null;
break;
} else
return failDecl(c, fn_decl_loc, fn_name, "function {} parameter has no name", .{fn_name});
@@ -516,7 +562,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
const arg_name = blk: {
const param_prefix = if (is_const) "" else "arg_";
- const bare_arg_name = try std.fmt.allocPrint(c.a(), "{}{}", .{ param_prefix, mangled_param_name });
+ const bare_arg_name = try std.fmt.allocPrint(c.arena, "{}{}", .{ param_prefix, mangled_param_name });
break :blk try block_scope.makeMangledName(c, bare_arg_name);
};
@@ -525,7 +571,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, ";");
- try block_node.statements.push(&node.base);
+ block_scope.block_statements_it = try c.llpush(*ast.Node, block_scope.block_statements_it, &node.base);
param.name_token = try appendIdentifier(c, arg_name);
_ = try appendToken(c, .Colon, ":");
}
@@ -560,7 +606,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
// TODO https://github.com/ziglang/zig/issues/3756
// TODO https://github.com/ziglang/zig/issues/1802
- const checked_name = if (isZigPrimitiveType(var_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ var_name, c.getMangle() }) else var_name;
+ const checked_name = if (isZigPrimitiveType(var_name)) try std.fmt.allocPrint(c.arena, "{}_{}", .{ var_name, c.getMangle() }) else var_name;
const var_decl_loc = ZigClangVarDecl_getLocation(var_decl);
const qual_type = ZigClangVarDecl_getTypeSourceInfo_getType(var_decl);
@@ -620,7 +666,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
_ = try appendToken(rp.c, .LParen, "(");
const expr = try transCreateNodeStringLiteral(
rp.c,
- try std.fmt.allocPrint(rp.c.a(), "\"{}\"", .{str_ptr[0..str_len]}),
+ try std.fmt.allocPrint(rp.c.arena, "\"{}\"", .{str_ptr[0..str_len]}),
);
_ = try appendToken(rp.c, .RParen, ")");
@@ -643,7 +689,7 @@ fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
break :blk null;
};
- const node = try c.a().create(ast.Node.VarDecl);
+ const node = try c.arena.create(ast.Node.VarDecl);
node.* = .{
.doc_comments = null,
.visib_token = visib_tok,
@@ -702,7 +748,7 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l
// TODO https://github.com/ziglang/zig/issues/3756
// TODO https://github.com/ziglang/zig/issues/1802
- const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name;
+ const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.arena, "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name;
if (checkForBuiltinTypedef(checked_name)) |builtin| {
return transTypeDefAsBuiltin(c, typedef_decl, builtin);
}
@@ -745,7 +791,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
// Record declarations such as `struct {...} x` have no name but they're not
// anonymous hence here isAnonymousStructOrUnion is not needed
if (bare_name.len == 0) {
- bare_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{c.getMangle()});
+ bare_name = try std.fmt.allocPrint(c.arena, "unnamed_{}", .{c.getMangle()});
is_unnamed = true;
}
@@ -762,7 +808,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
return null;
}
- const name = try std.fmt.allocPrint(c.a(), "{}_{}", .{ container_kind_name, bare_name });
+ const name = try std.fmt.allocPrint(c.arena, "{}_{}", .{ container_kind_name, bare_name });
_ = try c.decl_table.put(@ptrToInt(ZigClangRecordDecl_getCanonicalDecl(record_decl)), name);
const node = try transCreateNodeVarDecl(c, !is_unnamed, true, name);
@@ -785,15 +831,16 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
const container_tok = try appendToken(c, container_kind, container_kind_name);
const lbrace_token = try appendToken(c, .LBrace, "{");
- const container_node = try c.a().create(ast.Node.ContainerDecl);
+ const container_node = try c.arena.create(ast.Node.ContainerDecl);
container_node.* = .{
.layout_token = layout_tok,
.kind_token = container_tok,
.init_arg_expr = .None,
- .fields_and_decls = ast.Node.ContainerDecl.DeclList.init(c.a()),
+ .fields_and_decls = ast.Node.ContainerDecl.DeclList{},
.lbrace_token = lbrace_token,
.rbrace_token = undefined,
};
+ var container_fields_and_decls = c.llpusher(&container_node.fields_and_decls);
var unnamed_field_count: u32 = 0;
var it = ZigClangRecordDecl_field_begin(record_def);
@@ -821,7 +868,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
var raw_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, field_decl)));
if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl) or raw_name.len == 0) {
// Context.getMangle() is not used here because doing so causes unpredictable field names for anonymous fields.
- raw_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{unnamed_field_count});
+ raw_name = try std.fmt.allocPrint(c.arena, "unnamed_{}", .{unnamed_field_count});
unnamed_field_count += 1;
is_anon = true;
}
@@ -851,7 +898,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
break :blk null;
};
- const field_node = try c.a().create(ast.Node.ContainerField);
+ const field_node = try c.arena.create(ast.Node.ContainerField);
field_node.* = .{
.doc_comments = null,
.comptime_token = null,
@@ -868,7 +915,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
);
}
- try container_node.fields_and_decls.push(&field_node.base);
+ try container_fields_and_decls.push(&field_node.base);
_ = try appendToken(c, .Comma, ",");
}
container_node.rbrace_token = try appendToken(c, .RBrace, "}");
@@ -892,11 +939,11 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
var bare_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, enum_decl)));
var is_unnamed = false;
if (bare_name.len == 0) {
- bare_name = try std.fmt.allocPrint(c.a(), "unnamed_{}", .{c.getMangle()});
+ bare_name = try std.fmt.allocPrint(c.arena, "unnamed_{}", .{c.getMangle()});
is_unnamed = true;
}
- const name = try std.fmt.allocPrint(c.a(), "enum_{}", .{bare_name});
+ const name = try std.fmt.allocPrint(c.arena, "enum_{}", .{bare_name});
_ = try c.decl_table.put(@ptrToInt(ZigClangEnumDecl_getCanonicalDecl(enum_decl)), name);
const node = try transCreateNodeVarDecl(c, !is_unnamed, true, name);
node.eq_token = try appendToken(c, .Equal, "=");
@@ -916,15 +963,16 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
const extern_tok = try appendToken(c, .Keyword_extern, "extern");
const container_tok = try appendToken(c, .Keyword_enum, "enum");
- const container_node = try c.a().create(ast.Node.ContainerDecl);
+ const container_node = try c.arena.create(ast.Node.ContainerDecl);
container_node.* = .{
.layout_token = extern_tok,
.kind_token = container_tok,
.init_arg_expr = .None,
- .fields_and_decls = ast.Node.ContainerDecl.DeclList.init(c.a()),
+ .fields_and_decls = ast.Node.ContainerDecl.DeclList{},
.lbrace_token = undefined,
.rbrace_token = undefined,
};
+ var container_node_fields_and_decls = c.llpusher(&container_node.fields_and_decls);
const int_type = ZigClangEnumDecl_getIntegerType(enum_decl);
// The underlying type may be null in case of forward-declared enum
@@ -971,7 +1019,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
} else
null;
- const field_node = try c.a().create(ast.Node.ContainerField);
+ const field_node = try c.arena.create(ast.Node.ContainerField);
field_node.* = .{
.doc_comments = null,
.comptime_token = null,
@@ -981,7 +1029,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
.align_expr = null,
};
- try container_node.fields_and_decls.push(&field_node.base);
+ try container_node_fields_and_decls.push(&field_node.base);
_ = try appendToken(c, .Comma, ",");
// In C each enum value is in the global namespace. So we put them there too.
@@ -992,7 +1040,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
const enum_ident = try transCreateNodeIdentifier(c, name);
const period_tok = try appendToken(c, .Period, ".");
const field_ident = try transCreateNodeIdentifier(c, field_name);
- const field_access_node = try c.a().create(ast.Node.InfixOp);
+ const field_access_node = try c.arena.create(ast.Node.InfixOp);
field_access_node.* = .{
.op_token = period_tok,
.lhs = enum_ident,
@@ -1006,7 +1054,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
try addTopLevelDecl(c, field_name, &tld_node.base);
}
// make non exhaustive
- const field_node = try c.a().create(ast.Node.ContainerField);
+ const field_node = try c.arena.create(ast.Node.ContainerField);
field_node.* = .{
.doc_comments = null,
.comptime_token = null,
@@ -1016,7 +1064,7 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No
.align_expr = null,
};
- try container_node.fields_and_decls.push(&field_node.base);
+ try container_node_fields_and_decls.push(&field_node.base);
_ = try appendToken(c, .Comma, ",");
container_node.rbrace_token = try appendToken(c, .RBrace, "}");
@@ -1071,7 +1119,7 @@ fn transStmt(
.ParenExprClass => {
const expr = try transExpr(rp, scope, ZigClangParenExpr_getSubExpr(@ptrCast(*const ZigClangParenExpr, stmt)), .used, lrvalue);
if (expr.id == .GroupedExpression) return maybeSuppressResult(rp, scope, result_used, expr);
- const node = try rp.c.a().create(ast.Node.GroupedExpression);
+ const node = try rp.c.arena.create(ast.Node.GroupedExpression);
node.* = .{
.lparen = try appendToken(rp.c, .LParen, "("),
.expr = expr,
@@ -1116,7 +1164,7 @@ fn transStmt(
const source_expr = ZigClangOpaqueValueExpr_getSourceExpr(@ptrCast(*const ZigClangOpaqueValueExpr, stmt)).?;
const expr = try transExpr(rp, scope, source_expr, .used, lrvalue);
if (expr.id == .GroupedExpression) return maybeSuppressResult(rp, scope, result_used, expr);
- const node = try rp.c.a().create(ast.Node.GroupedExpression);
+ const node = try rp.c.arena.create(ast.Node.GroupedExpression);
node.* = .{
.lparen = try appendToken(rp.c, .LParen, "("),
.expr = expr,
@@ -1147,18 +1195,18 @@ fn transBinaryOperator(
var op_token: ast.TokenIndex = undefined;
var op_id: ast.Node.InfixOp.Op = undefined;
switch (op) {
- .Assign => return transCreateNodeAssign(rp, scope, result_used, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt)),
+ .Assign => return try transCreateNodeAssign(rp, scope, result_used, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt)),
.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.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
+ block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
break :blk l;
} else undefined;
const lhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getLHS(stmt), .unused, .r_value);
- try block_scope.block_node.statements.push(lhs);
+ try block_scope.statements.push(lhs);
const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
if (expr) {
@@ -1168,7 +1216,7 @@ fn transBinaryOperator(
try block_scope.block_node.statements.push(&break_node.base);
block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
const rparen = try appendToken(rp.c, .RParen, ")");
- const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
+ const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
grouped_expr.* = .{
.lparen = lparen,
.expr = &block_scope.block_node.base,
@@ -1335,7 +1383,7 @@ fn transCompoundStmtInline(
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.block_node = try transCreateNodeBlock(rp.c, 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;
@@ -1458,7 +1506,7 @@ fn transImplicitCastExpr(
switch (ZigClangImplicitCastExpr_getCastKind(expr)) {
.BitCast, .FloatingCast, .FloatingToIntegral, .IntegralToFloating, .IntegralCast, .PointerToIntegral, .IntegralToPointer => {
const sub_expr_node = try transExpr(rp, scope, sub_expr, .used, .r_value);
- return transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node);
+ return try transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node);
},
.LValueToRValue, .NoOp, .FunctionToPointerDecay => {
const sub_expr_node = try transExpr(rp, scope, sub_expr, .used, .r_value);
@@ -1539,7 +1587,7 @@ fn transBoolExpr(
if (grouped) {
const rparen = try appendToken(rp.c, .RParen, ")");
- const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
+ const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
grouped_expr.* = .{
.lparen = lparen,
.expr = node,
@@ -1747,13 +1795,13 @@ fn transStringLiteral(
len = 0;
for (str) |c| len += escapeChar(c, &char_buf).len;
- const buf = try rp.c.a().alloc(u8, len + "\"\"".len);
+ const buf = try rp.c.arena.alloc(u8, len + "\"\"".len);
buf[0] = '"';
writeEscapedString(buf[1..], str);
buf[buf.len - 1] = '"';
const token = try appendToken(rp.c, .StringLiteral, buf);
- const node = try rp.c.a().create(ast.Node.StringLiteral);
+ const node = try rp.c.arena.create(ast.Node.StringLiteral);
node.* = .{
.token = token,
};
@@ -2038,13 +2086,13 @@ fn transInitListExprRecord(
var raw_name = try rp.c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, field_decl)));
if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) {
const name = rp.c.decl_table.get(@ptrToInt(ZigClangFieldDecl_getCanonicalDecl(field_decl))).?;
- raw_name = try mem.dupe(rp.c.a(), u8, name.value);
+ raw_name = try mem.dupe(rp.c.arena, u8, name.value);
}
const field_name_tok = try appendIdentifier(rp.c, raw_name);
_ = try appendToken(rp.c, .Equal, "=");
- const field_init_node = try rp.c.a().create(ast.Node.FieldInitializer);
+ const field_init_node = try rp.c.arena.create(ast.Node.FieldInitializer);
field_init_node.* = .{
.period_token = period_tok,
.name_token = field_name_tok,
@@ -2133,7 +2181,7 @@ fn transInitListExprArray(
&filler_init_node.base
else blk: {
const mul_tok = try appendToken(rp.c, .AsteriskAsterisk, "**");
- const mul_node = try rp.c.a().create(ast.Node.InfixOp);
+ const mul_node = try rp.c.arena.create(ast.Node.InfixOp);
mul_node.* = .{
.op_token = mul_tok,
.lhs = &filler_init_node.base,
@@ -2147,7 +2195,7 @@ fn transInitListExprArray(
return rhs_node;
}
- const cat_node = try rp.c.a().create(ast.Node.InfixOp);
+ const cat_node = try rp.c.arena.create(ast.Node.InfixOp);
cat_node.* = .{
.op_token = cat_tok,
.lhs = &init_node.base,
@@ -2382,7 +2430,7 @@ fn transForLoop(
if (ZigClangForStmt_getInit(stmt)) |init| {
block_scope = try Scope.Block.init(rp.c, scope, null);
const block = try transCreateNodeBlock(rp.c, null);
- block_scope.?.block_node = block;
+ 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)
@@ -2445,7 +2493,7 @@ fn transSwitch(
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.block_node = block;
+ block_scope.setBlockNode(block);
const switch_block = try transCreateNodeBlock(rp.c, null);
try switch_block.statements.push(&switch_node.base);
@@ -2479,7 +2527,7 @@ fn transCase(
) TransError!*ast.Node {
const block_scope = scope.findBlockScope(rp.c) catch unreachable;
const switch_scope = scope.getSwitch();
- const label = try std.fmt.allocPrint(rp.c.a(), "__case_{}", .{switch_scope.cases.len - @boolToInt(switch_scope.has_default)});
+ const label = try std.fmt.allocPrint(rp.c.arena, "__case_{}", .{switch_scope.cases.len() - @boolToInt(switch_scope.has_default)});
_ = try appendToken(rp.c, .Semicolon, ";");
const expr = if (ZigClangCaseStmt_getRHS(stmt)) |rhs| blk: {
@@ -2487,7 +2535,7 @@ fn transCase(
const ellips = try appendToken(rp.c, .Ellipsis3, "...");
const rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
- const node = try rp.c.a().create(ast.Node.InfixOp);
+ const node = try rp.c.arena.create(ast.Node.InfixOp);
node.* = .{
.op_token = ellips,
.lhs = lhs_node,
@@ -2606,7 +2654,7 @@ fn transCharLiteral(
}
var char_buf: [4]u8 = undefined;
const token = try appendTokenFmt(rp.c, .CharLiteral, "'{}'", .{escapeChar(@intCast(u8, val), &char_buf)});
- const node = try rp.c.a().create(ast.Node.CharLiteral);
+ const node = try rp.c.arena.create(ast.Node.CharLiteral);
node.* = .{
.token = token,
};
@@ -2646,7 +2694,7 @@ 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.block_node = block;
+ block_scope.setBlockNode(block);
var it = ZigClangCompoundStmt_body_begin(comp);
const end_it = ZigClangCompoundStmt_body_end(comp);
@@ -2661,7 +2709,7 @@ fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr,
try block.statements.push(&break_node.base);
block.rbrace = try appendToken(rp.c, .RBrace, "}");
const rparen = try appendToken(rp.c, .RParen, ")");
- const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
+ const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
grouped_expr.* = .{
.lparen = lparen,
.expr = &block.base,
@@ -2686,7 +2734,7 @@ fn transMemberExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangMemberE
const field_decl = @ptrCast(*const struct_ZigClangFieldDecl, member_decl);
if (ZigClangFieldDecl_isAnonymousStructOrUnion(field_decl)) {
const name = rp.c.decl_table.get(@ptrToInt(ZigClangFieldDecl_getCanonicalDecl(field_decl))).?;
- break :blk try mem.dupe(rp.c.a(), u8, name.value);
+ break :blk try mem.dupe(rp.c.arena, u8, name.value);
}
}
const decl = @ptrCast(*const ZigClangNamedDecl, member_decl);
@@ -2941,7 +2989,7 @@ fn transCreatePreCrement(
// zig: break :blk _ref.*
// zig: })
const block_scope = try Scope.Block.init(rp.c, scope, "blk");
- block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
+ block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
const ref = try block_scope.makeMangledName(rp.c, "ref");
const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
@@ -2967,7 +3015,7 @@ fn transCreatePreCrement(
block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
// 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.a().create(ast.Node.GroupedExpression);
+ 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,
@@ -3007,7 +3055,7 @@ fn transCreatePostCrement(
// zig: break :blk _tmp
// zig: })
const block_scope = try Scope.Block.init(rp.c, scope, "blk");
- block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
+ block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
const ref = try block_scope.makeMangledName(rp.c, "ref");
const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
@@ -3040,7 +3088,7 @@ fn transCreatePostCrement(
try block_scope.block_node.statements.push(&break_node.base);
_ = try appendToken(rp.c, .Semicolon, ";");
block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
- const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
+ 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,
@@ -3106,7 +3154,7 @@ fn transCreateCompoundAssign(
if ((is_mod or is_div) and is_signed) {
const op_token = try appendToken(rp.c, .Equal, "=");
- const op_node = try rp.c.a().create(ast.Node.InfixOp);
+ 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 lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
@@ -3152,7 +3200,7 @@ fn transCreateCompoundAssign(
// zig: break :blk _ref.*
// zig: })
const block_scope = try Scope.Block.init(rp.c, scope, "blk");
- block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
+ block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
const ref = try block_scope.makeMangledName(rp.c, "ref");
const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
@@ -3169,7 +3217,7 @@ fn transCreateCompoundAssign(
if ((is_mod or is_div) and is_signed) {
const op_token = try appendToken(rp.c, .Equal, "=");
- const op_node = try rp.c.a().create(ast.Node.InfixOp);
+ 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));
@@ -3211,7 +3259,7 @@ fn transCreateCompoundAssign(
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, "}");
- const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
+ 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,
@@ -3295,7 +3343,7 @@ fn transBreak(rp: RestorePoint, scope: *Scope) TransError!*ast.Node {
fn transFloatingLiteral(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangFloatingLiteral, used: ResultUsed) TransError!*ast.Node {
// TODO use something more accurate
const dbl = ZigClangAPFloat_getValueAsApproximateDouble(stmt);
- const node = try rp.c.a().create(ast.Node.FloatLiteral);
+ const node = try rp.c.arena.create(ast.Node.FloatLiteral);
node.* = .{
.token = try appendTokenFmt(rp.c, .FloatLiteral, "{d}", .{dbl}),
};
@@ -3318,7 +3366,7 @@ 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.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
+ block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
const mangled_name = try block_scope.makeMangledName(rp.c, "cond_temp");
const tmp_var = try transCreateNodeVarDecl(rp.c, false, true, mangled_name);
@@ -3351,7 +3399,7 @@ fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const
try block_scope.block_node.statements.push(&break_node.base);
block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
- const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
+ const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
grouped_expr.* = .{
.lparen = lparen,
.expr = &block_scope.block_node.base,
@@ -3384,7 +3432,7 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla
if (grouped) {
const rparen = try appendToken(rp.c, .RParen, ")");
- const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
+ const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
grouped_expr.* = .{
.lparen = lparen,
.expr = &if_node.base,
@@ -3415,7 +3463,7 @@ fn maybeSuppressResult(
}
const lhs = try transCreateNodeIdentifier(rp.c, "_");
const op_token = try appendToken(rp.c, .Equal, "=");
- const op_node = try rp.c.a().create(ast.Node.InfixOp);
+ const op_node = try rp.c.arena.create(ast.Node.InfixOp);
op_node.* = .{
.op_token = op_token,
.lhs = lhs,
@@ -3426,7 +3474,7 @@ fn maybeSuppressResult(
}
fn addTopLevelDecl(c: *Context, name: []const u8, decl_node: *ast.Node) !void {
- try c.tree.root_node.decls.push(decl_node);
+ c.root_decls_it = try c.llpush(*ast.Node, c.root_decls_it, decl_node);
_ = try c.global_scope.sym_table.put(name, decl_node);
}
@@ -3524,7 +3572,7 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC
if (int_bit_width != 0) {
// we can perform the log2 now.
const cast_bit_width = math.log2_int(u64, int_bit_width);
- const node = try rp.c.a().create(ast.Node.IntegerLiteral);
+ const node = try rp.c.arena.create(ast.Node.IntegerLiteral);
node.* = .{
.token = try appendTokenFmt(rp.c, .Identifier, "u{}", .{cast_bit_width}),
};
@@ -3547,7 +3595,7 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC
const import_fn_call = try transCreateNodeBuiltinFnCall(rp.c, "@import");
const std_token = try appendToken(rp.c, .StringLiteral, "\"std\"");
- const std_node = try rp.c.a().create(ast.Node.StringLiteral);
+ const std_node = try rp.c.arena.create(ast.Node.StringLiteral);
std_node.* = .{
.token = std_token,
};
@@ -3749,7 +3797,7 @@ fn transCreateNodeAssign(
// zig: break :blk _tmp
// zig: })
const block_scope = try Scope.Block.init(rp.c, scope, "blk");
- block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
+ block_scope.setBlockNode(try transCreateNodeBlock(rp.c, block_scope.label));
const tmp = try block_scope.makeMangledName(rp.c, "tmp");
const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);
@@ -3786,10 +3834,10 @@ fn transCreateNodeAssign(
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.a().create(ast.Node.BuiltinCall);
+ const node = try c.arena.create(ast.Node.BuiltinCall);
node.* = .{
.builtin_token = builtin_token,
- .params = ast.Node.BuiltinCall.ParamList.init(c.a()),
+ .params = ast.Node.BuiltinCall.ParamList{},
.rparen_token = undefined, // set after appending args
};
return node;
@@ -3797,12 +3845,12 @@ fn transCreateNodeBuiltinFnCall(c: *Context, name: []const u8) !*ast.Node.Builti
fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp {
_ = try appendToken(c, .LParen, "(");
- const node = try c.a().create(ast.Node.SuffixOp);
+ const node = try c.arena.create(ast.Node.SuffixOp);
node.* = .{
.lhs = .{ .node = fn_expr },
.op = .{
.Call = .{
- .params = ast.Node.SuffixOp.Op.Call.ParamList.init(c.a()),
+ .params = ast.Node.SuffixOp.Op.Call.ParamList{},
.async_token = null,
},
},
@@ -3812,7 +3860,7 @@ fn transCreateNodeFnCall(c: *Context, fn_expr: *ast.Node) !*ast.Node.SuffixOp {
}
fn transCreateNodeFieldAccess(c: *Context, container: *ast.Node, field_name: []const u8) !*ast.Node {
- const field_access_node = try c.a().create(ast.Node.InfixOp);
+ const field_access_node = try c.arena.create(ast.Node.InfixOp);
field_access_node.* = .{
.op_token = try appendToken(c, .Period, "."),
.lhs = container,
@@ -3828,7 +3876,7 @@ fn transCreateNodePrefixOp(
op_tok_id: std.zig.Token.Id,
bytes: []const u8,
) !*ast.Node.PrefixOp {
- const node = try c.a().create(ast.Node.PrefixOp);
+ const node = try c.arena.create(ast.Node.PrefixOp);
node.* = .{
.op_token = try appendToken(c, op_tok_id, bytes),
.op = op,
@@ -3851,7 +3899,7 @@ fn transCreateNodeInfixOp(
try appendToken(rp.c, .LParen, "(")
else
null;
- const node = try rp.c.a().create(ast.Node.InfixOp);
+ const node = try rp.c.arena.create(ast.Node.InfixOp);
node.* = .{
.op_token = op_token,
.lhs = lhs_node,
@@ -3860,7 +3908,7 @@ fn transCreateNodeInfixOp(
};
if (!grouped) return maybeSuppressResult(rp, scope, used, &node.base);
const rparen = try appendToken(rp.c, .RParen, ")");
- const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
+ const grouped_expr = try rp.c.arena.create(ast.Node.GroupedExpression);
grouped_expr.* = .{
.lparen = lparen.?,
.expr = &node.base,
@@ -3904,7 +3952,7 @@ fn transCreateNodePtrType(
is_volatile: bool,
op_tok_id: std.zig.Token.Id,
) !*ast.Node.PrefixOp {
- const node = try c.a().create(ast.Node.PrefixOp);
+ const node = try c.arena.create(ast.Node.PrefixOp);
const op_token = switch (op_tok_id) {
.LBracket => blk: {
const lbracket = try appendToken(c, .LBracket, "[");
@@ -3946,8 +3994,8 @@ fn transCreateNodeAPInt(c: *Context, int: *const ZigClangAPSInt) !*ast.Node {
ZigClangAPSInt_free(aps_int);
};
- const limbs = try c.a().alloc(math.big.Limb, num_limbs);
- defer c.a().free(limbs);
+ const limbs = try c.arena.alloc(math.big.Limb, num_limbs);
+ defer c.arena.free(limbs);
const data = ZigClangAPSInt_getRawData(aps_int);
switch (@sizeOf(math.big.Limb)) {
@@ -3972,12 +4020,12 @@ fn transCreateNodeAPInt(c: *Context, int: *const ZigClangAPSInt) !*ast.Node {
}
const big: math.big.int.Const = .{ .limbs = limbs, .positive = !is_negative };
- const str = big.toStringAlloc(c.a(), 10, false) catch |err| switch (err) {
+ const str = big.toStringAlloc(c.arena, 10, false) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
};
- defer c.a().free(str);
+ defer c.arena.free(str);
const token = try appendToken(c, .IntegerLiteral, str);
- const node = try c.a().create(ast.Node.IntegerLiteral);
+ const node = try c.arena.create(ast.Node.IntegerLiteral);
node.* = .{
.token = token,
};
@@ -3986,7 +4034,7 @@ fn transCreateNodeAPInt(c: *Context, int: *const ZigClangAPSInt) !*ast.Node {
fn transCreateNodeReturnExpr(c: *Context) !*ast.Node.ControlFlowExpression {
const ltoken = try appendToken(c, .Keyword_return, "return");
- const node = try c.a().create(ast.Node.ControlFlowExpression);
+ const node = try c.arena.create(ast.Node.ControlFlowExpression);
node.* = .{
.ltoken = ltoken,
.kind = .Return,
@@ -3997,7 +4045,7 @@ fn transCreateNodeReturnExpr(c: *Context) !*ast.Node.ControlFlowExpression {
fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node {
const token = try appendToken(c, .Keyword_undefined, "undefined");
- const node = try c.a().create(ast.Node.UndefinedLiteral);
+ const node = try c.arena.create(ast.Node.UndefinedLiteral);
node.* = .{
.token = token,
};
@@ -4006,7 +4054,7 @@ fn transCreateNodeUndefinedLiteral(c: *Context) !*ast.Node {
fn transCreateNodeNullLiteral(c: *Context) !*ast.Node {
const token = try appendToken(c, .Keyword_null, "null");
- const node = try c.a().create(ast.Node.NullLiteral);
+ const node = try c.arena.create(ast.Node.NullLiteral);
node.* = .{
.token = token,
};
@@ -4018,7 +4066,7 @@ fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node {
try appendToken(c, .Keyword_true, "true")
else
try appendToken(c, .Keyword_false, "false");
- const node = try c.a().create(ast.Node.BoolLiteral);
+ const node = try c.arena.create(ast.Node.BoolLiteral);
node.* = .{
.token = token,
};
@@ -4027,11 +4075,11 @@ fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node {
fn transCreateNodeArrayInitializer(c: *Context, ty: *ast.Node) !*ast.Node.SuffixOp {
_ = try appendToken(c, .LBrace, "{");
- const node = try c.a().create(ast.Node.SuffixOp);
+ const node = try c.arena.create(ast.Node.SuffixOp);
node.* = .{
.lhs = .{ .node = ty },
.op = .{
- .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
+ .ArrayInitializer = ast.Node.SuffixOp.Op.InitList{},
},
.rtoken = undefined, // set after appending values
};
@@ -4040,11 +4088,11 @@ fn transCreateNodeArrayInitializer(c: *Context, ty: *ast.Node) !*ast.Node.Suffix
fn transCreateNodeStructInitializer(c: *Context, ty: *ast.Node) !*ast.Node.SuffixOp {
_ = try appendToken(c, .LBrace, "{");
- const node = try c.a().create(ast.Node.SuffixOp);
+ const node = try c.arena.create(ast.Node.SuffixOp);
node.* = .{
.lhs = .{ .node = ty },
.op = .{
- .StructInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
+ .StructInitializer = ast.Node.SuffixOp.Op.InitList{},
},
.rtoken = undefined, // set after appending values
};
@@ -4053,7 +4101,7 @@ fn transCreateNodeStructInitializer(c: *Context, ty: *ast.Node) !*ast.Node.Suffi
fn transCreateNodeInt(c: *Context, int: var) !*ast.Node {
const token = try appendTokenFmt(c, .IntegerLiteral, "{}", .{int});
- const node = try c.a().create(ast.Node.IntegerLiteral);
+ const node = try c.arena.create(ast.Node.IntegerLiteral);
node.* = .{
.token = token,
};
@@ -4062,7 +4110,7 @@ fn transCreateNodeInt(c: *Context, int: var) !*ast.Node {
fn transCreateNodeFloat(c: *Context, int: var) !*ast.Node {
const token = try appendTokenFmt(c, .FloatLiteral, "{}", .{int});
- const node = try c.a().create(ast.Node.FloatLiteral);
+ const node = try c.arena.create(ast.Node.FloatLiteral);
node.* = .{
.token = token,
};
@@ -4085,20 +4133,22 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
const name_tok = try appendIdentifier(c, name);
_ = try appendToken(c, .LParen, "(");
- var fn_params = ast.Node.FnProto.ParamList.init(c.a());
- var it = proto_alias.params.iterator(0);
- while (it.next()) |pn| {
- if (it.index != 0) {
+ var fn_params = ast.Node.FnProto.ParamList{};
+ var fn_params_list = &fn_params.first;
+ var it = proto_alias.params.first;
+ while (it) |pn_node| : (it = pn_node.next) {
+ const pn = pn_node.data;
+ if (pn_node != proto_alias.params.first.?) {
_ = try appendToken(c, .Comma, ",");
}
- const param = pn.*.cast(ast.Node.ParamDecl).?;
+ const param = pn.cast(ast.Node.ParamDecl).?;
const param_name_tok = param.name_token orelse
try appendTokenFmt(c, .Identifier, "arg_{}", .{c.getMangle()});
_ = try appendToken(c, .Colon, ":");
- const param_node = try c.a().create(ast.Node.ParamDecl);
+ const param_node = try c.arena.create(ast.Node.ParamDecl);
param_node.* = .{
.doc_comments = null,
.comptime_token = null,
@@ -4106,12 +4156,12 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
.name_token = param_name_tok,
.param_type = param.param_type,
};
- try fn_params.push(¶m_node.base);
+ fn_params_list = try c.llpush(*ast.Node, fn_params_list, ¶m_node.base);
}
_ = try appendToken(c, .RParen, ")");
- const fn_proto = try c.a().create(ast.Node.FnProto);
+ const fn_proto = try c.arena.create(ast.Node.FnProto);
fn_proto.* = .{
.doc_comments = null,
.visib_token = pub_tok,
@@ -4129,24 +4179,28 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
};
const block = try transCreateNodeBlock(c, null);
+ var block_statements_it = &block.statements.first;
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);
- it = fn_params.iterator(0);
- while (it.next()) |pn| {
- if (it.index != 0) {
+ var call_params_it = &call_expr.op.Call.params.first;
+
+ it = fn_params.first;
+ while (it) |pn_node| : (it = pn_node.next) {
+ const pn = pn_node.data;
+ if (fn_params.first.? != pn_node) {
_ = try appendToken(c, .Comma, ",");
}
- const param = pn.*.cast(ast.Node.ParamDecl).?;
- try call_expr.op.Call.params.push(try transCreateNodeIdentifier(c, tokenSlice(c, param.name_token.?)));
+ const param = pn.cast(ast.Node.ParamDecl).?;
+ call_params_it = try c.llpush(*ast.Node, call_params_it, 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, "}");
- try block.statements.push(&return_expr.base);
+ block_statements_it = try c.llpush(*ast.Node, block_statements_it, &return_expr.base);
fn_proto.body_node = &block.base;
return &fn_proto.base;
}
@@ -4154,7 +4208,7 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
fn transCreateNodeUnwrapNull(c: *Context, wrapped: *ast.Node) !*ast.Node {
_ = try appendToken(c, .Period, ".");
const qm = try appendToken(c, .QuestionMark, "?");
- const node = try c.a().create(ast.Node.SuffixOp);
+ const node = try c.arena.create(ast.Node.SuffixOp);
node.* = .{
.op = .UnwrapOptional,
.lhs = .{ .node = wrapped },
@@ -4164,7 +4218,7 @@ fn transCreateNodeUnwrapNull(c: *Context, wrapped: *ast.Node) !*ast.Node {
}
fn transCreateNodeEnumLiteral(c: *Context, name: []const u8) !*ast.Node {
- const node = try c.a().create(ast.Node.EnumLiteral);
+ const node = try c.arena.create(ast.Node.EnumLiteral);
node.* = .{
.dot = try appendToken(c, .Period, "."),
.name = try appendIdentifier(c, name),
@@ -4173,7 +4227,7 @@ fn transCreateNodeEnumLiteral(c: *Context, name: []const u8) !*ast.Node {
}
fn transCreateNodeStringLiteral(c: *Context, str: []const u8) !*ast.Node {
- const node = try c.a().create(ast.Node.StringLiteral);
+ const node = try c.arena.create(ast.Node.StringLiteral);
node.* = .{
.token = try appendToken(c, .StringLiteral, str),
};
@@ -4183,7 +4237,7 @@ fn transCreateNodeStringLiteral(c: *Context, str: []const u8) !*ast.Node {
fn transCreateNodeIf(c: *Context) !*ast.Node.If {
const if_tok = try appendToken(c, .Keyword_if, "if");
_ = try appendToken(c, .LParen, "(");
- const node = try c.a().create(ast.Node.If);
+ const node = try c.arena.create(ast.Node.If);
node.* = .{
.if_token = if_tok,
.condition = undefined,
@@ -4195,7 +4249,7 @@ fn transCreateNodeIf(c: *Context) !*ast.Node.If {
}
fn transCreateNodeElse(c: *Context) !*ast.Node.Else {
- const node = try c.a().create(ast.Node.Else);
+ const node = try c.arena.create(ast.Node.Else);
node.* = .{
.else_token = try appendToken(c, .Keyword_else, "else"),
.payload = null,
@@ -4210,11 +4264,11 @@ fn transCreateNodeBlock(c: *Context, label: ?[]const u8) !*ast.Node.Block {
_ = try appendToken(c, .Colon, ":");
break :blk ll;
} else null;
- const block_node = try c.a().create(ast.Node.Block);
+ 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.init(c.a()),
+ .statements = ast.Node.Block.StatementList{},
.rbrace = undefined,
};
return block_node;
@@ -4226,7 +4280,7 @@ fn transCreateNodeBreak(c: *Context, label: ?[]const u8) !*ast.Node.ControlFlowE
_ = try appendToken(c, .Colon, ":");
break :blk try transCreateNodeIdentifier(c, l);
} else null;
- const node = try c.a().create(ast.Node.ControlFlowExpression);
+ const node = try c.arena.create(ast.Node.ControlFlowExpression);
node.* = .{
.ltoken = ltoken,
.kind = .{ .Break = label_node },
@@ -4240,7 +4294,7 @@ fn transCreateNodeVarDecl(c: *Context, is_pub: bool, is_const: bool, name: []con
const mut_tok = if (is_const) try appendToken(c, .Keyword_const, "const") else try appendToken(c, .Keyword_var, "var");
const name_tok = try appendIdentifier(c, name);
- const node = try c.a().create(ast.Node.VarDecl);
+ const node = try c.arena.create(ast.Node.VarDecl);
node.* = .{
.doc_comments = null,
.visib_token = visib_tok,
@@ -4264,7 +4318,7 @@ fn transCreateNodeWhile(c: *Context) !*ast.Node.While {
const while_tok = try appendToken(c, .Keyword_while, "while");
_ = try appendToken(c, .LParen, "(");
- const node = try c.a().create(ast.Node.While);
+ const node = try c.arena.create(ast.Node.While);
node.* = .{
.label = null,
.inline_token = null,
@@ -4280,7 +4334,7 @@ fn transCreateNodeWhile(c: *Context) !*ast.Node.While {
fn transCreateNodeContinue(c: *Context) !*ast.Node {
const ltoken = try appendToken(c, .Keyword_continue, "continue");
- const node = try c.a().create(ast.Node.ControlFlowExpression);
+ const node = try c.arena.create(ast.Node.ControlFlowExpression);
node.* = .{
.ltoken = ltoken,
.kind = .{ .Continue = null },
@@ -4294,11 +4348,11 @@ fn transCreateNodeSwitch(c: *Context) !*ast.Node.Switch {
const switch_tok = try appendToken(c, .Keyword_switch, "switch");
_ = try appendToken(c, .LParen, "(");
- const node = try c.a().create(ast.Node.Switch);
+ const node = try c.arena.create(ast.Node.Switch);
node.* = .{
.switch_token = switch_tok,
.expr = undefined,
- .cases = ast.Node.Switch.CaseList.init(c.a()),
+ .cases = ast.Node.Switch.CaseList{},
.rbrace = undefined,
};
return node;
@@ -4307,9 +4361,9 @@ fn transCreateNodeSwitch(c: *Context) !*ast.Node.Switch {
fn transCreateNodeSwitchCase(c: *Context, lhs: *ast.Node) !*ast.Node.SwitchCase {
const arrow_tok = try appendToken(c, .EqualAngleBracketRight, "=>");
- const node = try c.a().create(ast.Node.SwitchCase);
+ const node = try c.arena.create(ast.Node.SwitchCase);
node.* = .{
- .items = ast.Node.SwitchCase.ItemList.init(c.a()),
+ .items = ast.Node.SwitchCase.ItemList{},
.arrow_token = arrow_tok,
.payload = null,
.expr = undefined,
@@ -4319,7 +4373,7 @@ fn transCreateNodeSwitchCase(c: *Context, lhs: *ast.Node) !*ast.Node.SwitchCase
}
fn transCreateNodeSwitchElse(c: *Context) !*ast.Node {
- const node = try c.a().create(ast.Node.SwitchElse);
+ const node = try c.arena.create(ast.Node.SwitchElse);
node.* = .{
.token = try appendToken(c, .Keyword_else, "else"),
};
@@ -4352,7 +4406,7 @@ fn transCreateNodeShiftOp(
try cast_node.params.push(rhs);
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
- const node = try rp.c.a().create(ast.Node.InfixOp);
+ const node = try rp.c.arena.create(ast.Node.InfixOp);
node.* = .{
.op_token = op_token,
.lhs = lhs,
@@ -4364,7 +4418,7 @@ fn transCreateNodeShiftOp(
}
fn transCreateNodePtrDeref(c: *Context, lhs: *ast.Node) !*ast.Node {
- const node = try c.a().create(ast.Node.SuffixOp);
+ const node = try c.arena.create(ast.Node.SuffixOp);
node.* = .{
.lhs = .{ .node = lhs },
.op = .Deref,
@@ -4375,7 +4429,7 @@ fn transCreateNodePtrDeref(c: *Context, lhs: *ast.Node) !*ast.Node {
fn transCreateNodeArrayAccess(c: *Context, lhs: *ast.Node) !*ast.Node.SuffixOp {
_ = try appendToken(c, .LBrace, "[");
- const node = try c.a().create(ast.Node.SuffixOp);
+ const node = try c.arena.create(ast.Node.SuffixOp);
node.* = .{
.lhs = .{ .node = lhs },
.op = .{
@@ -4392,7 +4446,7 @@ const RestorePoint = struct {
src_buf_index: usize,
fn activate(self: RestorePoint) void {
- self.c.tree.tokens.shrink(self.token_index);
+ self.c.tokens.shrink(self.c.gpa, self.token_index);
self.c.source_buffer.shrink(self.src_buf_index);
}
};
@@ -4400,7 +4454,7 @@ const RestorePoint = struct {
fn makeRestorePoint(c: *Context) RestorePoint {
return RestorePoint{
.c = c,
- .token_index = c.tree.tokens.len,
+ .token_index = c.tokens.items.len,
.src_buf_index = c.source_buffer.items.len,
};
}
@@ -4647,7 +4701,8 @@ fn finishTransFnProto(
const name_tok = if (fn_decl_context) |ctx| try appendIdentifier(rp.c, ctx.fn_name) else null;
const lparen_tok = try appendToken(rp.c, .LParen, "(");
- var fn_params = ast.Node.FnProto.ParamList.init(rp.c.a());
+ var fn_params = ast.Node.FnProto.ParamList{};
+ var fn_params_list = rp.c.llpusher(&fn_params);
const param_count: usize = if (fn_proto_ty != null) ZigClangFunctionProtoType_getNumParams(fn_proto_ty.?) else 0;
var i: usize = 0;
@@ -4672,7 +4727,7 @@ fn finishTransFnProto(
const type_node = try transQualType(rp, param_qt, source_loc);
- const param_node = try rp.c.a().create(ast.Node.ParamDecl);
+ const param_node = try rp.c.arena.create(ast.Node.ParamDecl);
param_node.* = .{
.doc_comments = null,
.comptime_token = null,
@@ -4680,7 +4735,7 @@ fn finishTransFnProto(
.name_token = param_name_tok,
.param_type = .{ .type_expr = type_node },
};
- try fn_params.push(¶m_node.base);
+ try fn_params_list.push(¶m_node.base);
if (i + 1 < param_count) {
_ = try appendToken(rp.c, .Comma, ",");
@@ -4692,7 +4747,7 @@ fn finishTransFnProto(
_ = try appendToken(rp.c, .Comma, ",");
}
- const var_arg_node = try rp.c.a().create(ast.Node.ParamDecl);
+ const var_arg_node = try rp.c.arena.create(ast.Node.ParamDecl);
var_arg_node.* = .{
.doc_comments = null,
.comptime_token = null,
@@ -4700,7 +4755,7 @@ fn finishTransFnProto(
.name_token = null,
.param_type = .{ .var_args = try appendToken(rp.c, .Ellipsis3, "...") }
};
- try fn_params.push(&var_arg_node.base);
+ try fn_params_list.push(&var_arg_node.base);
}
const rparen_tok = try appendToken(rp.c, .RParen, ")");
@@ -4713,7 +4768,7 @@ fn finishTransFnProto(
_ = try appendToken(rp.c, .LParen, "(");
const expr = try transCreateNodeStringLiteral(
rp.c,
- try std.fmt.allocPrint(rp.c.a(), "\"{}\"", .{str_ptr[0..str_len]}),
+ try std.fmt.allocPrint(rp.c.arena, "\"{}\"", .{str_ptr[0..str_len]}),
);
_ = try appendToken(rp.c, .RParen, ")");
@@ -4767,7 +4822,7 @@ fn finishTransFnProto(
}
};
- const fn_proto = try rp.c.a().create(ast.Node.FnProto);
+ const fn_proto = try rp.c.arena.create(ast.Node.FnProto);
fn_proto.* = .{
.doc_comments = null,
.visib_token = pub_tok,
@@ -4816,20 +4871,21 @@ pub fn failDecl(c: *Context, loc: ZigClangSourceLocation, name: []const u8, comp
const semi_tok = try appendToken(c, .Semicolon, ";");
_ = try appendTokenFmt(c, .LineComment, "// {}", .{c.locStr(loc)});
- const msg_node = try c.a().create(ast.Node.StringLiteral);
+ const msg_node = try c.arena.create(ast.Node.StringLiteral);
msg_node.* = .{
.token = msg_tok,
};
- const call_node = try c.a().create(ast.Node.BuiltinCall);
+ const call_node = try c.arena.create(ast.Node.BuiltinCall);
call_node.* = .{
.builtin_token = builtin_tok,
- .params = ast.Node.BuiltinCall.ParamList.init(c.a()),
+ .params = ast.Node.BuiltinCall.ParamList{},
.rparen_token = rparen_tok,
};
- try call_node.params.push(&msg_node.base);
+ var call_params_it = &call_node.params.first;
+ call_params_it = try c.llpush(*ast.Node, call_params_it, &msg_node.base);
- const var_decl_node = try c.a().create(ast.Node.VarDecl);
+ const var_decl_node = try c.arena.create(ast.Node.VarDecl);
var_decl_node.* = .{
.doc_comments = null,
.visib_token = pub_tok,
@@ -4861,9 +4917,9 @@ fn appendTokenFmt(c: *Context, token_id: Token.Id, comptime format: []const u8,
try c.source_buffer.outStream().print(format, args);
const end_index = c.source_buffer.items.len;
- const token_index = c.tree.tokens.len;
- const new_token = try c.tree.tokens.addOne();
- errdefer c.tree.tokens.shrink(token_index);
+ const token_index = c.tokens.items.len;
+ const new_token = try c.tokens.addOne(c.gpa);
+ errdefer c.tokens.shrink(c.gpa, token_index);
new_token.* = .{
.id = token_id,
@@ -4931,7 +4987,7 @@ fn appendIdentifier(c: *Context, name: []const u8) !ast.TokenIndex {
fn transCreateNodeIdentifier(c: *Context, name: []const u8) !*ast.Node {
const token_index = try appendIdentifier(c, name);
- const identifier = try c.a().create(ast.Node.Identifier);
+ const identifier = try c.arena.create(ast.Node.Identifier);
identifier.* = .{
.token = token_index,
};
@@ -4940,7 +4996,7 @@ fn transCreateNodeIdentifier(c: *Context, name: []const u8) !*ast.Node {
fn transCreateNodeIdentifierUnchecked(c: *Context, name: []const u8) !*ast.Node {
const token_index = try appendTokenFmt(c, .Identifier, "{}", .{name});
- const identifier = try c.a().create(ast.Node.Identifier);
+ const identifier = try c.arena.create(ast.Node.Identifier);
identifier.* = .{
.token = token_index,
};
@@ -4955,7 +5011,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
// TODO if we see #undef, delete it from the table
var it = ZigClangASTUnit_getLocalPreprocessingEntities_begin(unit);
const it_end = ZigClangASTUnit_getLocalPreprocessingEntities_end(unit);
- var tok_list = CTokenList.init(c.a());
+ var tok_list = CTokenList.init(c.arena);
const scope = c.global_scope;
while (it.I != it_end.I) : (it.I += 1) {
@@ -4970,7 +5026,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void {
const name = try c.str(raw_name);
// TODO https://github.com/ziglang/zig/issues/3756
// TODO https://github.com/ziglang/zig/issues/1802
- const mangled_name = if (isZigPrimitiveType(name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ name, c.getMangle() }) else name;
+ const mangled_name = if (isZigPrimitiveType(name)) try std.fmt.allocPrint(c.arena, "{}_{}", .{ name, c.getMangle() }) else name;
if (scope.containsNow(mangled_name)) {
continue;
}
@@ -5078,7 +5134,8 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
.{},
);
}
- var fn_params = ast.Node.FnProto.ParamList.init(c.a());
+ var fn_params = ast.Node.FnProto.ParamList{};
+ var fn_params_it = &fn_params.first;
while (true) {
const param_tok = it.next().?;
if (param_tok.id != .Identifier) {
@@ -5096,12 +5153,12 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
_ = try appendToken(c, .Colon, ":");
const token_index = try appendToken(c, .Keyword_var, "var");
- const identifier = try c.a().create(ast.Node.Identifier);
+ const identifier = try c.arena.create(ast.Node.Identifier);
identifier.* = .{
.token = token_index,
};
- const param_node = try c.a().create(ast.Node.ParamDecl);
+ const param_node = try c.arena.create(ast.Node.ParamDecl);
param_node.* = .{
.doc_comments = null,
.comptime_token = null,
@@ -5109,7 +5166,7 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
.name_token = param_name_tok,
.param_type = .{ .type_expr = &identifier.base },
};
- try fn_params.push(¶m_node.base);
+ fn_params_it = try c.llpush(*ast.Node, fn_params_it, ¶m_node.base);
if (it.peek().?.id != .Comma)
break;
@@ -5131,8 +5188,9 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
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 fn_proto = try c.a().create(ast.Node.FnProto);
+ const fn_proto = try c.arena.create(ast.Node.FnProto);
fn_proto.* = .{
.visib_token = pub_tok,
.extern_export_inline_token = inline_tok,
@@ -5150,6 +5208,7 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
};
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);
@@ -5165,16 +5224,16 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
_ = try appendToken(c, .Semicolon, ";");
const type_of_arg = if (expr.id != .Block) expr else blk: {
const blk = @fieldParentPtr(ast.Node.Block, "base", expr);
- const blk_last = blk.statements.at(blk.statements.len - 1).*;
+ const blk_last = blk.statements.first.?.findLast().data;
std.debug.assert(blk_last.id == .ControlFlowExpression);
const br = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", blk_last);
break :blk br.rhs.?;
};
- try type_of.params.push(type_of_arg);
+ try type_of_params.push(type_of_arg);
return_expr.rhs = expr;
block.rbrace = try appendToken(c, .RBrace, "}");
- try block.statements.push(&return_expr.base);
+ try block_statements.push(&return_expr.base);
fn_proto.body_node = &block.base;
_ = try c.global_scope.macro_table.put(name, &fn_proto.base);
}
@@ -5208,14 +5267,14 @@ 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.block_node = try transCreateNodeBlock(c, block_scope.label);
+ block_scope.setBlockNode(try transCreateNodeBlock(c, block_scope.label));
var last = node;
while (true) {
// suppress result
const lhs = try transCreateNodeIdentifier(c, "_");
const op_token = try appendToken(c, .Equal, "=");
- const op_node = try c.a().create(ast.Node.InfixOp);
+ const op_node = try c.arena.create(ast.Node.InfixOp);
op_node.* = .{
.op_token = op_token,
.lhs = lhs,
@@ -5253,11 +5312,11 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl
switch (lit_bytes[1]) {
'0'...'7' => {
// Octal
- lit_bytes = try std.fmt.allocPrint(c.a(), "0o{}", .{lit_bytes});
+ lit_bytes = try std.fmt.allocPrint(c.arena, "0o{}", .{lit_bytes});
},
'X' => {
// Hexadecimal with capital X, valid in C but not in Zig
- lit_bytes = try std.fmt.allocPrint(c.a(), "0x{}", .{lit_bytes[2..]});
+ lit_bytes = try std.fmt.allocPrint(c.arena, "0x{}", .{lit_bytes[2..]});
},
else => {},
}
@@ -5288,7 +5347,7 @@ fn parseCNumLit(c: *Context, tok: *CToken, source: []const u8, source_loc: ZigCl
return &cast_node.base;
} else if (tok.id == .FloatLiteral) {
if (lit_bytes[0] == '.')
- lit_bytes = try std.fmt.allocPrint(c.a(), "0{}", .{lit_bytes});
+ lit_bytes = try std.fmt.allocPrint(c.arena, "0{}", .{lit_bytes});
if (tok.id.FloatLiteral == .None) {
return transCreateNodeFloat(c, lit_bytes);
}
@@ -5318,7 +5377,7 @@ fn zigifyEscapeSequences(ctx: *Context, source_bytes: []const u8, name: []const
break;
}
} else return source;
- var bytes = try ctx.a().alloc(u8, source.len * 2);
+ var bytes = try ctx.arena.alloc(u8, source.len * 2);
var state: enum {
Start,
Escape,
@@ -5472,14 +5531,14 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
const first_tok = it.list.at(0);
if (source[tok.start] != '\'' or source[tok.start + 1] == '\\' or tok.end - tok.start == 3) {
const token = try appendToken(c, .CharLiteral, try zigifyEscapeSequences(c, source[tok.start..tok.end], source[first_tok.start..first_tok.end], source_loc));
- const node = try c.a().create(ast.Node.CharLiteral);
+ const node = try c.arena.create(ast.Node.CharLiteral);
node.* = .{
.token = token,
};
return &node.base;
} else {
const token = try appendTokenFmt(c, .IntegerLiteral, "0x{x}", .{source[tok.start+1..tok.end-1]});
- const node = try c.a().create(ast.Node.IntegerLiteral);
+ const node = try c.arena.create(ast.Node.IntegerLiteral);
node.* = .{
.token = token,
};
@@ -5489,7 +5548,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
.StringLiteral => {
const first_tok = it.list.at(0);
const token = try appendToken(c, .StringLiteral, try zigifyEscapeSequences(c, source[tok.start..tok.end], source[first_tok.start..first_tok.end], source_loc));
- const node = try c.a().create(ast.Node.StringLiteral);
+ const node = try c.arena.create(ast.Node.StringLiteral);
node.* = .{
.token = token,
};
@@ -5572,7 +5631,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
const type_info_node = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
try type_info_node.params.push(inner_node);
type_info_node.rparen_token = try appendToken(c, .LParen, ")");
- const cmp_node = try c.a().create(ast.Node.InfixOp);
+ const cmp_node = try c.arena.create(ast.Node.InfixOp);
cmp_node.* = .{
.op_token = try appendToken(c, .EqualEqual, "=="),
.lhs = &type_info_node.base,
@@ -5597,7 +5656,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
as_node.rparen_token = try appendToken(c, .RParen, ")");
else_node.body = &as_node.base;
- const group_node = try c.a().create(ast.Node.GroupedExpression);
+ const group_node = try c.arena.create(ast.Node.GroupedExpression);
group_node.* = .{
.lparen = lparen,
.expr = &if_node.base,
@@ -5621,7 +5680,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
type_of_1.rparen_token = try appendToken(c, .RParen, ")");
type_info_1.rparen_token = try appendToken(c, .RParen, ")");
- const cmp_1 = try c.a().create(ast.Node.InfixOp);
+ const cmp_1 = try c.arena.create(ast.Node.InfixOp);
cmp_1.* = .{
.op_token = try appendToken(c, .EqualEqual, "=="),
.lhs = &type_info_1.base,
@@ -5633,7 +5692,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
const period_tok = try appendToken(c, .Period, ".");
const child_ident = try transCreateNodeIdentifier(c, "Child");
- const inner_node_child = try c.a().create(ast.Node.InfixOp);
+ const inner_node_child = try c.arena.create(ast.Node.InfixOp);
inner_node_child.* = .{
.op_token = period_tok,
.lhs = inner_node,
@@ -5669,7 +5728,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
type_of_2.rparen_token = try appendToken(c, .RParen, ")");
type_info_2.rparen_token = try appendToken(c, .RParen, ")");
- const cmp_2 = try c.a().create(ast.Node.InfixOp);
+ const cmp_2 = try c.arena.create(ast.Node.InfixOp);
cmp_2.* = .{
.op_token = try appendToken(c, .EqualEqual, "=="),
.lhs = &type_info_2.base,
@@ -5677,7 +5736,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
.rhs = try transCreateNodeEnumLiteral(c, "Int"),
};
if_2.condition = &cmp_2.base;
- const cmp_4 = try c.a().create(ast.Node.InfixOp);
+ const cmp_4 = try c.arena.create(ast.Node.InfixOp);
cmp_4.* = .{
.op_token = try appendToken(c, .Keyword_and, "and"),
.lhs = &cmp_2.base,
@@ -5687,7 +5746,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
const type_info_3 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
try type_info_3.params.push(inner_node);
type_info_3.rparen_token = try appendToken(c, .LParen, ")");
- const cmp_3 = try c.a().create(ast.Node.InfixOp);
+ const cmp_3 = try c.arena.create(ast.Node.InfixOp);
cmp_3.* = .{
.op_token = try appendToken(c, .EqualEqual, "=="),
.lhs = &type_info_3.base,
@@ -5714,7 +5773,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
as.rparen_token = try appendToken(c, .RParen, ")");
else_2.body = &as.base;
- const group_node = try c.a().create(ast.Node.GroupedExpression);
+ const group_node = try c.arena.create(ast.Node.GroupedExpression);
group_node.* = .{
.lparen = lparen,
.expr = &if_1.base,
@@ -5740,7 +5799,7 @@ fn macroBoolToInt(c: *Context, node: *ast.Node) !*ast.Node {
if (!isBoolRes(node)) {
if (node.id != .InfixOp) return node;
- const group_node = try c.a().create(ast.Node.GroupedExpression);
+ const group_node = try c.arena.create(ast.Node.GroupedExpression);
group_node.* = .{
.lparen = try appendToken(c, .LParen, "("),
.expr = node,
@@ -5759,7 +5818,7 @@ fn macroIntToBool(c: *Context, node: *ast.Node) !*ast.Node {
if (isBoolRes(node)) {
if (node.id != .InfixOp) return node;
- const group_node = try c.a().create(ast.Node.GroupedExpression);
+ const group_node = try c.arena.create(ast.Node.GroupedExpression);
group_node.* = .{
.lparen = try appendToken(c, .LParen, "("),
.expr = node,
@@ -5770,14 +5829,14 @@ fn macroIntToBool(c: *Context, node: *ast.Node) !*ast.Node {
const op_token = try appendToken(c, .BangEqual, "!=");
const zero = try transCreateNodeInt(c, 0);
- const res = try c.a().create(ast.Node.InfixOp);
+ const res = try c.arena.create(ast.Node.InfixOp);
res.* = .{
.op_token = op_token,
.lhs = node,
.op = .BangEqual,
.rhs = zero,
};
- const group_node = try c.a().create(ast.Node.GroupedExpression);
+ const group_node = try c.arena.create(ast.Node.GroupedExpression);
group_node.* = .{
.lparen = try appendToken(c, .LParen, "("),
.expr = &res.base,
@@ -5989,7 +6048,7 @@ fn parseCSuffixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
const cast_fn = if (bool_op) macroIntToBool else macroBoolToInt;
const lhs_node = try cast_fn(c, node);
const rhs_node = try parseCPrefixOpExpr(c, it, source, source_loc, scope);
- const op_node = try c.a().create(ast.Node.InfixOp);
+ const op_node = try c.arena.create(ast.Node.InfixOp);
op_node.* = .{
.op_token = op_token,
.lhs = lhs_node,
@@ -6037,7 +6096,7 @@ fn parseCPrefixOpExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
}
fn tokenSlice(c: *Context, token: ast.TokenIndex) []u8 {
- const tok = c.tree.tokens.at(token);
+ const tok = c.tokens.items[token];
const slice = c.source_buffer.span()[tok.start..tok.end];
return if (mem.startsWith(u8, slice, "@\""))
slice[2 .. slice.len - 1]
@@ -6060,9 +6119,10 @@ fn getContainer(c: *Context, node: *ast.Node) ?*ast.Node {
return null;
if (getContainerTypeOf(c, infix.lhs)) |ty_node| {
if (ty_node.cast(ast.Node.ContainerDecl)) |container| {
- var it = container.fields_and_decls.iterator(0);
- while (it.next()) |field_ref| {
- const field = field_ref.*.cast(ast.Node.ContainerField).?;
+ var it = container.fields_and_decls.first;
+ while (it) |field_ref_node| : (it = field_ref_node.next) {
+ const field_ref = field_ref_node.data;
+ const field = field_ref.cast(ast.Node.ContainerField).?;
const ident = infix.rhs.cast(ast.Node.Identifier).?;
if (mem.eql(u8, tokenSlice(c, field.name_token), tokenSlice(c, ident.token))) {
return getContainer(c, field.type_expr.?);
@@ -6087,9 +6147,10 @@ fn getContainerTypeOf(c: *Context, ref: *ast.Node) ?*ast.Node {
return null;
if (getContainerTypeOf(c, infix.lhs)) |ty_node| {
if (ty_node.cast(ast.Node.ContainerDecl)) |container| {
- var it = container.fields_and_decls.iterator(0);
- while (it.next()) |field_ref| {
- const field = field_ref.*.cast(ast.Node.ContainerField).?;
+ var it = container.fields_and_decls.first;
+ while (it) |field_ref_node| : (it = field_ref_node.next) {
+ const field_ref = field_ref_node.data;
+ const field = field_ref.cast(ast.Node.ContainerField).?;
const ident = infix.rhs.cast(ast.Node.Identifier).?;
if (mem.eql(u8, tokenSlice(c, field.name_token), tokenSlice(c, ident.token))) {
return getContainer(c, field.type_expr.?);