diff --git a/src/AstGen.zig b/src/AstGen.zig index 24a73539b3..387364cb82 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -2567,7 +2567,11 @@ fn varDecl( for (init_scope.instructions.items) |src_inst| { if (zir_tags[src_inst] == .store_to_block_ptr) { if (zir_datas[src_inst].bin.lhs == init_scope.rl_ptr) { - zir_tags[src_inst] = .store_to_inferred_ptr; + if (var_decl.ast.type_node != 0) { + zir_tags[src_inst] = .store; + } else { + zir_tags[src_inst] = .store_to_inferred_ptr; + } } } parent_zir.appendAssumeCapacity(src_inst); diff --git a/src/Compilation.zig b/src/Compilation.zig index ef762dae1e..cb19a21c15 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1574,10 +1574,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { // also test the use case of `build-obj -fcompiler-rt` with the self-hosted compiler // and make sure the compiler-rt symbols are emitted. Currently this is hooked up for // stage1 but not stage2. - const capable_of_building_compiler_rt = comp.bin_file.options.use_stage1; - const capable_of_building_ssp = comp.bin_file.options.use_stage1; + const capable_of_building_compiler_rt = comp.bin_file.options.use_stage1 or + comp.bin_file.options.use_llvm; const capable_of_building_zig_libc = comp.bin_file.options.use_stage1 or comp.bin_file.options.use_llvm; + const capable_of_building_ssp = comp.bin_file.options.use_stage1; if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) { if (is_exe_or_dyn_lib) { @@ -1648,6 +1649,9 @@ pub fn destroy(self: *Compilation) void { if (self.compiler_rt_static_lib) |*crt_file| { crt_file.deinit(gpa); } + if (self.compiler_rt_obj) |*crt_file| { + crt_file.deinit(gpa); + } if (self.libssp_static_lib) |*crt_file| { crt_file.deinit(gpa); } @@ -3977,6 +3981,7 @@ fn buildOutputFromZig( }, .root_src_path = src_basename, }; + defer main_pkg.deinitTable(comp.gpa); const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len]; const target = comp.getTarget(); const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{ diff --git a/src/Package.zig b/src/Package.zig index 3814f0eb95..f5380aaacb 100644 --- a/src/Package.zig +++ b/src/Package.zig @@ -99,15 +99,18 @@ pub fn destroy(pkg: *Package, gpa: *Allocator) void { } } - { - var it = pkg.table.keyIterator(); - while (it.next()) |key| { - gpa.free(key.*); - } + pkg.deinitTable(gpa); + gpa.destroy(pkg); +} + +/// Only frees memory associated with the table. +pub fn deinitTable(pkg: *Package, gpa: *Allocator) void { + var it = pkg.table.keyIterator(); + while (it.next()) |key| { + gpa.free(key.*); } pkg.table.deinit(gpa); - gpa.destroy(pkg); } pub fn add(pkg: *Package, gpa: *Allocator, name: []const u8, package: *Package) !void { diff --git a/src/Sema.zig b/src/Sema.zig index 51ebb496f3..53d7a9f4a2 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1587,7 +1587,42 @@ fn zirAllocExtended( ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand); const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; - return sema.mod.fail(&block.base, src, "TODO implement Sema.zirAllocExtended", .{}); + const ty_src = src; // TODO better source location + const align_src = src; // TODO better source location + const small = @bitCast(Zir.Inst.AllocExtended.Small, extended.small); + + var extra_index: usize = extra.end; + + const var_ty: Type = if (small.has_type) blk: { + const type_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); + extra_index += 1; + break :blk try sema.resolveType(block, ty_src, type_ref); + } else { + return sema.mod.fail(&block.base, src, "TODO implement Sema.zirAllocExtended inferred", .{}); + }; + + const alignment: u16 = if (small.has_align) blk: { + const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); + extra_index += 1; + const alignment = try sema.resolveAlign(block, align_src, align_ref); + break :blk alignment; + } else 0; + + if (small.is_comptime) { + return sema.mod.fail(&block.base, src, "TODO implement Sema.zirAllocExtended comptime", .{}); + } + + if (!small.is_const) { + return sema.mod.fail(&block.base, src, "TODO implement Sema.zirAllocExtended var", .{}); + } + + const ptr_type = try Type.ptr(sema.arena, .{ + .pointee_type = var_ty, + .@"align" = alignment, + .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local), + }); + try sema.requireRuntimeBlock(block, src); + return block.addTy(.alloc, ptr_type); } fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -4620,7 +4655,8 @@ fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr return sema.mod.fail(&block.base, src, "unable to cast runtime value to 'comptime_int'", .{}); } - return sema.mod.fail(&block.base, src, "TODO implement analyze widen or shorten int", .{}); + try sema.requireRuntimeBlock(block, operand_src); + return block.addTyOp(.intcast, dest_type, operand); } fn zirBitcast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -8257,8 +8293,11 @@ fn zirFrameAddress( fn zirAlignOf(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; - const src = inst_data.src(); - return sema.mod.fail(&block.base, src, "TODO: Sema.zirAlignOf", .{}); + const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const ty = try sema.resolveType(block, operand_src, inst_data.operand); + const target = sema.mod.getTarget(); + const abi_align = ty.abiAlignment(target); + return sema.addIntUnsigned(Type.comptime_int, abi_align); } fn zirBoolToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { diff --git a/src/Zir.zig b/src/Zir.zig index 1da53a526e..e7359f9382 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -2878,6 +2878,14 @@ pub const Inst = struct { /// 1. align_inst: Ref, // if small 0b00X0 is set pub const AllocExtended = struct { src_node: i32, + + pub const Small = packed struct { + has_type: bool, + has_align: bool, + is_const: bool, + is_comptime: bool, + _: u12 = undefined, + }; }; pub const Export = struct { diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 6c3220d39e..cac475d445 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1284,7 +1284,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os; const compiler_rt_path: ?[]const u8 = if (self.base.options.include_compiler_rt) blk: { // TODO: remove when stage2 can build compiler_rt.zig - if (!build_options.is_stage1 or !self.base.options.use_stage1) break :blk null; + if (!self.base.options.use_llvm) break :blk null; // In the case of build-obj we include the compiler-rt symbols directly alongside // the symbols of the root source file, in the same compilation unit. diff --git a/src/print_zir.zig b/src/print_zir.zig index 5ffd6619af..54fd7e632f 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -393,6 +393,7 @@ const Writer = struct { .@"asm" => try self.writeAsm(stream, extended), .func => try self.writeFuncExtended(stream, extended), .variable => try self.writeVarExtended(stream, extended), + .alloc => try self.writeAllocExtended(stream, extended), .compile_log, .typeof_peer, @@ -423,7 +424,6 @@ const Writer = struct { try stream.writeByte(')'); }, - .alloc, .builtin_extern, .wasm_memory_size, .wasm_memory_grow, @@ -1767,6 +1767,30 @@ const Writer = struct { try stream.writeAll("))"); } + fn writeAllocExtended(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { + const extra = self.code.extraData(Zir.Inst.AllocExtended, extended.operand); + const small = @bitCast(Zir.Inst.AllocExtended.Small, extended.small); + const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; + + var extra_index: usize = extra.end; + const type_inst: Zir.Inst.Ref = if (!small.has_type) .none else blk: { + const type_inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]); + extra_index += 1; + break :blk type_inst; + }; + const align_inst: Zir.Inst.Ref = if (!small.has_align) .none else blk: { + const align_inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]); + extra_index += 1; + break :blk align_inst; + }; + try self.writeFlag(stream, ",is_const", small.is_const); + try self.writeFlag(stream, ",is_comptime", small.is_comptime); + try self.writeOptionalInstRef(stream, ",ty=", type_inst); + try self.writeOptionalInstRef(stream, ",align=", align_inst); + try stream.writeAll(")) "); + try self.writeSrc(stream, src); + } + fn writeBoolBr(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { const inst_data = self.code.instructions.items(.data)[inst].bool_br; const extra = self.code.extraData(Zir.Inst.Block, inst_data.payload_index); diff --git a/src/type.zig b/src/type.zig index cb2cc6d58a..2525aecef6 100644 --- a/src/type.zig +++ b/src/type.zig @@ -3866,6 +3866,7 @@ pub const Type = extern union { }; pub const @"bool" = initTag(.bool); + pub const @"comptime_int" = initTag(.comptime_int); pub fn ptr(arena: *Allocator, d: Payload.Pointer.Data) !Type { assert(d.host_size == 0 or d.bit_offset < d.host_size * 8);