Merge remote-tracking branch 'origin/master' into ast-memory-layout

Conflicts:
 * lib/std/zig/ast.zig
 * lib/std/zig/parse.zig
 * lib/std/zig/parser_test.zig
 * lib/std/zig/render.zig
 * src/Module.zig
 * src/zir.zig

I resolved some of the conflicts by reverting a small portion of
@tadeokondrak's stage2 logic here regarding `callconv(.Inline)`.
It will need to get reworked as part of this branch.
This commit is contained in:
Andrew Kelley
2021-02-11 23:45:40 -07:00
696 changed files with 36716 additions and 2738 deletions

View File

@@ -375,6 +375,10 @@ pub const Scope = struct {
}
}
pub fn isComptime(self: *Scope) bool {
return self.getGenZIR().force_comptime;
}
pub fn ownerDecl(self: *Scope) ?*Decl {
return switch (self.tag) {
.block => self.cast(Block).?.owner_decl,
@@ -669,14 +673,36 @@ pub const Scope = struct {
};
pub const Merges = struct {
results: ArrayListUnmanaged(*Inst),
block_inst: *Inst.Block,
/// Separate array list from break_inst_list so that it can be passed directly
/// to resolvePeerTypes.
results: ArrayListUnmanaged(*Inst),
/// Keeps track of the break instructions so that the operand can be replaced
/// if we need to add type coercion at the end of block analysis.
/// Same indexes, capacity, length as `results`.
br_list: ArrayListUnmanaged(*Inst.Br),
};
/// For debugging purposes.
pub fn dump(self: *Block, mod: Module) void {
zir.dumpBlock(mod, self);
}
pub fn makeSubBlock(parent: *Block) Block {
return .{
.parent = parent,
.inst_table = parent.inst_table,
.func = parent.func,
.owner_decl = parent.owner_decl,
.src_decl = parent.src_decl,
.instructions = .{},
.arena = parent.arena,
.label = null,
.inlining = parent.inlining,
.is_comptime = parent.is_comptime,
.branch_quota = parent.branch_quota,
};
}
};
/// This is a temporary structure, references to it are valid only
@@ -688,13 +714,32 @@ pub const Scope = struct {
parent: *Scope,
decl: *Decl,
arena: *Allocator,
force_comptime: bool,
/// The first N instructions in a function body ZIR are arg instructions.
instructions: std.ArrayListUnmanaged(*zir.Inst) = .{},
label: ?Label = null,
break_block: ?*zir.Inst.Block = null,
continue_block: ?*zir.Inst.Block = null,
/// only valid if label != null or (continue_block and break_block) != null
/// Only valid when setBlockResultLoc is called.
break_result_loc: astgen.ResultLoc = undefined,
/// When a block has a pointer result location, here it is.
rl_ptr: ?*zir.Inst = null,
/// Keeps track of how many branches of a block did not actually
/// consume the result location. astgen uses this to figure out
/// whether to rely on break instructions or writing to the result
/// pointer for the result instruction.
rvalue_rl_count: usize = 0,
/// Keeps track of how many break instructions there are. When astgen is finished
/// with a block, it can check this against rvalue_rl_count to find out whether
/// the break instructions should be downgraded to break_void.
break_count: usize = 0,
/// Tracks `break :foo bar` instructions so they can possibly be elided later if
/// the labeled block ends up not needing a result location pointer.
labeled_breaks: std.ArrayListUnmanaged(*zir.Inst.Break) = .{},
/// Tracks `store_to_block_ptr` instructions that correspond to break instructions
/// so they can possibly be elided later if the labeled block ends up not needing
/// a result location pointer.
labeled_store_to_block_ptr_list: std.ArrayListUnmanaged(*zir.Inst.BinOp) = .{},
pub const Label = struct {
token: ast.TokenIndex,
@@ -1000,6 +1045,7 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
.decl = decl,
.arena = &analysis_arena.allocator,
.parent = &decl.container.base,
.force_comptime = true,
};
defer gen_scope.instructions.deinit(self.gpa);
@@ -2121,6 +2167,7 @@ fn allocateNewDecl(
.macho => .{ .macho = link.File.MachO.TextBlock.empty },
.c => .{ .c = link.File.C.DeclBlock.empty },
.wasm => .{ .wasm = {} },
.spirv => .{ .spirv = {} },
},
.fn_link = switch (mod.comp.bin_file.tag) {
.coff => .{ .coff = {} },
@@ -2128,6 +2175,7 @@ fn allocateNewDecl(
.macho => .{ .macho = link.File.MachO.SrcFn.empty },
.c => .{ .c = link.File.C.FnBlock.empty },
.wasm => .{ .wasm = null },
.spirv => .{ .spirv = .{} },
},
.generation = 0,
.is_pub = false,
@@ -2225,6 +2273,7 @@ pub fn analyzeExport(
.macho => .{ .macho = link.File.MachO.Export{} },
.c => .{ .c = {} },
.wasm => .{ .wasm = {} },
.spirv => .{ .spirv = {} },
},
.owner_decl = owner_decl,
.exported_decl = exported_decl,
@@ -2366,7 +2415,7 @@ pub fn addBr(
src: usize,
target_block: *Inst.Block,
operand: *Inst,
) !*Inst {
) !*Inst.Br {
const inst = try scope_block.arena.create(Inst.Br);
inst.* = .{
.base = .{
@@ -2378,7 +2427,7 @@ pub fn addBr(
.block = target_block,
};
try scope_block.instructions.append(self.gpa, &inst.base);
return &inst.base;
return inst;
}
pub fn addCondBr(
@@ -2430,7 +2479,7 @@ pub fn addSwitchBr(
self: *Module,
block: *Scope.Block,
src: usize,
target_ptr: *Inst,
target: *Inst,
cases: []Inst.SwitchBr.Case,
else_body: ir.Body,
) !*Inst {
@@ -2441,7 +2490,7 @@ pub fn addSwitchBr(
.ty = Type.initTag(.noreturn),
.src = src,
},
.target_ptr = target_ptr,
.target = target,
.cases = cases,
.else_body = else_body,
};
@@ -3733,18 +3782,18 @@ pub fn addSafetyCheck(mod: *Module, parent_block: *Scope.Block, ok: *Inst, panic
};
const ok_body: ir.Body = .{
.instructions = try parent_block.arena.alloc(*Inst, 1), // Only need space for the brvoid.
.instructions = try parent_block.arena.alloc(*Inst, 1), // Only need space for the br_void.
};
const brvoid = try parent_block.arena.create(Inst.BrVoid);
brvoid.* = .{
const br_void = try parent_block.arena.create(Inst.BrVoid);
br_void.* = .{
.base = .{
.tag = .brvoid,
.tag = .br_void,
.ty = Type.initTag(.noreturn),
.src = ok.src,
},
.block = block_inst,
};
ok_body.instructions[0] = &brvoid.base;
ok_body.instructions[0] = &br_void.base;
var fail_block: Scope.Block = .{
.parent = parent_block,