diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-04-26 20:41:07 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-04-26 20:41:07 -0700 |
| commit | bfded492f0c12be2778c566bad0c82dea6ee76cb (patch) | |
| tree | 0942c1ca40f40fe371504fd4818535a9b73f90e5 /src/Sema.zig | |
| parent | 91c317bb9aa906684104db3d73442ab1198a83f4 (diff) | |
| download | zig-bfded492f0c12be2778c566bad0c82dea6ee76cb.tar.gz zig-bfded492f0c12be2778c566bad0c82dea6ee76cb.zip | |
stage2: rewire the frontend driver to whole-file-zir
* Remove some unused imports in AstGen.zig. I think it would make sense
to start decoupling AstGen from the rest of the compiler code,
similar to how the tokenizer and parser are decoupled.
* AstGen: For decls, move the block_inline instructions to the top of
the function so that they get lower ZIR instruction indexes. With
this, the block_inline instruction index combined with its corresponding
break_inline instruction index can be used to form a ZIR instruction
range. This is useful for allocating an array to map ZIR instructions
to semantically analyzed instructions.
* Module: extract emit-h functionality into a struct, and only allocate
it when emit-h is activated.
* Module: remove the `decl_table` field. This previously was a table of
all Decls in the entire Module. A "name hash" strategy was used to
find decls within a given namespace, using this global table. Now,
each Namespace has its own map of name to children Decls.
- Additionally, there were 3 places that relied on iterating over
decl_table in order to function:
- C backend and SPIR-V backend. These now have their own decl_table
that they keep populated when `updateDecl` and `removeDecl` are
called.
- emit-h. A `decl_table` field has been added to the new GlobalEmitH
struct which is only allocated when emit-h is activated.
* Module: fix ZIR serialization/deserialization bug in debug mode having
to do with the secret safety tag for untagged unions. There is still an
open TODO to investigate a friendlier solution to this problem with
the language.
* Module: improve deserialization of ZIR to allocate only exactly as
much capacity as length in the instructions array so as to not waste
space.
* Module: move `srcHashEql` to `std.zig` to live next to the definition
of `SrcHash` itself.
* Module: re-introduce the logic for scanning top level declarations
within a namespace.
* Compilation: add an `analyze_pkg` Job which is used to kick off the
start of semantic analysis by doing the equivalent of
`_ = @import("std");`. The `analyze_pkg` job is unconditionally added
to the work queue on every update(), with pkg set to the std lib pkg.
* Rename TZIR to AIR in a few places. A more comprehensive rename will
come later.
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 78 |
1 files changed, 21 insertions, 57 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 308e1d8859..7f53e976ed 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -655,7 +655,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) In return sema.mod.fail(&block.base, sema.src, "TODO implement zirCoerceResultPtr", .{}); } -fn zirStructDecl( +pub fn zirStructDecl( sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, @@ -668,8 +668,8 @@ fn zirStructDecl( const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); const extra = sema.code.extraData(Zir.Inst.StructDecl, inst_data.payload_index); - const body = sema.code.extra[extra.end..][0..extra.data.body_len]; const fields_len = extra.data.fields_len; + const decls_len = extra.data.decls_len; var new_decl_arena = std.heap.ArenaAllocator.init(gpa); @@ -686,37 +686,19 @@ fn zirStructDecl( .node_offset = inst_data.src_node, .namespace = .{ .parent = sema.owner_decl.namespace, - .parent_name_hash = new_decl.fullyQualifiedNameHash(), .ty = struct_ty, .file_scope = block.getFileScope(), }, }; - { - const ast = std.zig.ast; - const node = sema.owner_decl.relativeToNodeIndex(inst_data.src_node); - const tree: *const ast.Tree = &struct_obj.namespace.file_scope.tree; - const node_tags = tree.nodes.items(.tag); - var buf: [2]ast.Node.Index = undefined; - const members: []const ast.Node.Index = switch (node_tags[node]) { - .container_decl, - .container_decl_trailing, - => tree.containerDecl(node).ast.members, - - .container_decl_two, - .container_decl_two_trailing, - => tree.containerDeclTwo(&buf, node).ast.members, - - .container_decl_arg, - .container_decl_arg_trailing, - => tree.containerDeclArg(node).ast.members, - - .root => tree.rootDecls(), - else => unreachable, - }; - try sema.mod.analyzeNamespace(&struct_obj.namespace, members); - } + var extra_index: usize = try sema.mod.scanNamespace( + &struct_obj.namespace, + extra.end, + decls_len, + new_decl, + ); + 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); @@ -760,8 +742,8 @@ fn zirStructDecl( sema.branch_quota = struct_sema.branch_quota; } const bit_bags_count = std.math.divCeil(usize, fields_len, 16) catch unreachable; - const body_end = extra.end + body.len; - var extra_index: usize = body_end + bit_bags_count; + const body_end = extra_index + body.len; + extra_index += bit_bags_count; var bit_bag_index: usize = body_end; var cur_bit_bag: u32 = undefined; var field_i: u32 = 0; @@ -829,8 +811,8 @@ fn zirEnumDecl( const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); const extra = sema.code.extraData(Zir.Inst.EnumDecl, inst_data.payload_index); - const body = sema.code.extra[extra.end..][0..extra.data.body_len]; const fields_len = extra.data.fields_len; + const decls_len = extra.data.decls_len; var new_decl_arena = std.heap.ArenaAllocator.init(gpa); @@ -865,44 +847,27 @@ fn zirEnumDecl( .node_offset = inst_data.src_node, .namespace = .{ .parent = sema.owner_decl.namespace, - .parent_name_hash = new_decl.fullyQualifiedNameHash(), .ty = enum_ty, .file_scope = block.getFileScope(), }, }; - { - const ast = std.zig.ast; - const node = sema.owner_decl.relativeToNodeIndex(inst_data.src_node); - const tree: *const ast.Tree = &enum_obj.namespace.file_scope.tree; - const node_tags = tree.nodes.items(.tag); - var buf: [2]ast.Node.Index = undefined; - const members: []const ast.Node.Index = switch (node_tags[node]) { - .container_decl, - .container_decl_trailing, - => tree.containerDecl(node).ast.members, - - .container_decl_two, - .container_decl_two_trailing, - => tree.containerDeclTwo(&buf, node).ast.members, - - .container_decl_arg, - .container_decl_arg_trailing, - => tree.containerDeclArg(node).ast.members, - - .root => tree.rootDecls(), - else => unreachable, - }; - try sema.mod.analyzeNamespace(&enum_obj.namespace, members); - } + var extra_index: usize = try sema.mod.scanNamespace( + &enum_obj.namespace, + extra.end, + decls_len, + new_decl, + ); + 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); } const bit_bags_count = std.math.divCeil(usize, fields_len, 32) catch unreachable; - const body_end = extra.end + body.len; + const body_end = extra_index + body.len; + extra_index += bit_bags_count; try enum_obj.fields.ensureCapacity(&new_decl_arena.allocator, fields_len); const any_values = for (sema.code.extra[body_end..][0..bit_bags_count]) |bag| { @@ -947,7 +912,6 @@ fn zirEnumDecl( sema.branch_count = enum_sema.branch_count; sema.branch_quota = enum_sema.branch_quota; } - var extra_index: usize = body_end + bit_bags_count; var bit_bag_index: usize = body_end; var cur_bit_bag: u32 = undefined; var field_i: u32 = 0; |
