authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-16 05:42:25-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-04-16 05:42:25-04:00
log578a792b33d1f26c839cd6c77eaa2680601caaf2
tree1378c449be224c8b81fcb46ca4b1ad9097588c9b
parent3bfb1616db0883e6145a1fe1844eee3038bd4ca1
parent101aac92c258af9f25520c36f06b2ce8335d7f9a
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11442 from Vexu/stage3

Make self hosted compiler capable of building itself

12 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;
219pub extern "c" fn utimensat(dirfd: c.fd_t, pathname: [*:0]const u8, times: *[2]c.timespec, flags: u32) c_int;219pub extern "c" fn utimensat(dirfd: c.fd_t, pathname: [*:0]const u8, times: *[2]c.timespec, flags: u32) c_int;
220pub extern "c" fn futimens(fd: c.fd_t, times: *const [2]c.timespec) c_int;220pub extern "c" fn futimens(fd: c.fd_t, times: *const [2]c.timespec) c_int;
221221
222pub 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;222pub extern "c" fn pthread_create(noalias newthread: *pthread_t, noalias attr: ?*const c.pthread_attr_t, start_routine: PThreadStartFn, noalias arg: ?*anyopaque) c.E;
223const PThreadStartFn = if (builtin.zig_backend == .stage1)
224 fn (?*anyopaque) callconv(.C) ?*anyopaque
225else
226 *const fn (?*anyopaque) callconv(.C) ?*anyopaque;
223pub extern "c" fn pthread_attr_init(attr: *c.pthread_attr_t) c.E;227pub extern "c" fn pthread_attr_init(attr: *c.pthread_attr_t) c.E;
224pub extern "c" fn pthread_attr_setstack(attr: *c.pthread_attr_t, stackaddr: *anyopaque, stacksize: usize) c.E;228pub extern "c" fn pthread_attr_setstack(attr: *c.pthread_attr_t, stackaddr: *anyopaque, stacksize: usize) c.E;
225pub extern "c" fn pthread_attr_setstacksize(attr: *c.pthread_attr_t, stacksize: usize) c.E;229pub 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;
229pub extern "c" fn pthread_join(thread: pthread_t, arg_return: ?*?*anyopaque) c.E;233pub extern "c" fn pthread_join(thread: pthread_t, arg_return: ?*?*anyopaque) c.E;
230pub extern "c" fn pthread_detach(thread: pthread_t) c.E;234pub extern "c" fn pthread_detach(thread: pthread_t) c.E;
231pub extern "c" fn pthread_atfork(235pub 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;
240const PThreadForkFn = if (builtin.zig_backend == .stage1)
241 fn () callconv(.C) void
242else
243 *const fn () callconv(.C) void;
236pub extern "c" fn pthread_key_create(key: *c.pthread_key_t, destructor: ?fn (value: *anyopaque) callconv(.C) void) c.E;244pub extern "c" fn pthread_key_create(key: *c.pthread_key_t, destructor: ?fn (value: *anyopaque) callconv(.C) void) c.E;
237pub extern "c" fn pthread_key_delete(key: c.pthread_key_t) c.E;245pub extern "c" fn pthread_key_delete(key: c.pthread_key_t) c.E;
238pub extern "c" fn pthread_getspecific(key: c.pthread_key_t) ?*anyopaque;246pub 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,
128128
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 }
3434
35 if (builtin.zig_backend == .stage1) { // TODO remove this condition35 if (native_os == .linux) {
36 if (native_os == .linux) {36 @export(clone, .{ .name = "clone" });
37 @export(clone, .{ .name = "clone" });
38 }
39 }37 }
4038
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";
18081808
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;
18231826
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);
20362035
...@@ -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 instructions2047 // 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 and2051 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 if9719 /// 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 }) = .{},
97239722
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;
162162
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;
165170
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;
492497
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;
495500
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 }
47414742
...@@ -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 return4792 // 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;
48744883
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 }
72077222
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;
6262
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;
6565
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;
321321
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;
324324
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;
779779
780const Context = struct {780const 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}
27082708
2709struct ZigClangSourceLocation ZigClangFloatingLiteral_getBeginLoc(const struct ZigClangFloatingLiteral *self) {
2710 auto casted = reinterpret_cast<const clang::FloatingLiteral *>(self);
2711 return bitcast(casted->getBeginLoc());
2712}
2713
2709ZigClangAPFloatBase_Semantics ZigClangFloatingLiteral_getRawSemantics(const ZigClangFloatingLiteral *self) {2714ZigClangAPFloatBase_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
1245ZIG_EXTERN_C unsigned ZigClangAPFloat_convertToHexString(const struct ZigClangAPFloat *self, char *DST,1245ZIG_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);
1247ZIG_EXTERN_C double ZigClangFloatingLiteral_getValueAsApproximateDouble(const ZigClangFloatingLiteral *self);1247ZIG_EXTERN_C double ZigClangFloatingLiteral_getValueAsApproximateDouble(const ZigClangFloatingLiteral *self);
1248ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangFloatingLiteral_getBeginLoc(const struct ZigClangFloatingLiteral *);
1248ZIG_EXTERN_C ZigClangAPFloatBase_Semantics ZigClangFloatingLiteral_getRawSemantics(const ZigClangFloatingLiteral *self);1249ZIG_EXTERN_C ZigClangAPFloatBase_Semantics ZigClangFloatingLiteral_getRawSemantics(const ZigClangFloatingLiteral *self);
12491250
1250ZIG_EXTERN_C enum ZigClangStringLiteral_StringKind ZigClangStringLiteral_getKind(const struct ZigClangStringLiteral *self);1251ZIG_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
336test "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
355test "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}