| author | |
| committer | |
| log | 578a792b33d1f26c839cd6c77eaa2680601caaf2 |
| tree | 1378c449be224c8b81fcb46ca4b1ad9097588c9b |
| parent | 3bfb1616db0883e6145a1fe1844eee3038bd4ca1 |
| parent | 101aac92c258af9f25520c36f06b2ce8335d7f9a |
| signature |
Make self hosted compiler capable of building itself12 files changed, 114 insertions(+), 38 deletions(-)
lib/std/c.zig+12-4| ... | @@ -219,7 +219,11 @@ pub extern "c" fn utimes(path: [*:0]const u8, times: *[2]c.timeval) c_int; | ... | @@ -219,7 +219,11 @@ pub extern "c" fn utimes(path: [*:0]const u8, times: *[2]c.timeval) c_int; |
| 219 | pub extern "c" fn utimensat(dirfd: c.fd_t, pathname: [*:0]const u8, times: *[2]c.timespec, flags: u32) c_int; | 219 | pub extern "c" fn utimensat(dirfd: c.fd_t, pathname: [*:0]const u8, times: *[2]c.timespec, flags: u32) c_int; |
| 220 | pub extern "c" fn futimens(fd: c.fd_t, times: *const [2]c.timespec) c_int; | 220 | pub extern "c" fn futimens(fd: c.fd_t, times: *const [2]c.timespec) c_int; |
| 221 | 221 | ||
| 222 | pub extern "c" fn pthread_create(noalias newthread: *pthread_t, noalias attr: ?*const c.pthread_attr_t, start_routine: fn (?*anyopaque) callconv(.C) ?*anyopaque, noalias arg: ?*anyopaque) c.E; | 222 | pub extern "c" fn pthread_create(noalias newthread: *pthread_t, noalias attr: ?*const c.pthread_attr_t, start_routine: PThreadStartFn, noalias arg: ?*anyopaque) c.E; |
| 223 | const PThreadStartFn = if (builtin.zig_backend == .stage1) | ||
| 224 | fn (?*anyopaque) callconv(.C) ?*anyopaque | ||
| 225 | else | ||
| 226 | *const fn (?*anyopaque) callconv(.C) ?*anyopaque; | ||
| 223 | pub extern "c" fn pthread_attr_init(attr: *c.pthread_attr_t) c.E; | 227 | pub extern "c" fn pthread_attr_init(attr: *c.pthread_attr_t) c.E; |
| 224 | pub extern "c" fn pthread_attr_setstack(attr: *c.pthread_attr_t, stackaddr: *anyopaque, stacksize: usize) c.E; | 228 | pub extern "c" fn pthread_attr_setstack(attr: *c.pthread_attr_t, stackaddr: *anyopaque, stacksize: usize) c.E; |
| 225 | pub extern "c" fn pthread_attr_setstacksize(attr: *c.pthread_attr_t, stacksize: usize) c.E; | 229 | pub extern "c" fn pthread_attr_setstacksize(attr: *c.pthread_attr_t, stacksize: usize) c.E; |
| ... | @@ -229,10 +233,14 @@ pub extern "c" fn pthread_self() pthread_t; | ... | @@ -229,10 +233,14 @@ pub extern "c" fn pthread_self() pthread_t; |
| 229 | pub extern "c" fn pthread_join(thread: pthread_t, arg_return: ?*?*anyopaque) c.E; | 233 | pub extern "c" fn pthread_join(thread: pthread_t, arg_return: ?*?*anyopaque) c.E; |
| 230 | pub extern "c" fn pthread_detach(thread: pthread_t) c.E; | 234 | pub extern "c" fn pthread_detach(thread: pthread_t) c.E; |
| 231 | pub extern "c" fn pthread_atfork( | 235 | pub extern "c" fn pthread_atfork( |
| 232 | prepare: ?fn () callconv(.C) void, | 236 | prepare: ?PThreadForkFn, |
| 233 | parent: ?fn () callconv(.C) void, | 237 | parent: ?PThreadForkFn, |
| 234 | child: ?fn () callconv(.C) void, | 238 | child: ?PThreadForkFn, |
| 235 | ) c_int; | 239 | ) c_int; |
| 240 | const PThreadForkFn = if (builtin.zig_backend == .stage1) | ||
| 241 | fn () callconv(.C) void | ||
| 242 | else | ||
| 243 | *const fn () callconv(.C) void; | ||
| 236 | pub extern "c" fn pthread_key_create(key: *c.pthread_key_t, destructor: ?fn (value: *anyopaque) callconv(.C) void) c.E; | 244 | pub extern "c" fn pthread_key_create(key: *c.pthread_key_t, destructor: ?fn (value: *anyopaque) callconv(.C) void) c.E; |
| 237 | pub extern "c" fn pthread_key_delete(key: c.pthread_key_t) c.E; | 245 | pub extern "c" fn pthread_key_delete(key: c.pthread_key_t) c.E; |
| 238 | pub extern "c" fn pthread_getspecific(key: c.pthread_key_t) ?*anyopaque; | 246 | pub extern "c" fn pthread_getspecific(key: c.pthread_key_t) ?*anyopaque; |
lib/std/c/tokenizer.zig+5-1| ... | @@ -126,7 +126,11 @@ pub const Token = struct { | ... | @@ -126,7 +126,11 @@ pub const Token = struct { |
| 126 | Keyword_error, | 126 | Keyword_error, |
| 127 | Keyword_pragma, | 127 | Keyword_pragma, |
| 128 | 128 | ||
| 129 | pub fn symbol(id: std.meta.Tag(Id)) []const u8 { | 129 | pub fn symbol(id: Id) []const u8 { |
| 130 | return symbolName(id); | ||
| 131 | } | ||
| 132 | |||
| 133 | pub fn symbolName(id: std.meta.Tag(Id)) []const u8 { | ||
| 130 | return switch (id) { | 134 | return switch (id) { |
| 131 | .Invalid => "Invalid", | 135 | .Invalid => "Invalid", |
| 132 | .Eof => "Eof", | 136 | .Eof => "Eof", |
lib/std/special/c.zig+2-4| ... | @@ -32,10 +32,8 @@ comptime { | ... | @@ -32,10 +32,8 @@ comptime { |
| 32 | @export(wasm_start, .{ .name = "_start", .linkage = .Strong }); | 32 | @export(wasm_start, .{ .name = "_start", .linkage = .Strong }); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | if (builtin.zig_backend == .stage1) { // TODO remove this condition | 35 | if (native_os == .linux) { |
| 36 | if (native_os == .linux) { | 36 | @export(clone, .{ .name = "clone" }); |
| 37 | @export(clone, .{ .name = "clone" }); | ||
| 38 | } | ||
| 39 | } | 37 | } |
| 40 | 38 | ||
| 41 | @export(memset, .{ .name = "memset", .linkage = .Strong }); | 39 | @export(memset, .{ .name = "memset", .linkage = .Strong }); |
src/AstGen.zig+13-14| ... | @@ -1807,6 +1807,8 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -1807,6 +1807,8 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1807 | .@"break"; | 1807 | .@"break"; |
| 1808 | 1808 | ||
| 1809 | if (rhs == 0) { | 1809 | if (rhs == 0) { |
| 1810 | try genDefers(parent_gz, scope, parent_scope, .normal_only); | ||
| 1811 | |||
| 1810 | _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); | 1812 | _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); |
| 1811 | return Zir.Inst.Ref.unreachable_value; | 1813 | return Zir.Inst.Ref.unreachable_value; |
| 1812 | } | 1814 | } |
| ... | @@ -1819,12 +1821,15 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -1819,12 +1821,15 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1819 | const prev_rvalue_noresult = parent_gz.rvalue_noresult; | 1821 | const prev_rvalue_noresult = parent_gz.rvalue_noresult; |
| 1820 | parent_gz.rvalue_noresult = .none; | 1822 | parent_gz.rvalue_noresult = .none; |
| 1821 | const operand = try reachableExpr(parent_gz, parent_scope, block_gz.break_result_loc, rhs, node); | 1823 | const operand = try reachableExpr(parent_gz, parent_scope, block_gz.break_result_loc, rhs, node); |
| 1824 | const search_index = @intCast(Zir.Inst.Index, astgen.instructions.len); | ||
| 1822 | parent_gz.rvalue_noresult = prev_rvalue_noresult; | 1825 | parent_gz.rvalue_noresult = prev_rvalue_noresult; |
| 1823 | 1826 | ||
| 1827 | try genDefers(parent_gz, scope, parent_scope, .normal_only); | ||
| 1828 | |||
| 1824 | switch (block_gz.break_result_loc) { | 1829 | switch (block_gz.break_result_loc) { |
| 1825 | .block_ptr => { | 1830 | .block_ptr => { |
| 1826 | const br = try parent_gz.addBreak(break_tag, block_inst, operand); | 1831 | const br = try parent_gz.addBreak(break_tag, block_inst, operand); |
| 1827 | try block_gz.labeled_breaks.append(astgen.gpa, br); | 1832 | try block_gz.labeled_breaks.append(astgen.gpa, .{ .br = br, .search = search_index }); |
| 1828 | }, | 1833 | }, |
| 1829 | .ptr => { | 1834 | .ptr => { |
| 1830 | // In this case we don't have any mechanism to intercept it; | 1835 | // In this case we don't have any mechanism to intercept it; |
| ... | @@ -1843,13 +1848,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -1843,13 +1848,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1843 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, | 1848 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 1844 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, | 1849 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 1845 | .namespace => break, | 1850 | .namespace => break, |
| 1846 | .defer_normal => { | 1851 | .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent, |
| 1847 | const defer_scope = scope.cast(Scope.Defer).?; | ||
| 1848 | scope = defer_scope.parent; | ||
| 1849 | const expr_node = node_datas[defer_scope.defer_node].rhs; | ||
| 1850 | try unusedResultDeferExpr(parent_gz, defer_scope, defer_scope.parent, expr_node); | ||
| 1851 | }, | ||
| 1852 | .defer_error => scope = scope.cast(Scope.Defer).?.parent, | ||
| 1853 | .top => unreachable, | 1852 | .top => unreachable, |
| 1854 | } | 1853 | } |
| 1855 | } | 1854 | } |
| ... | @@ -2030,7 +2029,7 @@ fn labeledBlockExpr( | ... | @@ -2030,7 +2029,7 @@ fn labeledBlockExpr( |
| 2030 | // The code took advantage of the result location as a pointer. | 2029 | // The code took advantage of the result location as a pointer. |
| 2031 | // Turn the break instruction operands into void. | 2030 | // Turn the break instruction operands into void. |
| 2032 | for (block_scope.labeled_breaks.items) |br| { | 2031 | for (block_scope.labeled_breaks.items) |br| { |
| 2033 | zir_datas[br].@"break".operand = .void_value; | 2032 | zir_datas[br.br].@"break".operand = .void_value; |
| 2034 | } | 2033 | } |
| 2035 | try block_scope.setBlockBody(block_inst); | 2034 | try block_scope.setBlockBody(block_inst); |
| 2036 | 2035 | ||
| ... | @@ -2047,17 +2046,17 @@ fn labeledBlockExpr( | ... | @@ -2047,17 +2046,17 @@ fn labeledBlockExpr( |
| 2047 | for (block_scope.labeled_breaks.items) |br| { | 2046 | for (block_scope.labeled_breaks.items) |br| { |
| 2048 | // We expect the `store_to_block_ptr` to be created between 1-3 instructions | 2047 | // We expect the `store_to_block_ptr` to be created between 1-3 instructions |
| 2049 | // prior to the break. | 2048 | // prior to the break. |
| 2050 | var search_index = br -| 3; | 2049 | var search_index = br.search -| 3; |
| 2051 | while (search_index < br) : (search_index += 1) { | 2050 | while (search_index < br.search) : (search_index += 1) { |
| 2052 | if (zir_tags[search_index] == .store_to_block_ptr and | 2051 | if (zir_tags[search_index] == .store_to_block_ptr and |
| 2053 | zir_datas[search_index].bin.lhs == block_scope.rl_ptr) | 2052 | zir_datas[search_index].bin.lhs == block_scope.rl_ptr) |
| 2054 | { | 2053 | { |
| 2055 | zir_tags[search_index] = .as; | 2054 | zir_tags[search_index] = .as; |
| 2056 | zir_datas[search_index].bin = .{ | 2055 | zir_datas[search_index].bin = .{ |
| 2057 | .lhs = block_scope.rl_ty_inst, | 2056 | .lhs = block_scope.rl_ty_inst, |
| 2058 | .rhs = zir_datas[br].@"break".operand, | 2057 | .rhs = zir_datas[br.br].@"break".operand, |
| 2059 | }; | 2058 | }; |
| 2060 | zir_datas[br].@"break".operand = indexToRef(search_index); | 2059 | zir_datas[br.br].@"break".operand = indexToRef(search_index); |
| 2061 | break; | 2060 | break; |
| 2062 | } | 2061 | } |
| 2063 | } else unreachable; | 2062 | } else unreachable; |
| ... | @@ -9719,7 +9718,7 @@ const GenZir = struct { | ... | @@ -9719,7 +9718,7 @@ const GenZir = struct { |
| 9719 | break_count: usize = 0, | 9718 | break_count: usize = 0, |
| 9720 | /// Tracks `break :foo bar` instructions so they can possibly be elided later if | 9719 | /// Tracks `break :foo bar` instructions so they can possibly be elided later if |
| 9721 | /// the labeled block ends up not needing a result location pointer. | 9720 | /// the labeled block ends up not needing a result location pointer. |
| 9722 | labeled_breaks: ArrayListUnmanaged(Zir.Inst.Index) = .{}, | 9721 | labeled_breaks: ArrayListUnmanaged(struct { br: Zir.Inst.Index, search: Zir.Inst.Index }) = .{}, |
| 9723 | 9722 | ||
| 9724 | suspend_node: Ast.Node.Index = 0, | 9723 | suspend_node: Ast.Node.Index = 0, |
| 9725 | nosuspend_node: Ast.Node.Index = 0, | 9724 | nosuspend_node: Ast.Node.Index = 0, |
src/clang.zig+8-3| ... | @@ -161,7 +161,12 @@ pub const ASTUnit = opaque { | ... | @@ -161,7 +161,12 @@ pub const ASTUnit = opaque { |
| 161 | extern fn ZigClangASTUnit_getSourceManager(*ASTUnit) *SourceManager; | 161 | extern fn ZigClangASTUnit_getSourceManager(*ASTUnit) *SourceManager; |
| 162 | 162 | ||
| 163 | pub const visitLocalTopLevelDecls = ZigClangASTUnit_visitLocalTopLevelDecls; | 163 | pub const visitLocalTopLevelDecls = ZigClangASTUnit_visitLocalTopLevelDecls; |
| 164 | extern fn ZigClangASTUnit_visitLocalTopLevelDecls(*ASTUnit, context: ?*anyopaque, Fn: ?fn (?*anyopaque, *const Decl) callconv(.C) bool) bool; | 164 | extern fn ZigClangASTUnit_visitLocalTopLevelDecls(*ASTUnit, context: ?*anyopaque, Fn: ?VisitorFn) bool; |
| 165 | |||
| 166 | const VisitorFn = if (@import("builtin").zig_backend == .stage1) | ||
| 167 | fn (?*anyopaque, *const Decl) callconv(.C) bool | ||
| 168 | else | ||
| 169 | *const fn (?*anyopaque, *const Decl) callconv(.C) bool; | ||
| 165 | 170 | ||
| 166 | pub const getLocalPreprocessingEntities_begin = ZigClangASTUnit_getLocalPreprocessingEntities_begin; | 171 | pub const getLocalPreprocessingEntities_begin = ZigClangASTUnit_getLocalPreprocessingEntities_begin; |
| 167 | extern fn ZigClangASTUnit_getLocalPreprocessingEntities_begin(*ASTUnit) PreprocessingRecord.iterator; | 172 | extern fn ZigClangASTUnit_getLocalPreprocessingEntities_begin(*ASTUnit) PreprocessingRecord.iterator; |
| ... | @@ -490,8 +495,8 @@ pub const FloatingLiteral = opaque { | ... | @@ -490,8 +495,8 @@ pub const FloatingLiteral = opaque { |
| 490 | pub const getValueAsApproximateDouble = ZigClangFloatingLiteral_getValueAsApproximateDouble; | 495 | pub const getValueAsApproximateDouble = ZigClangFloatingLiteral_getValueAsApproximateDouble; |
| 491 | extern fn ZigClangFloatingLiteral_getValueAsApproximateDouble(*const FloatingLiteral) f64; | 496 | extern fn ZigClangFloatingLiteral_getValueAsApproximateDouble(*const FloatingLiteral) f64; |
| 492 | 497 | ||
| 493 | pub const getBeginLoc = ZigClangIntegerLiteral_getBeginLoc; | 498 | pub const getBeginLoc = ZigClangFloatingLiteral_getBeginLoc; |
| 494 | extern fn ZigClangIntegerLiteral_getBeginLoc(*const FloatingLiteral) SourceLocation; | 499 | extern fn ZigClangFloatingLiteral_getBeginLoc(*const FloatingLiteral) SourceLocation; |
| 495 | 500 | ||
| 496 | pub const getRawSemantics = ZigClangFloatingLiteral_getRawSemantics; | 501 | pub const getRawSemantics = ZigClangFloatingLiteral_getRawSemantics; |
| 497 | extern fn ZigClangFloatingLiteral_getRawSemantics(*const FloatingLiteral) APFloatBaseSemantics; | 502 | extern fn ZigClangFloatingLiteral_getRawSemantics(*const FloatingLiteral) APFloatBaseSemantics; |
src/codegen/llvm.zig+21-6| ... | @@ -4732,10 +4732,11 @@ pub const FuncGen = struct { | ... | @@ -4732,10 +4732,11 @@ pub const FuncGen = struct { |
| 4732 | var buf: Type.Payload.ElemType = undefined; | 4732 | var buf: Type.Payload.ElemType = undefined; |
| 4733 | const payload_ty = optional_ty.optionalChild(&buf); | 4733 | const payload_ty = optional_ty.optionalChild(&buf); |
| 4734 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 4734 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 4735 | const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand; | ||
| 4735 | if (invert) { | 4736 | if (invert) { |
| 4736 | return self.builder.buildNot(operand, ""); | 4737 | return self.builder.buildNot(loaded, ""); |
| 4737 | } else { | 4738 | } else { |
| 4738 | return operand; | 4739 | return loaded; |
| 4739 | } | 4740 | } |
| 4740 | } | 4741 | } |
| 4741 | 4742 | ||
| ... | @@ -4784,12 +4785,16 @@ pub const FuncGen = struct { | ... | @@ -4784,12 +4785,16 @@ pub const FuncGen = struct { |
| 4784 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 4785 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 4785 | const operand = try self.resolveInst(ty_op.operand); | 4786 | const operand = try self.resolveInst(ty_op.operand); |
| 4786 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); | 4787 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); |
| 4788 | const result_ty = self.air.getRefType(ty_op.ty); | ||
| 4787 | var buf: Type.Payload.ElemType = undefined; | 4789 | var buf: Type.Payload.ElemType = undefined; |
| 4788 | const payload_ty = optional_ty.optionalChild(&buf); | 4790 | const payload_ty = optional_ty.optionalChild(&buf); |
| 4789 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 4791 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 4790 | // We have a pointer to a zero-bit value and we need to return | 4792 | // We have a pointer to a zero-bit value and we need to return |
| 4791 | // a pointer to a zero-bit value. | 4793 | // a pointer to a zero-bit value. |
| 4792 | return operand; | 4794 | |
| 4795 | // TODO once we update to LLVM 14 this bitcast won't be necessary. | ||
| 4796 | const res_ptr_ty = try self.dg.llvmType(result_ty); | ||
| 4797 | return self.builder.buildBitCast(operand, res_ptr_ty, ""); | ||
| 4793 | } | 4798 | } |
| 4794 | if (optional_ty.isPtrLikeOptional()) { | 4799 | if (optional_ty.isPtrLikeOptional()) { |
| 4795 | // The payload and the optional are the same value. | 4800 | // The payload and the optional are the same value. |
| ... | @@ -4807,13 +4812,17 @@ pub const FuncGen = struct { | ... | @@ -4807,13 +4812,17 @@ pub const FuncGen = struct { |
| 4807 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 4812 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 4808 | const operand = try self.resolveInst(ty_op.operand); | 4813 | const operand = try self.resolveInst(ty_op.operand); |
| 4809 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); | 4814 | const optional_ty = self.air.typeOf(ty_op.operand).childType(); |
| 4815 | const result_ty = self.air.getRefType(ty_op.ty); | ||
| 4810 | var buf: Type.Payload.ElemType = undefined; | 4816 | var buf: Type.Payload.ElemType = undefined; |
| 4811 | const payload_ty = optional_ty.optionalChild(&buf); | 4817 | const payload_ty = optional_ty.optionalChild(&buf); |
| 4812 | const non_null_bit = self.context.intType(1).constAllOnes(); | 4818 | const non_null_bit = self.context.intType(1).constAllOnes(); |
| 4813 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 4819 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 4814 | // We have a pointer to a i1. We need to set it to 1 and then return the same pointer. | 4820 | // We have a pointer to a i1. We need to set it to 1 and then return the same pointer. |
| 4815 | _ = self.builder.buildStore(non_null_bit, operand); | 4821 | _ = self.builder.buildStore(non_null_bit, operand); |
| 4816 | return operand; | 4822 | |
| 4823 | // TODO once we update to LLVM 14 this bitcast won't be necessary. | ||
| 4824 | const res_ptr_ty = try self.dg.llvmType(result_ty); | ||
| 4825 | return self.builder.buildBitCast(operand, res_ptr_ty, ""); | ||
| 4817 | } | 4826 | } |
| 4818 | if (optional_ty.isPtrLikeOptional()) { | 4827 | if (optional_ty.isPtrLikeOptional()) { |
| 4819 | // The payload and the optional are the same value. | 4828 | // The payload and the optional are the same value. |
| ... | @@ -4872,7 +4881,13 @@ pub const FuncGen = struct { | ... | @@ -4872,7 +4881,13 @@ pub const FuncGen = struct { |
| 4872 | const target = self.dg.module.getTarget(); | 4881 | const target = self.dg.module.getTarget(); |
| 4873 | const offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; | 4882 | const offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; |
| 4874 | 4883 | ||
| 4875 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return null; | 4884 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { |
| 4885 | if (!operand_is_ptr) return null; | ||
| 4886 | |||
| 4887 | // TODO once we update to LLVM 14 this bitcast won't be necessary. | ||
| 4888 | const res_ptr_ty = try self.dg.llvmType(result_ty); | ||
| 4889 | return self.builder.buildBitCast(operand, res_ptr_ty, ""); | ||
| 4890 | } | ||
| 4876 | if (operand_is_ptr or isByRef(payload_ty)) { | 4891 | if (operand_is_ptr or isByRef(payload_ty)) { |
| 4877 | return self.builder.buildStructGEP(operand, offset, ""); | 4892 | return self.builder.buildStructGEP(operand, offset, ""); |
| 4878 | } | 4893 | } |
| ... | @@ -7205,7 +7220,7 @@ pub const FuncGen = struct { | ... | @@ -7205,7 +7220,7 @@ pub const FuncGen = struct { |
| 7205 | return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); | 7220 | return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, ""); |
| 7206 | } | 7221 | } |
| 7207 | 7222 | ||
| 7208 | fn getIntrinsic(self: *FuncGen, name: []const u8, types: []*const llvm.Type) *const llvm.Value { | 7223 | fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *const llvm.Type) *const llvm.Value { |
| 7209 | const id = llvm.lookupIntrinsicID(name.ptr, name.len); | 7224 | const id = llvm.lookupIntrinsicID(name.ptr, name.len); |
| 7210 | assert(id != 0); | 7225 | assert(id != 0); |
| 7211 | return self.llvmModule().getIntrinsicDeclaration(id, types.ptr, types.len); | 7226 | return self.llvmModule().getIntrinsicDeclaration(id, types.ptr, types.len); |
src/codegen/llvm/bindings.zig+2-2| ... | @@ -60,7 +60,7 @@ pub const Context = opaque { | ... | @@ -60,7 +60,7 @@ pub const Context = opaque { |
| 60 | Packed: Bool, | 60 | Packed: Bool, |
| 61 | ) *const Type; | 61 | ) *const Type; |
| 62 | 62 | ||
| 63 | const structCreateNamed = LLVMStructCreateNamed; | 63 | pub const structCreateNamed = LLVMStructCreateNamed; |
| 64 | extern fn LLVMStructCreateNamed(C: *const Context, Name: [*:0]const u8) *const Type; | 64 | extern fn LLVMStructCreateNamed(C: *const Context, Name: [*:0]const u8) *const Type; |
| 65 | 65 | ||
| 66 | pub const constString = LLVMConstStringInContext; | 66 | pub const constString = LLVMConstStringInContext; |
| ... | @@ -320,7 +320,7 @@ pub const Module = opaque { | ... | @@ -320,7 +320,7 @@ pub const Module = opaque { |
| 320 | extern fn LLVMGetNamedFunction(*const Module, Name: [*:0]const u8) ?*const Value; | 320 | extern fn LLVMGetNamedFunction(*const Module, Name: [*:0]const u8) ?*const Value; |
| 321 | 321 | ||
| 322 | pub const getIntrinsicDeclaration = LLVMGetIntrinsicDeclaration; | 322 | pub const getIntrinsicDeclaration = LLVMGetIntrinsicDeclaration; |
| 323 | extern fn LLVMGetIntrinsicDeclaration(Mod: *const Module, ID: c_uint, ParamTypes: ?[*]*const Type, ParamCount: usize) *const Value; | 323 | extern fn LLVMGetIntrinsicDeclaration(Mod: *const Module, ID: c_uint, ParamTypes: ?[*]const *const Type, ParamCount: usize) *const Value; |
| 324 | 324 | ||
| 325 | pub const printToString = LLVMPrintModuleToString; | 325 | pub const printToString = LLVMPrintModuleToString; |
| 326 | extern fn LLVMPrintModuleToString(*const Module) [*:0]const u8; | 326 | extern fn LLVMPrintModuleToString(*const Module) [*:0]const u8; |
src/translate_c.zig+5-3| ... | @@ -368,11 +368,13 @@ pub fn translate( | ... | @@ -368,11 +368,13 @@ pub fn translate( |
| 368 | resources_path: [*:0]const u8, | 368 | resources_path: [*:0]const u8, |
| 369 | zig_is_stage1: bool, | 369 | zig_is_stage1: bool, |
| 370 | ) !std.zig.Ast { | 370 | ) !std.zig.Ast { |
| 371 | // TODO stage2 bug | ||
| 372 | var tmp = errors; | ||
| 371 | const ast_unit = clang.LoadFromCommandLine( | 373 | const ast_unit = clang.LoadFromCommandLine( |
| 372 | args_begin, | 374 | args_begin, |
| 373 | args_end, | 375 | args_end, |
| 374 | &errors.ptr, | 376 | &tmp.ptr, |
| 375 | &errors.len, | 377 | &tmp.len, |
| 376 | resources_path, | 378 | resources_path, |
| 377 | ) orelse { | 379 | ) orelse { |
| 378 | if (errors.len == 0) return error.ASTUnitFailure; | 380 | if (errors.len == 0) return error.ASTUnitFailure; |
| ... | @@ -5325,7 +5327,7 @@ const MacroCtx = struct { | ... | @@ -5325,7 +5327,7 @@ const MacroCtx = struct { |
| 5325 | try self.fail( | 5327 | try self.fail( |
| 5326 | c, | 5328 | c, |
| 5327 | "unable to translate C expr: expected '{s}' instead got '{s}'", | 5329 | "unable to translate C expr: expected '{s}' instead got '{s}'", |
| 5328 | .{ CToken.Id.symbol(expected_id), next_id.symbol() }, | 5330 | .{ CToken.Id.symbolName(expected_id), next_id.symbol() }, |
| 5329 | ); | 5331 | ); |
| 5330 | return error.ParseError; | 5332 | return error.ParseError; |
| 5331 | } | 5333 | } |
src/translate_c/ast.zig+1-1| ... | @@ -779,7 +779,7 @@ const TokenTag = std.zig.Token.Tag; | ... | @@ -779,7 +779,7 @@ const TokenTag = std.zig.Token.Tag; |
| 779 | 779 | ||
| 780 | const Context = struct { | 780 | const Context = struct { |
| 781 | gpa: Allocator, | 781 | gpa: Allocator, |
| 782 | buf: std.ArrayList(u8) = .{}, | 782 | buf: std.ArrayList(u8), |
| 783 | nodes: std.zig.Ast.NodeList = .{}, | 783 | nodes: std.zig.Ast.NodeList = .{}, |
| 784 | extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .{}, | 784 | extra_data: std.ArrayListUnmanaged(std.zig.Ast.Node.Index) = .{}, |
| 785 | tokens: std.zig.Ast.TokenList = .{}, | 785 | tokens: std.zig.Ast.TokenList = .{}, |
src/zig_clang.cpp+5| ... | @@ -2706,6 +2706,11 @@ double ZigClangFloatingLiteral_getValueAsApproximateDouble(const ZigClangFloatin | ... | @@ -2706,6 +2706,11 @@ double ZigClangFloatingLiteral_getValueAsApproximateDouble(const ZigClangFloatin |
| 2706 | return casted->getValueAsApproximateDouble(); | 2706 | return casted->getValueAsApproximateDouble(); |
| 2707 | } | 2707 | } |
| 2708 | 2708 | ||
| 2709 | struct ZigClangSourceLocation ZigClangFloatingLiteral_getBeginLoc(const struct ZigClangFloatingLiteral *self) { | ||
| 2710 | auto casted = reinterpret_cast<const clang::FloatingLiteral *>(self); | ||
| 2711 | return bitcast(casted->getBeginLoc()); | ||
| 2712 | } | ||
| 2713 | |||
| 2709 | ZigClangAPFloatBase_Semantics ZigClangFloatingLiteral_getRawSemantics(const ZigClangFloatingLiteral *self) { | 2714 | ZigClangAPFloatBase_Semantics ZigClangFloatingLiteral_getRawSemantics(const ZigClangFloatingLiteral *self) { |
| 2710 | auto casted = reinterpret_cast<const clang::FloatingLiteral *>(self); | 2715 | auto casted = reinterpret_cast<const clang::FloatingLiteral *>(self); |
| 2711 | return static_cast<ZigClangAPFloatBase_Semantics>(casted->getRawSemantics()); | 2716 | return static_cast<ZigClangAPFloatBase_Semantics>(casted->getRawSemantics()); |
src/zig_clang.h+1| ... | @@ -1245,6 +1245,7 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangDeclStmt_getBeginLoc(const st | ... | @@ -1245,6 +1245,7 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangDeclStmt_getBeginLoc(const st |
| 1245 | ZIG_EXTERN_C unsigned ZigClangAPFloat_convertToHexString(const struct ZigClangAPFloat *self, char *DST, | 1245 | ZIG_EXTERN_C unsigned ZigClangAPFloat_convertToHexString(const struct ZigClangAPFloat *self, char *DST, |
| 1246 | unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM); | 1246 | unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM); |
| 1247 | ZIG_EXTERN_C double ZigClangFloatingLiteral_getValueAsApproximateDouble(const ZigClangFloatingLiteral *self); | 1247 | ZIG_EXTERN_C double ZigClangFloatingLiteral_getValueAsApproximateDouble(const ZigClangFloatingLiteral *self); |
| 1248 | ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangFloatingLiteral_getBeginLoc(const struct ZigClangFloatingLiteral *); | ||
| 1248 | ZIG_EXTERN_C ZigClangAPFloatBase_Semantics ZigClangFloatingLiteral_getRawSemantics(const ZigClangFloatingLiteral *self); | 1249 | ZIG_EXTERN_C ZigClangAPFloatBase_Semantics ZigClangFloatingLiteral_getRawSemantics(const ZigClangFloatingLiteral *self); |
| 1249 | 1250 | ||
| 1250 | ZIG_EXTERN_C enum ZigClangStringLiteral_StringKind ZigClangStringLiteral_getKind(const struct ZigClangStringLiteral *self); | 1251 | ZIG_EXTERN_C enum ZigClangStringLiteral_StringKind ZigClangStringLiteral_getKind(const struct ZigClangStringLiteral *self); |
test/behavior/optional.zig+39| ... | @@ -332,3 +332,42 @@ test "array of optional unaligned types" { | ... | @@ -332,3 +332,42 @@ test "array of optional unaligned types" { |
| 332 | i += 1; | 332 | i += 1; |
| 333 | try expect(Enum.three == values[i].?.Num); | 333 | try expect(Enum.three == values[i].?.Num); |
| 334 | } | 334 | } |
| 335 | |||
| 336 | test "optional pointer to zero bit optional payload" { | ||
| 337 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 338 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 339 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 340 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 341 | |||
| 342 | const B = struct { | ||
| 343 | fn foo(_: *@This()) void {} | ||
| 344 | }; | ||
| 345 | const A = struct { | ||
| 346 | b: ?B = .{}, | ||
| 347 | }; | ||
| 348 | var a: A = .{}; | ||
| 349 | var a_ptr = &a; | ||
| 350 | if (a_ptr.b) |*some| { | ||
| 351 | some.foo(); | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | test "optional pointer to zero bit error union payload" { | ||
| 356 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 357 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 358 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 359 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 360 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | ||
| 361 | |||
| 362 | const B = struct { | ||
| 363 | fn foo(_: *@This()) void {} | ||
| 364 | }; | ||
| 365 | const A = struct { | ||
| 366 | b: anyerror!B = .{}, | ||
| 367 | }; | ||
| 368 | var a: A = .{}; | ||
| 369 | var a_ptr = &a; | ||
| 370 | if (a_ptr.b) |*some| { | ||
| 371 | some.foo(); | ||
| 372 | } else |_| {} | ||
| 373 | } |