| ... | @@ -2138,10 +2138,72 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com | ... | @@ -2138,10 +2138,72 @@ fn zirCImport(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Com |
| 2138 | const tracy = trace(@src()); | 2138 | const tracy = trace(@src()); |
| 2139 | defer tracy.end(); | 2139 | defer tracy.end(); |
| 2140 | | 2140 | |
| 2141 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 2141 | const pl_node = sema.code.instructions.items(.data)[inst].pl_node; |
| 2142 | const src = inst_data.src(); | 2142 | const src = pl_node.src(); |
| | 2143 | const extra = sema.code.extraData(Zir.Inst.Block, pl_node.payload_index); |
| | 2144 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| | 2145 | |
| | 2146 | // we check this here to avoid undefined symbols |
| | 2147 | if (!@import("build_options").have_llvm) |
| | 2148 | return sema.mod.fail(&parent_block.base, src, "cannot do C import on Zig compiler not built with LLVM-extension", .{}); |
| | 2149 | |
| | 2150 | var c_import_buf = std.ArrayList(u8).init(sema.gpa); |
| | 2151 | defer c_import_buf.deinit(); |
| | 2152 | |
| | 2153 | var child_block: Scope.Block = .{ |
| | 2154 | .parent = parent_block, |
| | 2155 | .sema = sema, |
| | 2156 | .src_decl = parent_block.src_decl, |
| | 2157 | .instructions = .{}, |
| | 2158 | .inlining = parent_block.inlining, |
| | 2159 | .is_comptime = parent_block.is_comptime, |
| | 2160 | .c_import_buf = &c_import_buf, |
| | 2161 | }; |
| | 2162 | defer child_block.instructions.deinit(sema.gpa); |
| | 2163 | |
| | 2164 | _ = try sema.analyzeBody(&child_block, body); |
| | 2165 | |
| | 2166 | const c_import_res = sema.mod.comp.cImport(c_import_buf.items) catch |err| |
| | 2167 | return sema.mod.fail(&child_block.base, src, "C import failed: {s}", .{@errorName(err)}); |
| 2143 | | 2168 | |
| 2144 | return sema.mod.fail(&parent_block.base, src, "TODO: implement Sema.zirCImport", .{}); | 2169 | if (c_import_res.errors.len != 0) { |
| | 2170 | const msg = try sema.mod.errMsg(&child_block.base, src, "C import failed", .{}); |
| | 2171 | errdefer msg.destroy(sema.gpa); |
| | 2172 | |
| | 2173 | if (!sema.mod.comp.bin_file.options.link_libc) |
| | 2174 | try sema.mod.errNote(&child_block.base, src, msg, "libc headers not available; compilation does not link against libc", .{}); |
| | 2175 | |
| | 2176 | for (c_import_res.errors) |_| { |
| | 2177 | // TODO integrate with LazySrcLoc |
| | 2178 | // try sema.mod.errNoteNonLazy(.{}, msg, "{s}", .{clang_err.msg_ptr[0..clang_err.msg_len]}); |
| | 2179 | // if (clang_err.filename_ptr) |p| p[0..clang_err.filename_len] else "(no file)", |
| | 2180 | // clang_err.line + 1, |
| | 2181 | // clang_err.column + 1, |
| | 2182 | } |
| | 2183 | @import("clang.zig").Stage2ErrorMsg.delete(c_import_res.errors.ptr, c_import_res.errors.len); |
| | 2184 | return sema.mod.failWithOwnedErrorMsg(&child_block.base, msg); |
| | 2185 | } |
| | 2186 | const c_import_pkg = @import("Package.zig").createWithDir( |
| | 2187 | sema.gpa, |
| | 2188 | sema.mod.comp.local_cache_directory, |
| | 2189 | null, |
| | 2190 | std.fs.path.basename(c_import_res.out_zig_path), |
| | 2191 | ) catch |err| switch (err) { |
| | 2192 | error.OutOfMemory => return error.OutOfMemory, |
| | 2193 | else => unreachable, // we pass null for root_src_dir_path |
| | 2194 | }; |
| | 2195 | const std_pkg = sema.mod.main_pkg.table.get("std").?; |
| | 2196 | const builtin_pkg = sema.mod.main_pkg.table.get("builtin").?; |
| | 2197 | try c_import_pkg.add(sema.gpa, "builtin", builtin_pkg); |
| | 2198 | try c_import_pkg.add(sema.gpa, "std", std_pkg); |
| | 2199 | |
| | 2200 | const result = sema.mod.importPkg(c_import_pkg) catch |err| |
| | 2201 | return sema.mod.fail(&child_block.base, src, "C import failed: {s}", .{@errorName(err)}); |
| | 2202 | |
| | 2203 | try sema.mod.semaFile(result.file); |
| | 2204 | const file_root_decl = result.file.root_decl.?; |
| | 2205 | try sema.mod.declareDeclDependency(sema.owner_decl, file_root_decl); |
| | 2206 | return sema.addType(file_root_decl.ty); |
| 2145 | } | 2207 | } |
| 2146 | | 2208 | |
| 2147 | fn zirSuspendBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 2209 | fn zirSuspendBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -8226,7 +8288,10 @@ fn zirCUndef( | ... | @@ -8226,7 +8288,10 @@ fn zirCUndef( |
| 8226 | ) CompileError!Air.Inst.Ref { | 8288 | ) CompileError!Air.Inst.Ref { |
| 8227 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | 8289 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 8228 | const src: LazySrcLoc = .{ .node_offset = extra.node }; | 8290 | const src: LazySrcLoc = .{ .node_offset = extra.node }; |
| 8229 | return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirCUndef", .{}); | 8291 | |
| | 8292 | const name = try sema.resolveConstString(block, src, extra.operand); |
| | 8293 | try block.c_import_buf.?.writer().print("#undefine {s}\n", .{name}); |
| | 8294 | return Air.Inst.Ref.void_value; |
| 8230 | } | 8295 | } |
| 8231 | | 8296 | |
| 8232 | fn zirCInclude( | 8297 | fn zirCInclude( |
| ... | @@ -8236,7 +8301,10 @@ fn zirCInclude( | ... | @@ -8236,7 +8301,10 @@ fn zirCInclude( |
| 8236 | ) CompileError!Air.Inst.Ref { | 8301 | ) CompileError!Air.Inst.Ref { |
| 8237 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | 8302 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 8238 | const src: LazySrcLoc = .{ .node_offset = extra.node }; | 8303 | const src: LazySrcLoc = .{ .node_offset = extra.node }; |
| 8239 | return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirCInclude", .{}); | 8304 | |
| | 8305 | const name = try sema.resolveConstString(block, src, extra.operand); |
| | 8306 | try block.c_import_buf.?.writer().print("#include <{s}>\n", .{name}); |
| | 8307 | return Air.Inst.Ref.void_value; |
| 8240 | } | 8308 | } |
| 8241 | | 8309 | |
| 8242 | fn zirCDefine( | 8310 | fn zirCDefine( |
| ... | @@ -8246,7 +8314,15 @@ fn zirCDefine( | ... | @@ -8246,7 +8314,15 @@ fn zirCDefine( |
| 8246 | ) CompileError!Air.Inst.Ref { | 8314 | ) CompileError!Air.Inst.Ref { |
| 8247 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; | 8315 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; |
| 8248 | const src: LazySrcLoc = .{ .node_offset = extra.node }; | 8316 | const src: LazySrcLoc = .{ .node_offset = extra.node }; |
| 8249 | return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirCDefine", .{}); | 8317 | |
| | 8318 | const name = try sema.resolveConstString(block, src, extra.lhs); |
| | 8319 | if (sema.typeOf(extra.rhs).zigTypeTag() != .Void) { |
| | 8320 | const value = try sema.resolveConstString(block, src, extra.rhs); |
| | 8321 | try block.c_import_buf.?.writer().print("#define {s} {s}\n", .{ name, value }); |
| | 8322 | } else { |
| | 8323 | try block.c_import_buf.?.writer().print("#define {s}\n", .{name}); |
| | 8324 | } |
| | 8325 | return Air.Inst.Ref.void_value; |
| 8250 | } | 8326 | } |
| 8251 | | 8327 | |
| 8252 | fn zirWasmMemorySize( | 8328 | fn zirWasmMemorySize( |