aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-04-26 20:41:07 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-04-26 20:41:07 -0700
commitbfded492f0c12be2778c566bad0c82dea6ee76cb (patch)
tree0942c1ca40f40fe371504fd4818535a9b73f90e5 /src/Sema.zig
parent91c317bb9aa906684104db3d73442ab1198a83f4 (diff)
downloadzig-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.zig78
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;