mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
fixes and cleanup in self hosted
This commit is contained in:
parent
76f21852f6
commit
36849d8a7b
@ -25,10 +25,10 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
|
||||
|
||||
const context = llvm_handle.node.data;
|
||||
|
||||
const module = llvm.ModuleCreateWithNameInContext(comp.name.ptr(), context) orelse return error.OutOfMemory;
|
||||
const module = llvm.ModuleCreateWithNameInContext(comp.name.toSliceConst(), context) orelse return error.OutOfMemory;
|
||||
defer llvm.DisposeModule(module);
|
||||
|
||||
llvm.SetTarget(module, comp.llvm_triple.ptr());
|
||||
llvm.SetTarget(module, comp.llvm_triple.toSliceConst());
|
||||
llvm.SetDataLayout(module, comp.target_layout_str);
|
||||
|
||||
if (util.getObjectFormat(comp.target) == .coff) {
|
||||
@ -48,23 +48,23 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
|
||||
const producer = try std.Buffer.allocPrint(
|
||||
&code.arena.allocator,
|
||||
"zig {}.{}.{}",
|
||||
u32(c.ZIG_VERSION_MAJOR),
|
||||
u32(c.ZIG_VERSION_MINOR),
|
||||
u32(c.ZIG_VERSION_PATCH),
|
||||
@as(u32, c.ZIG_VERSION_MAJOR),
|
||||
@as(u32, c.ZIG_VERSION_MINOR),
|
||||
@as(u32, c.ZIG_VERSION_PATCH),
|
||||
);
|
||||
const flags = "";
|
||||
const runtime_version = 0;
|
||||
const compile_unit_file = llvm.CreateFile(
|
||||
dibuilder,
|
||||
comp.name.ptr(),
|
||||
comp.root_package.root_src_dir.ptr(),
|
||||
comp.name.toSliceConst(),
|
||||
comp.root_package.root_src_dir.toSliceConst(),
|
||||
) orelse return error.OutOfMemory;
|
||||
const is_optimized = comp.build_mode != .Debug;
|
||||
const compile_unit = llvm.CreateCompileUnit(
|
||||
dibuilder,
|
||||
DW.LANG_C99,
|
||||
compile_unit_file,
|
||||
producer.ptr(),
|
||||
producer.toSliceConst(),
|
||||
is_optimized,
|
||||
flags,
|
||||
runtime_version,
|
||||
@ -99,7 +99,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
|
||||
|
||||
// verify the llvm module when safety is on
|
||||
if (std.debug.runtime_safety) {
|
||||
var error_ptr: ?[*]u8 = null;
|
||||
var error_ptr: ?[*:0]u8 = null;
|
||||
_ = llvm.VerifyModule(ofile.module, llvm.AbortProcessAction, &error_ptr);
|
||||
}
|
||||
|
||||
@ -108,12 +108,12 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
|
||||
const is_small = comp.build_mode == .ReleaseSmall;
|
||||
const is_debug = comp.build_mode == .Debug;
|
||||
|
||||
var err_msg: [*]u8 = undefined;
|
||||
var err_msg: [*:0]u8 = undefined;
|
||||
// TODO integrate this with evented I/O
|
||||
if (llvm.TargetMachineEmitToFile(
|
||||
comp.target_machine,
|
||||
module,
|
||||
output_path.ptr(),
|
||||
output_path.toSliceConst(),
|
||||
llvm.EmitBinary,
|
||||
&err_msg,
|
||||
is_debug,
|
||||
@ -154,7 +154,7 @@ pub fn renderToLlvmModule(ofile: *ObjectFile, fn_val: *Value.Fn, code: *ir.Code)
|
||||
const llvm_fn_type = try fn_val.base.typ.getLlvmType(ofile.arena, ofile.context);
|
||||
const llvm_fn = llvm.AddFunction(
|
||||
ofile.module,
|
||||
fn_val.symbol_name.ptr(),
|
||||
fn_val.symbol_name.toSliceConst(),
|
||||
llvm_fn_type,
|
||||
) orelse return error.OutOfMemory;
|
||||
|
||||
@ -379,7 +379,7 @@ fn renderLoadUntyped(
|
||||
ptr: *llvm.Value,
|
||||
alignment: Type.Pointer.Align,
|
||||
vol: Type.Pointer.Vol,
|
||||
name: [*]const u8,
|
||||
name: [*:0]const u8,
|
||||
) !*llvm.Value {
|
||||
const result = llvm.BuildLoad(ofile.builder, ptr, name) orelse return error.OutOfMemory;
|
||||
switch (vol) {
|
||||
@ -390,7 +390,7 @@ fn renderLoadUntyped(
|
||||
return result;
|
||||
}
|
||||
|
||||
fn renderLoad(ofile: *ObjectFile, ptr: *llvm.Value, ptr_type: *Type.Pointer, name: [*]const u8) !*llvm.Value {
|
||||
fn renderLoad(ofile: *ObjectFile, ptr: *llvm.Value, ptr_type: *Type.Pointer, name: [*:0]const u8) !*llvm.Value {
|
||||
return renderLoadUntyped(ofile, ptr, ptr_type.key.alignment, ptr_type.key.vol, name);
|
||||
}
|
||||
|
||||
@ -438,7 +438,7 @@ pub fn renderAlloca(
|
||||
) !*llvm.Value {
|
||||
const llvm_var_type = try var_type.getLlvmType(ofile.arena, ofile.context);
|
||||
const name_with_null = try std.cstr.addNullByte(ofile.arena, name);
|
||||
const result = llvm.BuildAlloca(ofile.builder, llvm_var_type, name_with_null.ptr) orelse return error.OutOfMemory;
|
||||
const result = llvm.BuildAlloca(ofile.builder, llvm_var_type, @ptrCast([*:0]const u8, name_with_null.ptr)) orelse return error.OutOfMemory;
|
||||
llvm.SetAlignment(result, resolveAlign(ofile, alignment, llvm_var_type));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ pub const ZigCompiler = struct {
|
||||
return LlvmHandle{ .node = node };
|
||||
}
|
||||
|
||||
pub async fn getNativeLibC(self: *ZigCompiler) !*LibCInstallation {
|
||||
pub fn getNativeLibC(self: *ZigCompiler) !*LibCInstallation {
|
||||
if (self.native_libc.start()) |ptr| return ptr;
|
||||
try self.native_libc.data.findNative(self.allocator);
|
||||
self.native_libc.resolve();
|
||||
@ -135,26 +135,26 @@ pub const Compilation = struct {
|
||||
/// lazily created when we need it
|
||||
tmp_dir: event.Future(BuildError![]u8),
|
||||
|
||||
version_major: u32,
|
||||
version_minor: u32,
|
||||
version_patch: u32,
|
||||
version_major: u32 = 0,
|
||||
version_minor: u32 = 0,
|
||||
version_patch: u32 = 0,
|
||||
|
||||
linker_script: ?[]const u8,
|
||||
out_h_path: ?[]const u8,
|
||||
linker_script: ?[]const u8 = null,
|
||||
out_h_path: ?[]const u8 = null,
|
||||
|
||||
is_test: bool,
|
||||
each_lib_rpath: bool,
|
||||
strip: bool,
|
||||
is_test: bool = false,
|
||||
each_lib_rpath: bool = false,
|
||||
strip: bool = false,
|
||||
is_static: bool,
|
||||
linker_rdynamic: bool,
|
||||
linker_rdynamic: bool = false,
|
||||
|
||||
clang_argv: []const []const u8,
|
||||
lib_dirs: []const []const u8,
|
||||
rpath_list: []const []const u8,
|
||||
assembly_files: []const []const u8,
|
||||
clang_argv: []const []const u8 = [_][]const u8{},
|
||||
lib_dirs: []const []const u8 = [_][]const u8{},
|
||||
rpath_list: []const []const u8 = [_][]const u8{},
|
||||
assembly_files: []const []const u8 = [_][]const u8{},
|
||||
|
||||
/// paths that are explicitly provided by the user to link against
|
||||
link_objects: []const []const u8,
|
||||
link_objects: []const []const u8 = [_][]const u8{},
|
||||
|
||||
/// functions that have their own objects that we need to link
|
||||
/// it uses an optional pointer so that tombstone removals are possible
|
||||
@ -162,33 +162,33 @@ pub const Compilation = struct {
|
||||
|
||||
pub const FnLinkSet = std.TailQueue(?*Value.Fn);
|
||||
|
||||
windows_subsystem_windows: bool,
|
||||
windows_subsystem_console: bool,
|
||||
windows_subsystem_windows: bool = false,
|
||||
windows_subsystem_console: bool = false,
|
||||
|
||||
link_libs_list: ArrayList(*LinkLib),
|
||||
libc_link_lib: ?*LinkLib,
|
||||
libc_link_lib: ?*LinkLib = null,
|
||||
|
||||
err_color: errmsg.Color,
|
||||
err_color: errmsg.Color = .Auto,
|
||||
|
||||
verbose_tokenize: bool,
|
||||
verbose_ast_tree: bool,
|
||||
verbose_ast_fmt: bool,
|
||||
verbose_cimport: bool,
|
||||
verbose_ir: bool,
|
||||
verbose_llvm_ir: bool,
|
||||
verbose_link: bool,
|
||||
verbose_tokenize: bool = false,
|
||||
verbose_ast_tree: bool = false,
|
||||
verbose_ast_fmt: bool = false,
|
||||
verbose_cimport: bool = false,
|
||||
verbose_ir: bool = false,
|
||||
verbose_llvm_ir: bool = false,
|
||||
verbose_link: bool = false,
|
||||
|
||||
darwin_frameworks: []const []const u8,
|
||||
darwin_version_min: DarwinVersionMin,
|
||||
darwin_frameworks: []const []const u8 = [_][]const u8{},
|
||||
darwin_version_min: DarwinVersionMin = .None,
|
||||
|
||||
test_filters: []const []const u8,
|
||||
test_name_prefix: ?[]const u8,
|
||||
test_filters: []const []const u8 = [_][]const u8{},
|
||||
test_name_prefix: ?[]const u8 = null,
|
||||
|
||||
emit_file_type: Emit,
|
||||
emit_file_type: Emit = .Binary,
|
||||
|
||||
kind: Kind,
|
||||
|
||||
link_out_file: ?[]const u8,
|
||||
link_out_file: ?[]const u8 = null,
|
||||
events: *event.Channel(Event),
|
||||
|
||||
exported_symbol_names: event.Locked(Decl.Table),
|
||||
@ -213,7 +213,7 @@ pub const Compilation = struct {
|
||||
|
||||
target_machine: *llvm.TargetMachine,
|
||||
target_data_ref: *llvm.TargetData,
|
||||
target_layout_str: [*]u8,
|
||||
target_layout_str: [*:0]u8,
|
||||
target_ptr_bits: u32,
|
||||
|
||||
/// for allocating things which have the same lifetime as this Compilation
|
||||
@ -222,7 +222,7 @@ pub const Compilation = struct {
|
||||
root_package: *Package,
|
||||
std_package: *Package,
|
||||
|
||||
override_libc: ?*LibCInstallation,
|
||||
override_libc: ?*LibCInstallation = null,
|
||||
|
||||
/// need to wait on this group before deinitializing
|
||||
deinit_group: event.Group(void),
|
||||
@ -231,7 +231,7 @@ pub const Compilation = struct {
|
||||
// main_loop_frame: @Frame(Compilation.mainLoop),
|
||||
main_loop_future: event.Future(void),
|
||||
|
||||
have_err_ret_tracing: bool,
|
||||
have_err_ret_tracing: bool = false,
|
||||
|
||||
/// not locked because it is read-only
|
||||
primitive_type_table: TypeTable,
|
||||
@ -243,7 +243,7 @@ pub const Compilation = struct {
|
||||
|
||||
c_int_types: [CInt.list.len]*Type.Int,
|
||||
|
||||
// fs_watch: *fs.Watch(*Scope.Root),
|
||||
fs_watch: *fs.Watch(*Scope.Root),
|
||||
|
||||
const IntTypeTable = std.HashMap(*const Type.Int.Key, *Type.Int, Type.Int.Key.hash, Type.Int.Key.eql);
|
||||
const ArrayTypeTable = std.HashMap(*const Type.Array.Key, *Type.Array, Type.Array.Key.hash, Type.Array.Key.eql);
|
||||
@ -392,43 +392,10 @@ pub const Compilation = struct {
|
||||
|
||||
.name = undefined,
|
||||
.llvm_triple = undefined,
|
||||
|
||||
.version_major = 0,
|
||||
.version_minor = 0,
|
||||
.version_patch = 0,
|
||||
|
||||
.verbose_tokenize = false,
|
||||
.verbose_ast_tree = false,
|
||||
.verbose_ast_fmt = false,
|
||||
.verbose_cimport = false,
|
||||
.verbose_ir = false,
|
||||
.verbose_llvm_ir = false,
|
||||
.verbose_link = false,
|
||||
|
||||
.linker_script = null,
|
||||
.out_h_path = null,
|
||||
.is_test = false,
|
||||
.each_lib_rpath = false,
|
||||
.strip = false,
|
||||
.is_static = is_static,
|
||||
.linker_rdynamic = false,
|
||||
.clang_argv = [_][]const u8{},
|
||||
.lib_dirs = [_][]const u8{},
|
||||
.rpath_list = [_][]const u8{},
|
||||
.assembly_files = [_][]const u8{},
|
||||
.link_objects = [_][]const u8{},
|
||||
.fn_link_set = event.Locked(FnLinkSet).init(FnLinkSet.init()),
|
||||
.windows_subsystem_windows = false,
|
||||
.windows_subsystem_console = false,
|
||||
.link_libs_list = undefined,
|
||||
.libc_link_lib = null,
|
||||
.err_color = errmsg.Color.Auto,
|
||||
.darwin_frameworks = [_][]const u8{},
|
||||
.darwin_version_min = DarwinVersionMin.None,
|
||||
.test_filters = [_][]const u8{},
|
||||
.test_name_prefix = null,
|
||||
.emit_file_type = Emit.Binary,
|
||||
.link_out_file = null,
|
||||
|
||||
.exported_symbol_names = event.Locked(Decl.Table).init(Decl.Table.init(allocator)),
|
||||
.prelink_group = event.Group(BuildError!void).init(allocator),
|
||||
.deinit_group = event.Group(void).init(allocator),
|
||||
@ -458,11 +425,9 @@ pub const Compilation = struct {
|
||||
.root_package = undefined,
|
||||
.std_package = undefined,
|
||||
|
||||
.override_libc = null,
|
||||
.have_err_ret_tracing = false,
|
||||
.primitive_type_table = undefined,
|
||||
|
||||
// .fs_watch = undefined,
|
||||
.fs_watch = undefined,
|
||||
};
|
||||
comp.link_libs_list = ArrayList(*LinkLib).init(comp.arena());
|
||||
comp.primitive_type_table = TypeTable.init(comp.arena());
|
||||
@ -534,8 +499,8 @@ pub const Compilation = struct {
|
||||
comp.root_package = try Package.create(comp.arena(), ".", "");
|
||||
}
|
||||
|
||||
// comp.fs_watch = try fs.Watch(*Scope.Root).create(16);
|
||||
// defer comp.fs_watch.destroy();
|
||||
comp.fs_watch = try fs.Watch(*Scope.Root).init(allocator, 16);
|
||||
defer comp.fs_watch.deinit();
|
||||
|
||||
try comp.initTypes();
|
||||
defer comp.primitive_type_table.deinit();
|
||||
@ -559,7 +524,7 @@ pub const Compilation = struct {
|
||||
}
|
||||
|
||||
/// it does ref the result because it could be an arbitrary integer size
|
||||
pub async fn getPrimitiveType(comp: *Compilation, name: []const u8) !?*Type {
|
||||
pub fn getPrimitiveType(comp: *Compilation, name: []const u8) !?*Type {
|
||||
if (name.len >= 2) {
|
||||
switch (name[0]) {
|
||||
'i', 'u' => blk: {
|
||||
@ -795,47 +760,47 @@ pub const Compilation = struct {
|
||||
self.events.put(Event{ .Error = err });
|
||||
}
|
||||
|
||||
// // First, get an item from the watch channel, waiting on the channel.
|
||||
// var group = event.Group(BuildError!void).init(self.gpa());
|
||||
// {
|
||||
// const ev = (self.fs_watch.channel.get()) catch |err| {
|
||||
// build_result = err;
|
||||
// continue;
|
||||
// };
|
||||
// const root_scope = ev.data;
|
||||
// group.call(rebuildFile, self, root_scope) catch |err| {
|
||||
// build_result = err;
|
||||
// continue;
|
||||
// };
|
||||
// }
|
||||
// // Next, get all the items from the channel that are buffered up.
|
||||
// while (self.fs_watch.channel.getOrNull()) |ev_or_err| {
|
||||
// if (ev_or_err) |ev| {
|
||||
// const root_scope = ev.data;
|
||||
// group.call(rebuildFile, self, root_scope) catch |err| {
|
||||
// build_result = err;
|
||||
// continue;
|
||||
// };
|
||||
// } else |err| {
|
||||
// build_result = err;
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// build_result = group.wait();
|
||||
// First, get an item from the watch channel, waiting on the channel.
|
||||
var group = event.Group(BuildError!void).init(self.gpa());
|
||||
{
|
||||
const ev = (self.fs_watch.channel.get()) catch |err| {
|
||||
build_result = err;
|
||||
continue;
|
||||
};
|
||||
const root_scope = ev.data;
|
||||
group.call(rebuildFile, self, root_scope) catch |err| {
|
||||
build_result = err;
|
||||
continue;
|
||||
};
|
||||
}
|
||||
// Next, get all the items from the channel that are buffered up.
|
||||
while (self.fs_watch.channel.getOrNull()) |ev_or_err| {
|
||||
if (ev_or_err) |ev| {
|
||||
const root_scope = ev.data;
|
||||
group.call(rebuildFile, self, root_scope) catch |err| {
|
||||
build_result = err;
|
||||
continue;
|
||||
};
|
||||
} else |err| {
|
||||
build_result = err;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
build_result = group.wait();
|
||||
}
|
||||
}
|
||||
|
||||
async fn rebuildFile(self: *Compilation, root_scope: *Scope.Root) !void {
|
||||
async fn rebuildFile(self: *Compilation, root_scope: *Scope.Root) BuildError!void {
|
||||
const tree_scope = blk: {
|
||||
const source_code = "";
|
||||
// const source_code = fs.readFile(
|
||||
// root_scope.realpath,
|
||||
// max_src_size,
|
||||
// ) catch |err| {
|
||||
// try self.addCompileErrorCli(root_scope.realpath, "unable to open: {}", @errorName(err));
|
||||
// return;
|
||||
// };
|
||||
// errdefer self.gpa().free(source_code);
|
||||
const source_code = fs.readFile(
|
||||
self.gpa(),
|
||||
root_scope.realpath,
|
||||
max_src_size,
|
||||
) catch |err| {
|
||||
try self.addCompileErrorCli(root_scope.realpath, "unable to open: {}", @errorName(err));
|
||||
return;
|
||||
};
|
||||
errdefer self.gpa().free(source_code);
|
||||
|
||||
const tree = try std.zig.parse(self.gpa(), source_code);
|
||||
errdefer {
|
||||
@ -873,7 +838,7 @@ pub const Compilation = struct {
|
||||
try decl_group.wait();
|
||||
}
|
||||
|
||||
async fn rebuildChangedDecls(
|
||||
fn rebuildChangedDecls(
|
||||
self: *Compilation,
|
||||
group: *event.Group(BuildError!void),
|
||||
locked_table: *Decl.Table,
|
||||
@ -962,7 +927,7 @@ pub const Compilation = struct {
|
||||
}
|
||||
}
|
||||
|
||||
async fn initialCompile(self: *Compilation) !void {
|
||||
fn initialCompile(self: *Compilation) !void {
|
||||
if (self.root_src_path) |root_src_path| {
|
||||
const root_scope = blk: {
|
||||
// TODO async/await std.fs.realpath
|
||||
@ -981,7 +946,7 @@ pub const Compilation = struct {
|
||||
}
|
||||
}
|
||||
|
||||
async fn maybeLink(self: *Compilation) !void {
|
||||
fn maybeLink(self: *Compilation) !void {
|
||||
(self.prelink_group.wait()) catch |err| switch (err) {
|
||||
error.SemanticAnalysisFailed => {},
|
||||
else => return err,
|
||||
@ -1184,7 +1149,7 @@ pub const Compilation = struct {
|
||||
|
||||
/// If the temporary directory for this compilation has not been created, it creates it.
|
||||
/// Then it creates a random file name in that dir and returns it.
|
||||
pub async fn createRandomOutputPath(self: *Compilation, suffix: []const u8) !Buffer {
|
||||
pub fn createRandomOutputPath(self: *Compilation, suffix: []const u8) !Buffer {
|
||||
const tmp_dir = try self.getTmpDir();
|
||||
const file_prefix = self.getRandomFileName();
|
||||
|
||||
@ -1200,14 +1165,14 @@ pub const Compilation = struct {
|
||||
/// If the temporary directory for this Compilation has not been created, creates it.
|
||||
/// Then returns it. The directory is unique to this Compilation and cleaned up when
|
||||
/// the Compilation deinitializes.
|
||||
async fn getTmpDir(self: *Compilation) ![]const u8 {
|
||||
fn getTmpDir(self: *Compilation) ![]const u8 {
|
||||
if (self.tmp_dir.start()) |ptr| return ptr.*;
|
||||
self.tmp_dir.data = self.getTmpDirImpl();
|
||||
self.tmp_dir.resolve();
|
||||
return self.tmp_dir.data;
|
||||
}
|
||||
|
||||
async fn getTmpDirImpl(self: *Compilation) ![]u8 {
|
||||
fn getTmpDirImpl(self: *Compilation) ![]u8 {
|
||||
const comp_dir_name = self.getRandomFileName();
|
||||
const zig_dir_path = try getZigDir(self.gpa());
|
||||
defer self.gpa().free(zig_dir_path);
|
||||
@ -1217,7 +1182,7 @@ pub const Compilation = struct {
|
||||
return tmp_dir;
|
||||
}
|
||||
|
||||
async fn getRandomFileName(self: *Compilation) [12]u8 {
|
||||
fn getRandomFileName(self: *Compilation) [12]u8 {
|
||||
// here we replace the standard +/ with -_ so that it can be used in a file name
|
||||
const b64_fs_encoder = std.base64.Base64Encoder.init(
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
|
||||
@ -1243,7 +1208,7 @@ pub const Compilation = struct {
|
||||
}
|
||||
|
||||
/// Returns a value which has been ref()'d once
|
||||
async fn analyzeConstValue(
|
||||
fn analyzeConstValue(
|
||||
comp: *Compilation,
|
||||
tree_scope: *Scope.AstTree,
|
||||
scope: *Scope,
|
||||
@ -1256,7 +1221,7 @@ pub const Compilation = struct {
|
||||
return analyzed_code.getCompTimeResult(comp);
|
||||
}
|
||||
|
||||
async fn analyzeTypeExpr(comp: *Compilation, tree_scope: *Scope.AstTree, scope: *Scope, node: *ast.Node) !*Type {
|
||||
fn analyzeTypeExpr(comp: *Compilation, tree_scope: *Scope.AstTree, scope: *Scope, node: *ast.Node) !*Type {
|
||||
const meta_type = &Type.MetaType.get(comp).base;
|
||||
defer meta_type.base.deref(comp);
|
||||
|
||||
@ -1287,7 +1252,7 @@ fn parseVisibToken(tree: *ast.Tree, optional_token_index: ?ast.TokenIndex) Visib
|
||||
}
|
||||
|
||||
/// The function that actually does the generation.
|
||||
async fn generateDecl(comp: *Compilation, decl: *Decl) !void {
|
||||
fn generateDecl(comp: *Compilation, decl: *Decl) !void {
|
||||
switch (decl.id) {
|
||||
.Var => @panic("TODO"),
|
||||
.Fn => {
|
||||
@ -1298,7 +1263,7 @@ async fn generateDecl(comp: *Compilation, decl: *Decl) !void {
|
||||
}
|
||||
}
|
||||
|
||||
async fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void {
|
||||
fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void {
|
||||
const tree_scope = fn_decl.base.tree_scope;
|
||||
|
||||
const body_node = fn_decl.fn_proto.body_node orelse return generateDeclFnProto(comp, fn_decl);
|
||||
@ -1315,7 +1280,7 @@ async fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void {
|
||||
|
||||
// The Decl.Fn owns the initial 1 reference count
|
||||
const fn_val = try Value.Fn.create(comp, fn_type, fndef_scope, symbol_name);
|
||||
fn_decl.value = Decl.Fn.Val{ .Fn = fn_val };
|
||||
fn_decl.value = .{ .Fn = fn_val };
|
||||
symbol_name_consumed = true;
|
||||
|
||||
// Define local parameter variables
|
||||
@ -1382,7 +1347,7 @@ fn getZigDir(allocator: *mem.Allocator) ![]u8 {
|
||||
return std.fs.getAppDataDir(allocator, "zig");
|
||||
}
|
||||
|
||||
async fn analyzeFnType(
|
||||
fn analyzeFnType(
|
||||
comp: *Compilation,
|
||||
tree_scope: *Scope.AstTree,
|
||||
scope: *Scope,
|
||||
@ -1444,7 +1409,7 @@ async fn analyzeFnType(
|
||||
return fn_type;
|
||||
}
|
||||
|
||||
async fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void {
|
||||
fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void {
|
||||
const fn_type = try analyzeFnType(
|
||||
comp,
|
||||
fn_decl.base.tree_scope,
|
||||
@ -1459,6 +1424,6 @@ async fn generateDeclFnProto(comp: *Compilation, fn_decl: *Decl.Fn) !void {
|
||||
|
||||
// The Decl.Fn owns the initial 1 reference count
|
||||
const fn_proto_val = try Value.FnProto.create(comp, fn_type, symbol_name);
|
||||
fn_decl.value = Decl.Fn.Val{ .FnProto = fn_proto_val };
|
||||
fn_decl.value = .{ .FnProto = fn_proto_val };
|
||||
symbol_name_consumed = true;
|
||||
}
|
||||
|
||||
@ -69,15 +69,12 @@ pub const Decl = struct {
|
||||
|
||||
pub const Fn = struct {
|
||||
base: Decl,
|
||||
value: Val,
|
||||
fn_proto: *ast.Node.FnProto,
|
||||
|
||||
// TODO https://github.com/ziglang/zig/issues/683 and then make this anonymous
|
||||
pub const Val = union(enum) {
|
||||
value: union(enum) {
|
||||
Unresolved,
|
||||
Fn: *Value.Fn,
|
||||
FnProto: *Value.FnProto,
|
||||
};
|
||||
},
|
||||
fn_proto: *ast.Node.FnProto,
|
||||
|
||||
pub fn externLibName(self: Fn, tree: *ast.Tree) ?[]const u8 {
|
||||
return if (self.fn_proto.extern_export_inline_token) |tok_index| x: {
|
||||
|
||||
@ -110,7 +110,7 @@ pub const Inst = struct {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
pub async fn analyze(base: *Inst, ira: *Analyze) Analyze.Error!*Inst {
|
||||
pub fn analyze(base: *Inst, ira: *Analyze) Analyze.Error!*Inst {
|
||||
switch (base.id) {
|
||||
.Return => return @fieldParentPtr(Return, "base", base).analyze(ira),
|
||||
.Const => return @fieldParentPtr(Const, "base", base).analyze(ira),
|
||||
@ -422,7 +422,7 @@ pub const Inst = struct {
|
||||
return false;
|
||||
}
|
||||
|
||||
pub async fn analyze(self: *const Ref, ira: *Analyze) !*Inst {
|
||||
pub fn analyze(self: *const Ref, ira: *Analyze) !*Inst {
|
||||
const target = try self.params.target.getAsParam();
|
||||
|
||||
if (ira.getCompTimeValOrNullUndefOk(target)) |val| {
|
||||
@ -472,7 +472,7 @@ pub const Inst = struct {
|
||||
return false;
|
||||
}
|
||||
|
||||
pub async fn analyze(self: *const DeclRef, ira: *Analyze) !*Inst {
|
||||
pub fn analyze(self: *const DeclRef, ira: *Analyze) !*Inst {
|
||||
(ira.irb.comp.resolveDecl(self.params.decl)) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => return error.SemanticAnalysisFailed,
|
||||
@ -516,7 +516,7 @@ pub const Inst = struct {
|
||||
return false;
|
||||
}
|
||||
|
||||
pub async fn analyze(self: *const VarPtr, ira: *Analyze) !*Inst {
|
||||
pub fn analyze(self: *const VarPtr, ira: *Analyze) !*Inst {
|
||||
switch (self.params.var_scope.data) {
|
||||
.Const => @panic("TODO"),
|
||||
.Param => |param| {
|
||||
@ -563,7 +563,7 @@ pub const Inst = struct {
|
||||
return false;
|
||||
}
|
||||
|
||||
pub async fn analyze(self: *const LoadPtr, ira: *Analyze) !*Inst {
|
||||
pub fn analyze(self: *const LoadPtr, ira: *Analyze) !*Inst {
|
||||
const target = try self.params.target.getAsParam();
|
||||
const target_type = target.getKnownType();
|
||||
if (target_type.id != .Pointer) {
|
||||
@ -645,7 +645,7 @@ pub const Inst = struct {
|
||||
return false;
|
||||
}
|
||||
|
||||
pub async fn analyze(self: *const PtrType, ira: *Analyze) !*Inst {
|
||||
pub fn analyze(self: *const PtrType, ira: *Analyze) !*Inst {
|
||||
const child_type = try self.params.child_type.getAsConstType(ira);
|
||||
// if (child_type->id == TypeTableEntryIdUnreachable) {
|
||||
// ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed"));
|
||||
@ -927,7 +927,7 @@ pub const Variable = struct {
|
||||
|
||||
pub const BasicBlock = struct {
|
||||
ref_count: usize,
|
||||
name_hint: [*]const u8, // must be a C string literal
|
||||
name_hint: [*:0]const u8,
|
||||
debug_id: usize,
|
||||
scope: *Scope,
|
||||
instruction_list: std.ArrayList(*Inst),
|
||||
@ -1051,7 +1051,7 @@ pub const Builder = struct {
|
||||
}
|
||||
|
||||
/// No need to clean up resources thanks to the arena allocator.
|
||||
pub fn createBasicBlock(self: *Builder, scope: *Scope, name_hint: [*]const u8) !*BasicBlock {
|
||||
pub fn createBasicBlock(self: *Builder, scope: *Scope, name_hint: [*:0]const u8) !*BasicBlock {
|
||||
const basic_block = try self.arena().create(BasicBlock);
|
||||
basic_block.* = BasicBlock{
|
||||
.ref_count = 0,
|
||||
@ -1186,6 +1186,7 @@ pub const Builder = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn genCall(irb: *Builder, suffix_op: *ast.Node.SuffixOp, call: *ast.Node.SuffixOp.Op.Call, scope: *Scope) !*Inst {
|
||||
async fn genCall(irb: *Builder, suffix_op: *ast.Node.SuffixOp, call: *ast.Node.SuffixOp.Op.Call, scope: *Scope) !*Inst {
|
||||
const fn_ref = try irb.genNode(suffix_op.lhs, scope, .None);
|
||||
|
||||
@ -1214,7 +1215,7 @@ pub const Builder = struct {
|
||||
//return ir_lval_wrap(irb, scope, fn_call, lval);
|
||||
}
|
||||
|
||||
async fn genPtrType(
|
||||
fn genPtrType(
|
||||
irb: *Builder,
|
||||
prefix_op: *ast.Node.PrefixOp,
|
||||
ptr_info: ast.Node.PrefixOp.PtrInfo,
|
||||
@ -1307,9 +1308,9 @@ pub const Builder = struct {
|
||||
var rest: []const u8 = undefined;
|
||||
if (int_token.len >= 3 and int_token[0] == '0') {
|
||||
base = switch (int_token[1]) {
|
||||
'b' => u8(2),
|
||||
'o' => u8(8),
|
||||
'x' => u8(16),
|
||||
'b' => 2,
|
||||
'o' => 8,
|
||||
'x' => 16,
|
||||
else => unreachable,
|
||||
};
|
||||
rest = int_token[2..];
|
||||
@ -1339,7 +1340,7 @@ pub const Builder = struct {
|
||||
return inst;
|
||||
}
|
||||
|
||||
pub async fn genStrLit(irb: *Builder, str_lit: *ast.Node.StringLiteral, scope: *Scope) !*Inst {
|
||||
pub fn genStrLit(irb: *Builder, str_lit: *ast.Node.StringLiteral, scope: *Scope) !*Inst {
|
||||
const str_token = irb.code.tree_scope.tree.tokenSlice(str_lit.token);
|
||||
const src_span = Span.token(str_lit.token);
|
||||
|
||||
@ -1389,7 +1390,7 @@ pub const Builder = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn genBlock(irb: *Builder, block: *ast.Node.Block, parent_scope: *Scope) !*Inst {
|
||||
pub fn genBlock(irb: *Builder, block: *ast.Node.Block, parent_scope: *Scope) !*Inst {
|
||||
const block_scope = try Scope.Block.create(irb.comp, parent_scope);
|
||||
|
||||
const outer_block_scope = &block_scope.base;
|
||||
@ -1499,7 +1500,7 @@ pub const Builder = struct {
|
||||
return irb.buildConstVoid(child_scope, Span.token(block.rbrace), true);
|
||||
}
|
||||
|
||||
pub async fn genControlFlowExpr(
|
||||
pub fn genControlFlowExpr(
|
||||
irb: *Builder,
|
||||
control_flow_expr: *ast.Node.ControlFlowExpression,
|
||||
scope: *Scope,
|
||||
@ -1596,7 +1597,7 @@ pub const Builder = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn genIdentifier(irb: *Builder, identifier: *ast.Node.Identifier, scope: *Scope, lval: LVal) !*Inst {
|
||||
pub fn genIdentifier(irb: *Builder, identifier: *ast.Node.Identifier, scope: *Scope, lval: LVal) !*Inst {
|
||||
const src_span = Span.token(identifier.token);
|
||||
const name = irb.code.tree_scope.tree.tokenSlice(identifier.token);
|
||||
|
||||
@ -1694,7 +1695,7 @@ pub const Builder = struct {
|
||||
return result;
|
||||
}
|
||||
|
||||
async fn genDefersForBlock(
|
||||
fn genDefersForBlock(
|
||||
irb: *Builder,
|
||||
inner_scope: *Scope,
|
||||
outer_scope: *Scope,
|
||||
@ -1797,7 +1798,7 @@ pub const Builder = struct {
|
||||
// Look at the params and ref() other instructions
|
||||
comptime var i = 0;
|
||||
inline while (i < @memberCount(I.Params)) : (i += 1) {
|
||||
const FieldType = comptime @typeOf(@field(I.Params(undefined), @memberName(I.Params, i)));
|
||||
const FieldType = comptime @typeOf(@field(@as(I.Params, undefined), @memberName(I.Params, i)));
|
||||
switch (FieldType) {
|
||||
*Inst => @field(inst.params, @memberName(I.Params, i)).ref(self),
|
||||
*BasicBlock => @field(inst.params, @memberName(I.Params, i)).ref(self),
|
||||
@ -1909,7 +1910,7 @@ pub const Builder = struct {
|
||||
VarScope: *Scope.Var,
|
||||
};
|
||||
|
||||
async fn findIdent(irb: *Builder, scope: *Scope, name: []const u8) Ident {
|
||||
fn findIdent(irb: *Builder, scope: *Scope, name: []const u8) Ident {
|
||||
var s = scope;
|
||||
while (true) {
|
||||
switch (s.id) {
|
||||
@ -2519,7 +2520,7 @@ const Analyze = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub async fn gen(
|
||||
pub fn gen(
|
||||
comp: *Compilation,
|
||||
body_node: *ast.Node,
|
||||
tree_scope: *Scope.AstTree,
|
||||
@ -2541,7 +2542,7 @@ pub async fn gen(
|
||||
return irb.finish();
|
||||
}
|
||||
|
||||
pub async fn analyze(comp: *Compilation, old_code: *Code, expected_type: ?*Type) !*Code {
|
||||
pub fn analyze(comp: *Compilation, old_code: *Code, expected_type: ?*Type) !*Code {
|
||||
const old_entry_bb = old_code.basic_block_list.at(0);
|
||||
|
||||
var ira = try Analyze.init(comp, old_code.tree_scope, expected_type);
|
||||
|
||||
@ -143,7 +143,7 @@ pub const LibCInstallation = struct {
|
||||
}
|
||||
|
||||
/// Finds the default, native libc.
|
||||
pub async fn findNative(self: *LibCInstallation, allocator: *Allocator) !void {
|
||||
pub fn findNative(self: *LibCInstallation, allocator: *Allocator) !void {
|
||||
self.initEmpty();
|
||||
var group = event.Group(FindError!void).init(allocator);
|
||||
errdefer group.wait() catch {};
|
||||
@ -393,7 +393,7 @@ pub const LibCInstallation = struct {
|
||||
};
|
||||
|
||||
/// caller owns returned memory
|
||||
async fn ccPrintFileName(allocator: *Allocator, o_file: []const u8, want_dirname: bool) ![]u8 {
|
||||
fn ccPrintFileName(allocator: *Allocator, o_file: []const u8, want_dirname: bool) ![]u8 {
|
||||
const cc_exe = std.os.getenv("CC") orelse "cc";
|
||||
const arg1 = try std.fmt.allocPrint(allocator, "-print-file-name={}", o_file);
|
||||
defer allocator.free(arg1);
|
||||
|
||||
@ -11,7 +11,7 @@ const util = @import("util.zig");
|
||||
const Context = struct {
|
||||
comp: *Compilation,
|
||||
arena: std.heap.ArenaAllocator,
|
||||
args: std.ArrayList([*]const u8),
|
||||
args: std.ArrayList([*:0]const u8),
|
||||
link_in_crt: bool,
|
||||
|
||||
link_err: error{OutOfMemory}!void,
|
||||
@ -21,7 +21,7 @@ const Context = struct {
|
||||
out_file_path: std.Buffer,
|
||||
};
|
||||
|
||||
pub async fn link(comp: *Compilation) !void {
|
||||
pub fn link(comp: *Compilation) !void {
|
||||
var ctx = Context{
|
||||
.comp = comp,
|
||||
.arena = std.heap.ArenaAllocator.init(comp.gpa()),
|
||||
@ -33,7 +33,7 @@ pub async fn link(comp: *Compilation) !void {
|
||||
.out_file_path = undefined,
|
||||
};
|
||||
defer ctx.arena.deinit();
|
||||
ctx.args = std.ArrayList([*]const u8).init(&ctx.arena.allocator);
|
||||
ctx.args = std.ArrayList([*:0]const u8).init(&ctx.arena.allocator);
|
||||
ctx.link_msg = std.Buffer.initNull(&ctx.arena.allocator);
|
||||
|
||||
if (comp.link_out_file) |out_file| {
|
||||
@ -171,7 +171,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
|
||||
//}
|
||||
|
||||
try ctx.args.append("-o");
|
||||
try ctx.args.append(ctx.out_file_path.ptr());
|
||||
try ctx.args.append(ctx.out_file_path.toSliceConst());
|
||||
|
||||
if (ctx.link_in_crt) {
|
||||
const crt1o = if (ctx.comp.is_static) "crt1.o" else "Scrt1.o";
|
||||
@ -214,10 +214,11 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
|
||||
|
||||
if (ctx.comp.haveLibC()) {
|
||||
try ctx.args.append("-L");
|
||||
try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.lib_dir.?)).ptr);
|
||||
// TODO addNullByte should probably return [:0]u8
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, (try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.lib_dir.?)).ptr));
|
||||
|
||||
try ctx.args.append("-L");
|
||||
try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.static_lib_dir.?)).ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, (try std.cstr.addNullByte(&ctx.arena.allocator, ctx.libc.static_lib_dir.?)).ptr));
|
||||
|
||||
if (!ctx.comp.is_static) {
|
||||
const dl = blk: {
|
||||
@ -226,7 +227,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
|
||||
return error.LibCMissingDynamicLinker;
|
||||
};
|
||||
try ctx.args.append("-dynamic-linker");
|
||||
try ctx.args.append((try std.cstr.addNullByte(&ctx.arena.allocator, dl)).ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, (try std.cstr.addNullByte(&ctx.arena.allocator, dl)).ptr));
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,7 +239,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
|
||||
// .o files
|
||||
for (ctx.comp.link_objects) |link_object| {
|
||||
const link_obj_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, link_object);
|
||||
try ctx.args.append(link_obj_with_null.ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, link_obj_with_null.ptr));
|
||||
}
|
||||
try addFnObjects(ctx);
|
||||
|
||||
@ -313,7 +314,7 @@ fn constructLinkerArgsElf(ctx: *Context) !void {
|
||||
fn addPathJoin(ctx: *Context, dirname: []const u8, basename: []const u8) !void {
|
||||
const full_path = try std.fs.path.join(&ctx.arena.allocator, [_][]const u8{ dirname, basename });
|
||||
const full_path_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, full_path);
|
||||
try ctx.args.append(full_path_with_null.ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, full_path_with_null.ptr));
|
||||
}
|
||||
|
||||
fn constructLinkerArgsCoff(ctx: *Context) !void {
|
||||
@ -339,12 +340,12 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
|
||||
const is_library = ctx.comp.kind == .Lib;
|
||||
|
||||
const out_arg = try std.fmt.allocPrint(&ctx.arena.allocator, "-OUT:{}\x00", ctx.out_file_path.toSliceConst());
|
||||
try ctx.args.append(out_arg.ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, out_arg.ptr));
|
||||
|
||||
if (ctx.comp.haveLibC()) {
|
||||
try ctx.args.append((try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.msvc_lib_dir.?)).ptr);
|
||||
try ctx.args.append((try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.kernel32_lib_dir.?)).ptr);
|
||||
try ctx.args.append((try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.lib_dir.?)).ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, (try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.msvc_lib_dir.?)).ptr));
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, (try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.kernel32_lib_dir.?)).ptr));
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, (try std.fmt.allocPrint(&ctx.arena.allocator, "-LIBPATH:{}\x00", ctx.libc.lib_dir.?)).ptr));
|
||||
}
|
||||
|
||||
if (ctx.link_in_crt) {
|
||||
@ -353,17 +354,17 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
|
||||
|
||||
if (ctx.comp.is_static) {
|
||||
const cmt_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "libcmt{}.lib\x00", d_str);
|
||||
try ctx.args.append(cmt_lib_name.ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, cmt_lib_name.ptr));
|
||||
} else {
|
||||
const msvcrt_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "msvcrt{}.lib\x00", d_str);
|
||||
try ctx.args.append(msvcrt_lib_name.ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, msvcrt_lib_name.ptr));
|
||||
}
|
||||
|
||||
const vcruntime_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "{}vcruntime{}.lib\x00", lib_str, d_str);
|
||||
try ctx.args.append(vcruntime_lib_name.ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, vcruntime_lib_name.ptr));
|
||||
|
||||
const crt_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "{}ucrt{}.lib\x00", lib_str, d_str);
|
||||
try ctx.args.append(crt_lib_name.ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, crt_lib_name.ptr));
|
||||
|
||||
// Visual C++ 2015 Conformance Changes
|
||||
// https://msdn.microsoft.com/en-us/library/bb531344.aspx
|
||||
@ -395,7 +396,7 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
|
||||
|
||||
for (ctx.comp.link_objects) |link_object| {
|
||||
const link_obj_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, link_object);
|
||||
try ctx.args.append(link_obj_with_null.ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, link_obj_with_null.ptr));
|
||||
}
|
||||
try addFnObjects(ctx);
|
||||
|
||||
@ -504,11 +505,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
|
||||
//}
|
||||
|
||||
try ctx.args.append("-arch");
|
||||
const darwin_arch_str = try std.cstr.addNullByte(
|
||||
&ctx.arena.allocator,
|
||||
ctx.comp.target.getDarwinArchString(),
|
||||
);
|
||||
try ctx.args.append(darwin_arch_str.ptr);
|
||||
try ctx.args.append(util.getDarwinArchString(ctx.comp.target));
|
||||
|
||||
const platform = try DarwinPlatform.get(ctx.comp);
|
||||
switch (platform.kind) {
|
||||
@ -517,7 +514,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
|
||||
.IPhoneOSSimulator => try ctx.args.append("-ios_simulator_version_min"),
|
||||
}
|
||||
const ver_str = try std.fmt.allocPrint(&ctx.arena.allocator, "{}.{}.{}\x00", platform.major, platform.minor, platform.micro);
|
||||
try ctx.args.append(ver_str.ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, ver_str.ptr));
|
||||
|
||||
if (ctx.comp.kind == .Exe) {
|
||||
if (ctx.comp.is_static) {
|
||||
@ -528,7 +525,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
|
||||
}
|
||||
|
||||
try ctx.args.append("-o");
|
||||
try ctx.args.append(ctx.out_file_path.ptr());
|
||||
try ctx.args.append(ctx.out_file_path.toSliceConst());
|
||||
|
||||
//for (size_t i = 0; i < g->rpath_list.length; i += 1) {
|
||||
// Buf *rpath = g->rpath_list.at(i);
|
||||
@ -572,7 +569,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
|
||||
|
||||
for (ctx.comp.link_objects) |link_object| {
|
||||
const link_obj_with_null = try std.cstr.addNullByte(&ctx.arena.allocator, link_object);
|
||||
try ctx.args.append(link_obj_with_null.ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, link_obj_with_null.ptr));
|
||||
}
|
||||
try addFnObjects(ctx);
|
||||
|
||||
@ -593,10 +590,10 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
|
||||
} else {
|
||||
if (mem.indexOfScalar(u8, lib.name, '/') == null) {
|
||||
const arg = try std.fmt.allocPrint(&ctx.arena.allocator, "-l{}\x00", lib.name);
|
||||
try ctx.args.append(arg.ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, arg.ptr));
|
||||
} else {
|
||||
const arg = try std.cstr.addNullByte(&ctx.arena.allocator, lib.name);
|
||||
try ctx.args.append(arg.ptr);
|
||||
try ctx.args.append(@ptrCast([*:0]const u8, arg.ptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -639,7 +636,7 @@ fn addFnObjects(ctx: *Context) !void {
|
||||
ctx.comp.gpa().destroy(node);
|
||||
continue;
|
||||
};
|
||||
try ctx.args.append(fn_val.containing_object.ptr());
|
||||
try ctx.args.append(fn_val.containing_object.toSliceConst());
|
||||
it = node.next;
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ pub const AddGlobal = LLVMAddGlobal;
|
||||
extern fn LLVMAddGlobal(M: *Module, Ty: *Type, Name: [*:0]const u8) ?*Value;
|
||||
|
||||
pub const ConstStringInContext = LLVMConstStringInContext;
|
||||
extern fn LLVMConstStringInContext(C: *Context, Str: [*:0]const u8, Length: c_uint, DontNullTerminate: Bool) ?*Value;
|
||||
extern fn LLVMConstStringInContext(C: *Context, Str: [*]const u8, Length: c_uint, DontNullTerminate: Bool) ?*Value;
|
||||
|
||||
pub const ConstInt = LLVMConstInt;
|
||||
extern fn LLVMConstInt(IntTy: *Type, N: c_ulonglong, SignExtend: Bool) ?*Value;
|
||||
|
||||
@ -126,7 +126,8 @@ pub fn main() !void {
|
||||
|
||||
try stderr.print("unknown command: {}\n\n", args[1]);
|
||||
try stderr.write(usage);
|
||||
process.exit(1);
|
||||
process.argsFree(allocator, args);
|
||||
defer process.exit(1);
|
||||
}
|
||||
|
||||
const usage_build_generic =
|
||||
@ -461,13 +462,12 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
|
||||
comp.link_objects = link_objects;
|
||||
|
||||
comp.start();
|
||||
const frame = async processBuildEvents(comp, color);
|
||||
processBuildEvents(comp, color);
|
||||
}
|
||||
|
||||
async fn processBuildEvents(comp: *Compilation, color: errmsg.Color) void {
|
||||
fn processBuildEvents(comp: *Compilation, color: errmsg.Color) void {
|
||||
var count: usize = 0;
|
||||
while (true) {
|
||||
// TODO directly awaiting async should guarantee memory allocation elision
|
||||
while (true) { // TODO(Vexu)
|
||||
const build_event = comp.events.get();
|
||||
count += 1;
|
||||
|
||||
@ -567,10 +567,6 @@ fn cmdLibC(allocator: *Allocator, args: []const []const u8) !void {
|
||||
var zig_compiler = try ZigCompiler.init(allocator);
|
||||
defer zig_compiler.deinit();
|
||||
|
||||
const frame = async findLibCAsync(&zig_compiler);
|
||||
}
|
||||
|
||||
async fn findLibCAsync(zig_compiler: *ZigCompiler) void {
|
||||
const libc = zig_compiler.getNativeLibC() catch |err| {
|
||||
stderr.print("unable to find libc: {}\n", @errorName(err)) catch process.exit(1);
|
||||
process.exit(1);
|
||||
@ -644,11 +640,23 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
return asyncFmtMain(
|
||||
allocator,
|
||||
&flags,
|
||||
color,
|
||||
);
|
||||
var fmt = Fmt{
|
||||
.allocator = allocator,
|
||||
.seen = event.Locked(Fmt.SeenMap).init(Fmt.SeenMap.init(allocator)),
|
||||
.any_error = false,
|
||||
.color = color,
|
||||
};
|
||||
|
||||
const check_mode = flags.present("check");
|
||||
|
||||
var group = event.Group(FmtError!void).init(allocator);
|
||||
for (flags.positionals.toSliceConst()) |file_path| {
|
||||
try group.call(fmtPath, &fmt, file_path, check_mode);
|
||||
}
|
||||
try group.wait();
|
||||
if (fmt.any_error) {
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
const FmtError = error{
|
||||
@ -673,30 +681,6 @@ const FmtError = error{
|
||||
CurrentWorkingDirectoryUnlinked,
|
||||
} || fs.File.OpenError;
|
||||
|
||||
async fn asyncFmtMain(
|
||||
allocator: *Allocator,
|
||||
flags: *const Args,
|
||||
color: errmsg.Color,
|
||||
) FmtError!void {
|
||||
var fmt = Fmt{
|
||||
.allocator = allocator,
|
||||
.seen = event.Locked(Fmt.SeenMap).init(Fmt.SeenMap.init(allocator)),
|
||||
.any_error = false,
|
||||
.color = color,
|
||||
};
|
||||
|
||||
const check_mode = flags.present("check");
|
||||
|
||||
var group = event.Group(FmtError!void).init(allocator);
|
||||
for (flags.positionals.toSliceConst()) |file_path| {
|
||||
try group.call(fmtPath, &fmt, file_path, check_mode);
|
||||
}
|
||||
try group.wait();
|
||||
if (fmt.any_error) {
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void {
|
||||
const file_path = try std.mem.dupe(fmt.allocator, u8, file_path_ref);
|
||||
defer fmt.allocator.free(file_path);
|
||||
@ -708,33 +692,33 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro
|
||||
if (try held.value.put(file_path, {})) |_| return;
|
||||
}
|
||||
|
||||
const source_code = "";
|
||||
// const source_code = event.fs.readFile(
|
||||
// file_path,
|
||||
// max_src_size,
|
||||
// ) catch |err| switch (err) {
|
||||
// error.IsDir, error.AccessDenied => {
|
||||
// // TODO make event based (and dir.next())
|
||||
// var dir = try fs.Dir.cwd().openDirList(file_path);
|
||||
// defer dir.close();
|
||||
const source_code = event.fs.readFile(
|
||||
fmt.allocator,
|
||||
file_path,
|
||||
max_src_size,
|
||||
) catch |err| switch (err) {
|
||||
error.IsDir, error.AccessDenied => {
|
||||
var dir = try fs.Dir.cwd().openDirList(file_path);
|
||||
defer dir.close();
|
||||
|
||||
// var group = event.Group(FmtError!void).init(fmt.allocator);
|
||||
// while (try dir.next()) |entry| {
|
||||
// if (entry.kind == fs.Dir.Entry.Kind.Directory or mem.endsWith(u8, entry.name, ".zig")) {
|
||||
// const full_path = try fs.path.join(fmt.allocator, [_][]const u8{ file_path, entry.name });
|
||||
// try group.call(fmtPath, fmt, full_path, check_mode);
|
||||
// }
|
||||
// }
|
||||
// return group.wait();
|
||||
// },
|
||||
// else => {
|
||||
// // TODO lock stderr printing
|
||||
// try stderr.print("unable to open '{}': {}\n", file_path, err);
|
||||
// fmt.any_error = true;
|
||||
// return;
|
||||
// },
|
||||
// };
|
||||
// defer fmt.allocator.free(source_code);
|
||||
var group = event.Group(FmtError!void).init(fmt.allocator);
|
||||
var it = dir.iterate();
|
||||
while (try it.next()) |entry| {
|
||||
if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) {
|
||||
const full_path = try fs.path.join(fmt.allocator, [_][]const u8{ file_path, entry.name });
|
||||
try group.call(fmtPath, fmt, full_path, check_mode);
|
||||
}
|
||||
}
|
||||
return group.wait();
|
||||
},
|
||||
else => {
|
||||
// TODO lock stderr printing
|
||||
try stderr.print("unable to open '{}': {}\n", file_path, err);
|
||||
fmt.any_error = true;
|
||||
return;
|
||||
},
|
||||
};
|
||||
defer fmt.allocator.free(source_code);
|
||||
|
||||
const tree = std.zig.parse(fmt.allocator, source_code) catch |err| {
|
||||
try stderr.print("error parsing file '{}': {}\n", file_path, err);
|
||||
|
||||
@ -116,7 +116,7 @@ pub const TestContext = struct {
|
||||
const file_index = try std.fmt.bufPrint(file_index_buf[0..], "{}", self.file_index.incr());
|
||||
const file1_path = try std.fs.path.join(allocator, [_][]const u8{ tmp_dir_name, file_index, file1 });
|
||||
|
||||
const output_file = try std.fmt.allocPrint(allocator, "{}-out{}", file1_path, (Target{.Native = {}}).exeFileExt());
|
||||
const output_file = try std.fmt.allocPrint(allocator, "{}-out{}", file1_path, (Target{ .Native = {} }).exeFileExt());
|
||||
if (std.fs.path.dirname(file1_path)) |dirname| {
|
||||
try std.fs.makePath(allocator, dirname);
|
||||
}
|
||||
@ -148,15 +148,12 @@ pub const TestContext = struct {
|
||||
exe_file: []const u8,
|
||||
expected_output: []const u8,
|
||||
) anyerror!void {
|
||||
// TODO this should not be necessary
|
||||
const exe_file_2 = try std.mem.dupe(allocator, u8, exe_file);
|
||||
|
||||
defer comp.destroy();
|
||||
const build_event = comp.events.get();
|
||||
|
||||
switch (build_event) {
|
||||
.Ok => {
|
||||
const argv = [_][]const u8{exe_file_2};
|
||||
const argv = [_][]const u8{exe_file};
|
||||
// TODO use event loop
|
||||
const child = try std.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024);
|
||||
switch (child.term) {
|
||||
@ -173,8 +170,8 @@ pub const TestContext = struct {
|
||||
return error.OutputMismatch;
|
||||
}
|
||||
},
|
||||
Compilation.Event.Error => |err| return err,
|
||||
Compilation.Event.Fail => |msgs| {
|
||||
.Error => |err| return err,
|
||||
.Fail => |msgs| {
|
||||
const stderr = std.io.getStdErr();
|
||||
try stderr.write("build incorrectly failed:\n");
|
||||
for (msgs) |msg| {
|
||||
|
||||
@ -53,7 +53,7 @@ pub const Type = struct {
|
||||
base: *Type,
|
||||
allocator: *Allocator,
|
||||
llvm_context: *llvm.Context,
|
||||
) (error{OutOfMemory}!*llvm.Type) {
|
||||
) error{OutOfMemory}!*llvm.Type {
|
||||
switch (base.id) {
|
||||
.Struct => return @fieldParentPtr(Struct, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.Fn => return @fieldParentPtr(Fn, "base", base).getLlvmType(allocator, llvm_context),
|
||||
@ -184,7 +184,7 @@ pub const Type = struct {
|
||||
|
||||
/// If you happen to have an llvm context handy, use getAbiAlignmentInContext instead.
|
||||
/// Otherwise, this one will grab one from the pool and then release it.
|
||||
pub async fn getAbiAlignment(base: *Type, comp: *Compilation) !u32 {
|
||||
pub fn getAbiAlignment(base: *Type, comp: *Compilation) !u32 {
|
||||
if (base.abi_alignment.start()) |ptr| return ptr.*;
|
||||
|
||||
{
|
||||
@ -200,7 +200,7 @@ pub const Type = struct {
|
||||
}
|
||||
|
||||
/// If you have an llvm conext handy, you can use it here.
|
||||
pub async fn getAbiAlignmentInContext(base: *Type, comp: *Compilation, llvm_context: *llvm.Context) !u32 {
|
||||
pub fn getAbiAlignmentInContext(base: *Type, comp: *Compilation, llvm_context: *llvm.Context) !u32 {
|
||||
if (base.abi_alignment.start()) |ptr| return ptr.*;
|
||||
|
||||
base.abi_alignment.data = base.resolveAbiAlignment(comp, llvm_context);
|
||||
@ -209,7 +209,7 @@ pub const Type = struct {
|
||||
}
|
||||
|
||||
/// Lower level function that does the work. See getAbiAlignment.
|
||||
async fn resolveAbiAlignment(base: *Type, comp: *Compilation, llvm_context: *llvm.Context) !u32 {
|
||||
fn resolveAbiAlignment(base: *Type, comp: *Compilation, llvm_context: *llvm.Context) !u32 {
|
||||
const llvm_type = try base.getLlvmType(comp.gpa(), llvm_context);
|
||||
return @intCast(u32, llvm.ABIAlignmentOfType(comp.target_data_ref, llvm_type));
|
||||
}
|
||||
@ -367,7 +367,7 @@ pub const Type = struct {
|
||||
}
|
||||
|
||||
/// takes ownership of key.Normal.params on success
|
||||
pub async fn get(comp: *Compilation, key: Key) !*Fn {
|
||||
pub fn get(comp: *Compilation, key: Key) !*Fn {
|
||||
{
|
||||
const held = comp.fn_type_table.acquire();
|
||||
defer held.release();
|
||||
@ -564,7 +564,7 @@ pub const Type = struct {
|
||||
return comp.u8_type;
|
||||
}
|
||||
|
||||
pub async fn get(comp: *Compilation, key: Key) !*Int {
|
||||
pub fn get(comp: *Compilation, key: Key) !*Int {
|
||||
{
|
||||
const held = comp.int_type_table.acquire();
|
||||
defer held.release();
|
||||
@ -606,7 +606,7 @@ pub const Type = struct {
|
||||
comp.registerGarbage(Int, &self.garbage_node);
|
||||
}
|
||||
|
||||
pub async fn gcDestroy(self: *Int, comp: *Compilation) void {
|
||||
pub fn gcDestroy(self: *Int, comp: *Compilation) void {
|
||||
{
|
||||
const held = comp.int_type_table.acquire();
|
||||
defer held.release();
|
||||
@ -700,7 +700,7 @@ pub const Type = struct {
|
||||
comp.registerGarbage(Pointer, &self.garbage_node);
|
||||
}
|
||||
|
||||
pub async fn gcDestroy(self: *Pointer, comp: *Compilation) void {
|
||||
pub fn gcDestroy(self: *Pointer, comp: *Compilation) void {
|
||||
{
|
||||
const held = comp.ptr_type_table.acquire();
|
||||
defer held.release();
|
||||
@ -711,14 +711,14 @@ pub const Type = struct {
|
||||
comp.gpa().destroy(self);
|
||||
}
|
||||
|
||||
pub async fn getAlignAsInt(self: *Pointer, comp: *Compilation) u32 {
|
||||
pub fn getAlignAsInt(self: *Pointer, comp: *Compilation) u32 {
|
||||
switch (self.key.alignment) {
|
||||
.Abi => return self.key.child_type.getAbiAlignment(comp),
|
||||
.Override => |alignment| return alignment,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get(
|
||||
pub fn get(
|
||||
comp: *Compilation,
|
||||
key: Key,
|
||||
) !*Pointer {
|
||||
@ -828,7 +828,7 @@ pub const Type = struct {
|
||||
comp.gpa().destroy(self);
|
||||
}
|
||||
|
||||
pub async fn get(comp: *Compilation, key: Key) !*Array {
|
||||
pub fn get(comp: *Compilation, key: Key) !*Array {
|
||||
key.elem_type.base.ref();
|
||||
errdefer key.elem_type.base.deref(comp);
|
||||
|
||||
|
||||
@ -32,21 +32,21 @@ pub fn getFloatAbi(self: Target) FloatAbi {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getObjectFormat(self: Target) Target.ObjectFormat {
|
||||
return switch (self) {
|
||||
.Native => @import("builtin").object_format,
|
||||
.Cross => {
|
||||
pub fn getObjectFormat(target: Target) Target.ObjectFormat {
|
||||
switch (target) {
|
||||
.Native => return @import("builtin").object_format,
|
||||
.Cross => blk: {
|
||||
if (target.isWindows() or target.isUefi()) {
|
||||
break .coff;
|
||||
return .coff;
|
||||
} else if (target.isDarwin()) {
|
||||
break .macho;
|
||||
return .macho;
|
||||
}
|
||||
if (target.isWasm()) {
|
||||
break .wasm;
|
||||
return .wasm;
|
||||
}
|
||||
break .elf;
|
||||
return .elf;
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getDynamicLinkerPath(self: Target) ?[]const u8 {
|
||||
@ -156,7 +156,7 @@ pub fn getDynamicLinkerPath(self: Target) ?[]const u8 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getDarwinArchString(self: Target) []const u8 {
|
||||
pub fn getDarwinArchString(self: Target) [:0]const u8 {
|
||||
const arch = self.getArch();
|
||||
switch (arch) {
|
||||
.aarch64 => return "arm64",
|
||||
@ -166,7 +166,8 @@ pub fn getDarwinArchString(self: Target) []const u8 {
|
||||
.powerpc => return "ppc",
|
||||
.powerpc64 => return "ppc64",
|
||||
.powerpc64le => return "ppc64le",
|
||||
else => return @tagName(arch),
|
||||
// @tagName should be able to return sentinel terminated slice
|
||||
else => @panic("TODO"), //return @tagName(arch),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -156,7 +156,7 @@ pub const Value = struct {
|
||||
const llvm_fn_type = try self.base.typ.getLlvmType(ofile.arena, ofile.context);
|
||||
const llvm_fn = llvm.AddFunction(
|
||||
ofile.module,
|
||||
self.symbol_name.ptr(),
|
||||
self.symbol_name.toSliceConst(),
|
||||
llvm_fn_type,
|
||||
) orelse return error.OutOfMemory;
|
||||
|
||||
@ -241,7 +241,7 @@ pub const Value = struct {
|
||||
const llvm_fn_type = try self.base.typ.getLlvmType(ofile.arena, ofile.context);
|
||||
const llvm_fn = llvm.AddFunction(
|
||||
ofile.module,
|
||||
self.symbol_name.ptr(),
|
||||
self.symbol_name.toSliceConst(),
|
||||
llvm_fn_type,
|
||||
) orelse return error.OutOfMemory;
|
||||
|
||||
@ -334,7 +334,7 @@ pub const Value = struct {
|
||||
field_index: usize,
|
||||
};
|
||||
|
||||
pub async fn createArrayElemPtr(
|
||||
pub fn createArrayElemPtr(
|
||||
comp: *Compilation,
|
||||
array_val: *Array,
|
||||
mut: Type.Pointer.Mut,
|
||||
@ -390,13 +390,13 @@ pub const Value = struct {
|
||||
const array_llvm_value = (try base_array.val.getLlvmConst(ofile)).?;
|
||||
const ptr_bit_count = ofile.comp.target_ptr_bits;
|
||||
const usize_llvm_type = llvm.IntTypeInContext(ofile.context, ptr_bit_count) orelse return error.OutOfMemory;
|
||||
const indices = [_]*llvm.Value{
|
||||
var indices = [_]*llvm.Value{
|
||||
llvm.ConstNull(usize_llvm_type) orelse return error.OutOfMemory,
|
||||
llvm.ConstInt(usize_llvm_type, base_array.elem_index, 0) orelse return error.OutOfMemory,
|
||||
};
|
||||
return llvm.ConstInBoundsGEP(
|
||||
array_llvm_value,
|
||||
&indices,
|
||||
@ptrCast([*]*llvm.Value, &indices),
|
||||
@intCast(c_uint, indices.len),
|
||||
) orelse return error.OutOfMemory;
|
||||
},
|
||||
@ -423,7 +423,7 @@ pub const Value = struct {
|
||||
};
|
||||
|
||||
/// Takes ownership of buffer
|
||||
pub async fn createOwnedBuffer(comp: *Compilation, buffer: []u8) !*Array {
|
||||
pub fn createOwnedBuffer(comp: *Compilation, buffer: []u8) !*Array {
|
||||
const u8_type = Type.Int.get_u8(comp);
|
||||
defer u8_type.base.base.deref(comp);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user