diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-04-30 11:07:31 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-04-30 11:07:31 -0700 |
| commit | 2d8d681b5ee34663aa87f0583f7b1a012b17d5b4 (patch) | |
| tree | fefb28fbbdc9ab0c94c41a8609402077307ce024 /src/Sema.zig | |
| parent | 5d696b0706de2ac267cb774ef39e0d81131d5c38 (diff) | |
| download | zig-2d8d681b5ee34663aa87f0583f7b1a012b17d5b4.tar.gz zig-2d8d681b5ee34663aa87f0583f7b1a012b17d5b4.zip | |
stage2: un-tangle memory management of Decl and Namespace
Before there was this "top_decl" and "tmp_namespace" stack values that
were kludgy and buggy. Now Sema is slightly reworked so that files which
are structs are analyzed with their own Decl and Namespace already set
up.
After this commit there are no memory leaks for a successful build-obj.
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 76 |
1 files changed, 47 insertions, 29 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index d1893a82f9..bb9a608b7c 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -634,15 +634,19 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) In return sema.mod.fail(&block.base, sema.src, "TODO implement zirCoerceResultPtr", .{}); } -pub fn zirStructDecl( +pub fn analyzeStructDecl( sema: *Sema, block: *Scope.Block, + new_decl_arena: *std.heap.ArenaAllocator, + new_decl: *Decl, inst: Zir.Inst.Index, layout: std.builtin.TypeInfo.ContainerLayout, -) InnerError!*Inst { + struct_obj: *Module.Struct, +) InnerError!void { const tracy = trace(@src()); defer tracy.end(); + const mod = sema.mod; const gpa = sema.gpa; const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); @@ -650,27 +654,7 @@ pub fn zirStructDecl( const fields_len = extra.data.fields_len; const decls_len = extra.data.decls_len; - var new_decl_arena = std.heap.ArenaAllocator.init(gpa); - - const struct_obj = try new_decl_arena.allocator.create(Module.Struct); - const struct_ty = try Type.Tag.@"struct".create(&new_decl_arena.allocator, struct_obj); - const struct_val = try Value.Tag.ty.create(&new_decl_arena.allocator, struct_ty); - const new_decl = try sema.mod.createAnonymousDecl(&block.base, &new_decl_arena, .{ - .ty = Type.initTag(.type), - .val = struct_val, - }); - struct_obj.* = .{ - .owner_decl = sema.owner_decl, - .fields = .{}, - .node_offset = inst_data.src_node, - .namespace = .{ - .parent = sema.owner_decl.namespace, - .ty = struct_ty, - .file_scope = block.getFileScope(), - }, - }; - - var extra_index: usize = try sema.mod.scanNamespace( + var extra_index: usize = try mod.scanNamespace( &struct_obj.namespace, extra.end, decls_len, @@ -680,7 +664,7 @@ pub fn zirStructDecl( const body = sema.code.extra[extra_index..][0..extra.data.body_len]; if (fields_len == 0) { assert(body.len == 0); - return sema.analyzeDeclVal(block, src, new_decl); + return; } try struct_obj.fields.ensureCapacity(&new_decl_arena.allocator, fields_len); @@ -691,7 +675,7 @@ pub fn zirStructDecl( // Within the field type, default value, and alignment expressions, the "owner decl" // should be the struct itself. Thus we need a new Sema. var struct_sema: Sema = .{ - .mod = sema.mod, + .mod = mod, .gpa = gpa, .arena = &new_decl_arena.allocator, .code = sema.code, @@ -752,7 +736,7 @@ pub fn zirStructDecl( // This string needs to outlive the ZIR code. const field_name = try new_decl_arena.allocator.dupe(u8, field_name_zir); if (field_type_ref == .none) { - return sema.mod.fail(&block.base, src, "TODO: implement anytype struct field", .{}); + return mod.fail(&block.base, src, "TODO: implement anytype struct field", .{}); } const field_ty: Type = if (field_type_ref == .none) Type.initTag(.noreturn) @@ -788,7 +772,38 @@ pub fn zirStructDecl( gop.entry.value.default_val = (try sema.resolveInstConst(block, src, default_ref)).val; } } +} + +fn zirStructDecl( + sema: *Sema, + block: *Scope.Block, + inst: Zir.Inst.Index, + layout: std.builtin.TypeInfo.ContainerLayout, +) InnerError!*Inst { + const inst_data = sema.code.instructions.items(.data)[inst].pl_node; + const src = inst_data.src(); + + var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); + const struct_obj = try new_decl_arena.allocator.create(Module.Struct); + const struct_ty = try Type.Tag.@"struct".create(&new_decl_arena.allocator, struct_obj); + const struct_val = try Value.Tag.ty.create(&new_decl_arena.allocator, struct_ty); + const new_decl = try sema.mod.createAnonymousDecl(&block.base, .{ + .ty = Type.initTag(.type), + .val = struct_val, + }); + struct_obj.* = .{ + .owner_decl = sema.owner_decl, + .fields = .{}, + .node_offset = inst_data.src_node, + .namespace = .{ + .parent = sema.owner_decl.namespace, + .ty = struct_ty, + .file_scope = block.getFileScope(), + }, + }; + try sema.analyzeStructDecl(block, &new_decl_arena, new_decl, inst, layout, struct_obj); + try new_decl.finalizeNewArena(&new_decl_arena); return sema.analyzeDeclVal(block, src, new_decl); } @@ -822,14 +837,14 @@ fn zirEnumDecl( }; const enum_obj = try new_decl_arena.allocator.create(Module.EnumFull); - const enum_ty_payload = try gpa.create(Type.Payload.EnumFull); + const enum_ty_payload = try new_decl_arena.allocator.create(Type.Payload.EnumFull); enum_ty_payload.* = .{ .base = .{ .tag = if (nonexhaustive) .enum_nonexhaustive else .enum_full }, .data = enum_obj, }; const enum_ty = Type.initPayload(&enum_ty_payload.base); const enum_val = try Value.Tag.ty.create(&new_decl_arena.allocator, enum_ty); - const new_decl = try sema.mod.createAnonymousDecl(&block.base, &new_decl_arena, .{ + const new_decl = try sema.mod.createAnonymousDecl(&block.base, .{ .ty = Type.initTag(.type), .val = enum_val, }); @@ -856,6 +871,7 @@ fn zirEnumDecl( const body = sema.code.extra[extra_index..][0..extra.data.body_len]; if (fields_len == 0) { assert(body.len == 0); + try new_decl.finalizeNewArena(&new_decl_arena); return sema.analyzeDeclVal(block, src, new_decl); } @@ -942,6 +958,7 @@ fn zirEnumDecl( } } + try new_decl.finalizeNewArena(&new_decl_arena); return sema.analyzeDeclVal(block, src, new_decl); } @@ -1424,10 +1441,11 @@ fn zirStr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*In const decl_ty = try Type.Tag.array_u8_sentinel_0.create(&new_decl_arena.allocator, bytes.len); const decl_val = try Value.Tag.bytes.create(&new_decl_arena.allocator, bytes); - const new_decl = try sema.mod.createAnonymousDecl(&block.base, &new_decl_arena, .{ + const new_decl = try sema.mod.createAnonymousDecl(&block.base, .{ .ty = decl_ty, .val = decl_val, }); + try new_decl.finalizeNewArena(&new_decl_arena); return sema.analyzeDeclRef(block, .unneeded, new_decl); } |
