self hosted compiler: use enum literals
parent
7000316113
commit
c6076a1360
|
@ -119,9 +119,9 @@ pub const Args = struct {
|
|||
|
||||
// MergeN creation disallows 0 length flag entry (doesn't make sense)
|
||||
switch (flag_args) {
|
||||
FlagArg.None => unreachable,
|
||||
FlagArg.Single => |inner| try prev.append(inner),
|
||||
FlagArg.Many => |inner| try prev.appendSlice(inner.toSliceConst()),
|
||||
.None => unreachable,
|
||||
.Single => |inner| try prev.append(inner),
|
||||
.Many => |inner| try prev.appendSlice(inner.toSliceConst()),
|
||||
}
|
||||
|
||||
_ = try parsed.flags.put(flag_name_trimmed, FlagArg{ .Many = prev });
|
||||
|
@ -158,7 +158,7 @@ pub const Args = struct {
|
|||
pub fn single(self: *Args, name: []const u8) ?[]const u8 {
|
||||
if (self.flags.get(name)) |entry| {
|
||||
switch (entry.value) {
|
||||
FlagArg.Single => |inner| {
|
||||
.Single => |inner| {
|
||||
return inner;
|
||||
},
|
||||
else => @panic("attempted to retrieve flag with wrong type"),
|
||||
|
@ -172,7 +172,7 @@ pub const Args = struct {
|
|||
pub fn many(self: *Args, name: []const u8) []const []const u8 {
|
||||
if (self.flags.get(name)) |entry| {
|
||||
switch (entry.value) {
|
||||
FlagArg.Many => |inner| {
|
||||
.Many => |inner| {
|
||||
return inner.toSliceConst();
|
||||
},
|
||||
else => @panic("attempted to retrieve flag with wrong type"),
|
||||
|
|
|
@ -19,56 +19,56 @@ pub const CInt = struct {
|
|||
|
||||
pub const list = [_]CInt{
|
||||
CInt{
|
||||
.id = Id.Short,
|
||||
.id = .Short,
|
||||
.zig_name = "c_short",
|
||||
.c_name = "short",
|
||||
.is_signed = true,
|
||||
},
|
||||
CInt{
|
||||
.id = Id.UShort,
|
||||
.id = .UShort,
|
||||
.zig_name = "c_ushort",
|
||||
.c_name = "unsigned short",
|
||||
.is_signed = false,
|
||||
},
|
||||
CInt{
|
||||
.id = Id.Int,
|
||||
.id = .Int,
|
||||
.zig_name = "c_int",
|
||||
.c_name = "int",
|
||||
.is_signed = true,
|
||||
},
|
||||
CInt{
|
||||
.id = Id.UInt,
|
||||
.id = .UInt,
|
||||
.zig_name = "c_uint",
|
||||
.c_name = "unsigned int",
|
||||
.is_signed = false,
|
||||
},
|
||||
CInt{
|
||||
.id = Id.Long,
|
||||
.id = .Long,
|
||||
.zig_name = "c_long",
|
||||
.c_name = "long",
|
||||
.is_signed = true,
|
||||
},
|
||||
CInt{
|
||||
.id = Id.ULong,
|
||||
.id = .ULong,
|
||||
.zig_name = "c_ulong",
|
||||
.c_name = "unsigned long",
|
||||
.is_signed = false,
|
||||
},
|
||||
CInt{
|
||||
.id = Id.LongLong,
|
||||
.id = .LongLong,
|
||||
.zig_name = "c_longlong",
|
||||
.c_name = "long long",
|
||||
.is_signed = true,
|
||||
},
|
||||
CInt{
|
||||
.id = Id.ULongLong,
|
||||
.id = .ULongLong,
|
||||
.zig_name = "c_ulonglong",
|
||||
.c_name = "unsigned long long",
|
||||
.is_signed = false,
|
||||
},
|
||||
};
|
||||
|
||||
pub fn sizeInBits(id: CInt.Id, self: Target) u32 {
|
||||
pub fn sizeInBits(id: Id, self: Target) u32 {
|
||||
const arch = self.getArch();
|
||||
switch (self.getOs()) {
|
||||
.freestanding => switch (self.getArch()) {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
const llvm = @import("llvm.zig");
|
||||
const c = @import("c.zig");
|
||||
|
@ -31,7 +30,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
|
|||
llvm.SetTarget(module, comp.llvm_triple.ptr());
|
||||
llvm.SetDataLayout(module, comp.target_layout_str);
|
||||
|
||||
if (comp.target.getObjectFormat() == builtin.ObjectFormat.coff) {
|
||||
if (comp.target.getObjectFormat() == .coff) {
|
||||
llvm.AddModuleCodeViewFlag(module);
|
||||
} else {
|
||||
llvm.AddModuleDebugInfoFlag(module);
|
||||
|
@ -59,7 +58,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
|
|||
comp.name.ptr(),
|
||||
comp.root_package.root_src_dir.ptr(),
|
||||
) orelse return error.OutOfMemory;
|
||||
const is_optimized = comp.build_mode != builtin.Mode.Debug;
|
||||
const is_optimized = comp.build_mode != .Debug;
|
||||
const compile_unit = llvm.CreateCompileUnit(
|
||||
dibuilder,
|
||||
DW.LANG_C99,
|
||||
|
@ -105,8 +104,8 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
|
|||
|
||||
assert(comp.emit_file_type == Compilation.Emit.Binary); // TODO support other types
|
||||
|
||||
const is_small = comp.build_mode == builtin.Mode.ReleaseSmall;
|
||||
const is_debug = comp.build_mode == builtin.Mode.Debug;
|
||||
const is_small = comp.build_mode == .ReleaseSmall;
|
||||
const is_debug = comp.build_mode == .Debug;
|
||||
|
||||
var err_msg: [*]u8 = undefined;
|
||||
// TODO integrate this with evented I/O
|
||||
|
@ -114,7 +113,7 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
|
|||
comp.target_machine,
|
||||
module,
|
||||
output_path.ptr(),
|
||||
llvm.EmitBinary,
|
||||
.EmitBinary,
|
||||
&err_msg,
|
||||
is_debug,
|
||||
is_small,
|
||||
|
@ -234,8 +233,8 @@ pub fn renderToLlvmModule(ofile: *ObjectFile, fn_val: *Value.Fn, code: *ir.Code)
|
|||
// create debug variable declarations for variables and allocate all local variables
|
||||
for (var_list) |var_scope, i| {
|
||||
const var_type = switch (var_scope.data) {
|
||||
Scope.Var.Data.Const => unreachable,
|
||||
Scope.Var.Data.Param => |param| param.typ,
|
||||
.Const => unreachable,
|
||||
.Param => |param| param.typ,
|
||||
};
|
||||
// if (!type_has_bits(var->value->type)) {
|
||||
// continue;
|
||||
|
@ -266,7 +265,7 @@ pub fn renderToLlvmModule(ofile: *ObjectFile, fn_val: *Value.Fn, code: *ir.Code)
|
|||
var_scope.data.Param.llvm_value = llvm.GetParam(llvm_fn, @intCast(c_uint, i));
|
||||
} else {
|
||||
// gen_type = var->value->type;
|
||||
var_scope.data.Param.llvm_value = try renderAlloca(ofile, var_type, var_scope.name, Type.Pointer.Align.Abi);
|
||||
var_scope.data.Param.llvm_value = try renderAlloca(ofile, var_type, var_scope.name, .Abi);
|
||||
}
|
||||
// if (var->decl_node) {
|
||||
// var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
|
||||
|
@ -300,8 +299,8 @@ pub fn renderToLlvmModule(ofile: *ObjectFile, fn_val: *Value.Fn, code: *ir.Code)
|
|||
ofile,
|
||||
llvm_param,
|
||||
scope_var.data.Param.llvm_value,
|
||||
Type.Pointer.Align.Abi,
|
||||
Type.Pointer.Vol.Non,
|
||||
.Abi,
|
||||
.Non,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -383,8 +382,8 @@ fn renderLoadUntyped(
|
|||
) !*llvm.Value {
|
||||
const result = llvm.BuildLoad(ofile.builder, ptr, name) orelse return error.OutOfMemory;
|
||||
switch (vol) {
|
||||
Type.Pointer.Vol.Non => {},
|
||||
Type.Pointer.Vol.Volatile => llvm.SetVolatile(result, 1),
|
||||
.Non => {},
|
||||
.Volatile => llvm.SetVolatile(result, 1),
|
||||
}
|
||||
llvm.SetAlignment(result, resolveAlign(ofile, alignment, llvm.GetElementType(llvm.TypeOf(ptr))));
|
||||
return result;
|
||||
|
@ -414,8 +413,8 @@ pub fn renderStoreUntyped(
|
|||
) !*llvm.Value {
|
||||
const result = llvm.BuildStore(ofile.builder, value, ptr) orelse return error.OutOfMemory;
|
||||
switch (vol) {
|
||||
Type.Pointer.Vol.Non => {},
|
||||
Type.Pointer.Vol.Volatile => llvm.SetVolatile(result, 1),
|
||||
.Non => {},
|
||||
.Volatile => llvm.SetVolatile(result, 1),
|
||||
}
|
||||
llvm.SetAlignment(result, resolveAlign(ofile, alignment, llvm.TypeOf(value)));
|
||||
return result;
|
||||
|
@ -445,7 +444,7 @@ pub fn renderAlloca(
|
|||
|
||||
pub fn resolveAlign(ofile: *ObjectFile, alignment: Type.Pointer.Align, llvm_type: *llvm.Type) u32 {
|
||||
return switch (alignment) {
|
||||
Type.Pointer.Align.Abi => return llvm.ABIAlignmentOfType(ofile.comp.target_data_ref, llvm_type),
|
||||
Type.Pointer.Align.Override => |a| a,
|
||||
.Abi => return llvm.ABIAlignmentOfType(ofile.comp.target_data_ref, llvm_type),
|
||||
.Override => |a| a,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ const Allocator = mem.Allocator;
|
|||
const Buffer = std.Buffer;
|
||||
const llvm = @import("llvm.zig");
|
||||
const c = @import("c.zig");
|
||||
const builtin = @import("builtin");
|
||||
const builtin = std.builtin;
|
||||
const Target = std.Target;
|
||||
const warn = std.debug.warn;
|
||||
const Token = std.zig.Token;
|
||||
|
@ -481,7 +481,7 @@ pub const Compilation = struct {
|
|||
comp.zig_std_dir = try std.fs.path.join(comp.arena(), [_][]const u8{ zig_lib_dir, "std" });
|
||||
|
||||
const opt_level = switch (build_mode) {
|
||||
builtin.Mode.Debug => llvm.CodeGenLevelNone,
|
||||
.Debug => llvm.CodeGenLevelNone,
|
||||
else => llvm.CodeGenLevelAggressive,
|
||||
};
|
||||
|
||||
|
@ -594,11 +594,11 @@ pub const Compilation = struct {
|
|||
.base = Type{
|
||||
.name = "type",
|
||||
.base = Value{
|
||||
.id = Value.Id.Type,
|
||||
.id = .Type,
|
||||
.typ = undefined,
|
||||
.ref_count = std.atomic.Int(usize).init(3), // 3 because it references itself twice
|
||||
},
|
||||
.id = builtin.TypeId.Type,
|
||||
.id = .Type,
|
||||
.abi_alignment = Type.AbiAlignment.init(),
|
||||
},
|
||||
.value = undefined,
|
||||
|
@ -612,11 +612,11 @@ pub const Compilation = struct {
|
|||
.base = Type{
|
||||
.name = "void",
|
||||
.base = Value{
|
||||
.id = Value.Id.Type,
|
||||
.id = .Type,
|
||||
.typ = &Type.MetaType.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
.id = builtin.TypeId.Void,
|
||||
.id = .Void,
|
||||
.abi_alignment = Type.AbiAlignment.init(),
|
||||
},
|
||||
};
|
||||
|
@ -627,11 +627,11 @@ pub const Compilation = struct {
|
|||
.base = Type{
|
||||
.name = "noreturn",
|
||||
.base = Value{
|
||||
.id = Value.Id.Type,
|
||||
.id = .Type,
|
||||
.typ = &Type.MetaType.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
.id = builtin.TypeId.NoReturn,
|
||||
.id = .NoReturn,
|
||||
.abi_alignment = Type.AbiAlignment.init(),
|
||||
},
|
||||
};
|
||||
|
@ -642,11 +642,11 @@ pub const Compilation = struct {
|
|||
.base = Type{
|
||||
.name = "comptime_int",
|
||||
.base = Value{
|
||||
.id = Value.Id.Type,
|
||||
.id = .Type,
|
||||
.typ = &Type.MetaType.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
.id = builtin.TypeId.ComptimeInt,
|
||||
.id = .ComptimeInt,
|
||||
.abi_alignment = Type.AbiAlignment.init(),
|
||||
},
|
||||
};
|
||||
|
@ -657,11 +657,11 @@ pub const Compilation = struct {
|
|||
.base = Type{
|
||||
.name = "bool",
|
||||
.base = Value{
|
||||
.id = Value.Id.Type,
|
||||
.id = .Type,
|
||||
.typ = &Type.MetaType.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
.id = builtin.TypeId.Bool,
|
||||
.id = .Bool,
|
||||
.abi_alignment = Type.AbiAlignment.init(),
|
||||
},
|
||||
};
|
||||
|
@ -670,7 +670,7 @@ pub const Compilation = struct {
|
|||
comp.void_value = try comp.arena().create(Value.Void);
|
||||
comp.void_value.* = Value.Void{
|
||||
.base = Value{
|
||||
.id = Value.Id.Void,
|
||||
.id = .Void,
|
||||
.typ = &Type.Void.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
|
@ -679,7 +679,7 @@ pub const Compilation = struct {
|
|||
comp.true_value = try comp.arena().create(Value.Bool);
|
||||
comp.true_value.* = Value.Bool{
|
||||
.base = Value{
|
||||
.id = Value.Id.Bool,
|
||||
.id = .Bool,
|
||||
.typ = &Type.Bool.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
|
@ -689,7 +689,7 @@ pub const Compilation = struct {
|
|||
comp.false_value = try comp.arena().create(Value.Bool);
|
||||
comp.false_value.* = Value.Bool{
|
||||
.base = Value{
|
||||
.id = Value.Id.Bool,
|
||||
.id = .Bool,
|
||||
.typ = &Type.Bool.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
|
@ -699,7 +699,7 @@ pub const Compilation = struct {
|
|||
comp.noreturn_value = try comp.arena().create(Value.NoReturn);
|
||||
comp.noreturn_value.* = Value.NoReturn{
|
||||
.base = Value{
|
||||
.id = Value.Id.NoReturn,
|
||||
.id = .NoReturn,
|
||||
.typ = &Type.NoReturn.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
|
@ -711,11 +711,11 @@ pub const Compilation = struct {
|
|||
.base = Type{
|
||||
.name = cint.zig_name,
|
||||
.base = Value{
|
||||
.id = Value.Id.Type,
|
||||
.id = .Type,
|
||||
.typ = &Type.MetaType.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
.id = builtin.TypeId.Int,
|
||||
.id = .Int,
|
||||
.abi_alignment = Type.AbiAlignment.init(),
|
||||
},
|
||||
.key = Type.Int.Key{
|
||||
|
@ -732,11 +732,11 @@ pub const Compilation = struct {
|
|||
.base = Type{
|
||||
.name = "u8",
|
||||
.base = Value{
|
||||
.id = Value.Id.Type,
|
||||
.id = .Type,
|
||||
.typ = &Type.MetaType.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
.id = builtin.TypeId.Int,
|
||||
.id = .Int,
|
||||
.abi_alignment = Type.AbiAlignment.init(),
|
||||
},
|
||||
.key = Type.Int.Key{
|
||||
|
@ -884,15 +884,15 @@ pub const Compilation = struct {
|
|||
while (ast_it.next()) |decl_ptr| {
|
||||
const decl = decl_ptr.*;
|
||||
switch (decl.id) {
|
||||
ast.Node.Id.Comptime => {
|
||||
.Comptime => {
|
||||
const comptime_node = @fieldParentPtr(ast.Node.Comptime, "base", decl);
|
||||
|
||||
// TODO connect existing comptime decls to updated source files
|
||||
|
||||
try self.prelink_group.call(addCompTimeBlock, self, tree_scope, &decl_scope.base, comptime_node);
|
||||
},
|
||||
ast.Node.Id.VarDecl => @panic("TODO"),
|
||||
ast.Node.Id.FnProto => {
|
||||
.VarDecl => @panic("TODO"),
|
||||
.FnProto => {
|
||||
const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl);
|
||||
|
||||
const name = if (fn_proto.name_token) |name_token| tree_scope.tree.tokenSlice(name_token) else {
|
||||
|
@ -945,7 +945,7 @@ pub const Compilation = struct {
|
|||
try group.call(addTopLevelDecl, self, &fn_decl.base, locked_table);
|
||||
}
|
||||
},
|
||||
ast.Node.Id.TestDecl => @panic("TODO"),
|
||||
.TestDecl => @panic("TODO"),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
@ -1285,12 +1285,12 @@ 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 {
|
||||
switch (decl.id) {
|
||||
Decl.Id.Var => @panic("TODO"),
|
||||
Decl.Id.Fn => {
|
||||
.Var => @panic("TODO"),
|
||||
.Fn => {
|
||||
const fn_decl = @fieldParentPtr(Decl.Fn, "base", decl);
|
||||
return generateDeclFn(comp, fn_decl);
|
||||
},
|
||||
Decl.Id.CompTime => @panic("TODO"),
|
||||
.CompTime => @panic("TODO"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1385,8 +1385,8 @@ async fn analyzeFnType(
|
|||
fn_proto: *ast.Node.FnProto,
|
||||
) !*Type.Fn {
|
||||
const return_type_node = switch (fn_proto.return_type) {
|
||||
ast.Node.FnProto.ReturnType.Explicit => |n| n,
|
||||
ast.Node.FnProto.ReturnType.InferErrorSet => |n| n,
|
||||
.Explicit => |n| n,
|
||||
.InferErrorSet => |n| n,
|
||||
};
|
||||
const return_type = try comp.analyzeTypeExpr(tree_scope, scope, return_type_node);
|
||||
return_type.base.deref(comp);
|
||||
|
|
|
@ -29,7 +29,7 @@ pub const Decl = struct {
|
|||
|
||||
pub fn isExported(base: *const Decl, tree: *ast.Tree) bool {
|
||||
switch (base.id) {
|
||||
Id.Fn => {
|
||||
.Fn => {
|
||||
const fn_decl = @fieldParentPtr(Fn, "base", base);
|
||||
return fn_decl.isExported(tree);
|
||||
},
|
||||
|
@ -39,7 +39,7 @@ pub const Decl = struct {
|
|||
|
||||
pub fn getSpan(base: *const Decl) errmsg.Span {
|
||||
switch (base.id) {
|
||||
Id.Fn => {
|
||||
.Fn => {
|
||||
const fn_decl = @fieldParentPtr(Fn, "base", base);
|
||||
const fn_proto = fn_decl.fn_proto;
|
||||
const start = fn_proto.fn_token;
|
||||
|
@ -69,21 +69,18 @@ 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) {
|
||||
Unresolved: void,
|
||||
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: {
|
||||
const token = tree.tokens.at(tok_index);
|
||||
break :x switch (token.id) {
|
||||
Token.Id.Extern => tree.tokenSlicePtr(token),
|
||||
.Extern => tree.tokenSlicePtr(token),
|
||||
else => null,
|
||||
};
|
||||
} else null;
|
||||
|
@ -92,7 +89,7 @@ pub const Decl = struct {
|
|||
pub fn isExported(self: Fn, tree: *ast.Tree) bool {
|
||||
if (self.fn_proto.extern_export_inline_token) |tok_index| {
|
||||
const token = tree.tokens.at(tok_index);
|
||||
return token.id == Token.Id.Keyword_export;
|
||||
return token.id == .Keyword_export;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -62,17 +62,17 @@ pub const Msg = struct {
|
|||
|
||||
pub fn destroy(self: *Msg) void {
|
||||
switch (self.data) {
|
||||
Data.Cli => |cli| {
|
||||
.Cli => |cli| {
|
||||
cli.allocator.free(self.text);
|
||||
cli.allocator.free(self.realpath);
|
||||
cli.allocator.destroy(self);
|
||||
},
|
||||
Data.PathAndTree => |path_and_tree| {
|
||||
.PathAndTree => |path_and_tree| {
|
||||
path_and_tree.allocator.free(self.text);
|
||||
path_and_tree.allocator.free(self.realpath);
|
||||
path_and_tree.allocator.destroy(self);
|
||||
},
|
||||
Data.ScopeAndComp => |scope_and_comp| {
|
||||
.ScopeAndComp => |scope_and_comp| {
|
||||
scope_and_comp.tree_scope.base.deref(scope_and_comp.compilation);
|
||||
scope_and_comp.compilation.gpa().free(self.text);
|
||||
scope_and_comp.compilation.gpa().free(self.realpath);
|
||||
|
@ -83,11 +83,11 @@ pub const Msg = struct {
|
|||
|
||||
fn getAllocator(self: *const Msg) *mem.Allocator {
|
||||
switch (self.data) {
|
||||
Data.Cli => |cli| return cli.allocator,
|
||||
Data.PathAndTree => |path_and_tree| {
|
||||
.Cli => |cli| return cli.allocator,
|
||||
.PathAndTree => |path_and_tree| {
|
||||
return path_and_tree.allocator;
|
||||
},
|
||||
Data.ScopeAndComp => |scope_and_comp| {
|
||||
.ScopeAndComp => |scope_and_comp| {
|
||||
return scope_and_comp.compilation.gpa();
|
||||
},
|
||||
}
|
||||
|
@ -95,11 +95,11 @@ pub const Msg = struct {
|
|||
|
||||
pub fn getTree(self: *const Msg) *ast.Tree {
|
||||
switch (self.data) {
|
||||
Data.Cli => unreachable,
|
||||
Data.PathAndTree => |path_and_tree| {
|
||||
.Cli => unreachable,
|
||||
.PathAndTree => |path_and_tree| {
|
||||
return path_and_tree.tree;
|
||||
},
|
||||
Data.ScopeAndComp => |scope_and_comp| {
|
||||
.ScopeAndComp => |scope_and_comp| {
|
||||
return scope_and_comp.tree_scope.tree;
|
||||
},
|
||||
}
|
||||
|
@ -107,9 +107,9 @@ pub const Msg = struct {
|
|||
|
||||
pub fn getSpan(self: *const Msg) Span {
|
||||
return switch (self.data) {
|
||||
Data.Cli => unreachable,
|
||||
Data.PathAndTree => |path_and_tree| path_and_tree.span,
|
||||
Data.ScopeAndComp => |scope_and_comp| scope_and_comp.span,
|
||||
.Cli => unreachable,
|
||||
.PathAndTree => |path_and_tree| path_and_tree.span,
|
||||
.ScopeAndComp => |scope_and_comp| scope_and_comp.span,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -230,7 +230,7 @@ pub const Msg = struct {
|
|||
|
||||
pub fn printToStream(msg: *const Msg, stream: var, color_on: bool) !void {
|
||||
switch (msg.data) {
|
||||
Data.Cli => {
|
||||
.Cli => {
|
||||
try stream.print("{}:-:-: error: {}\n", msg.realpath, msg.text);
|
||||
return;
|
||||
},
|
||||
|
@ -279,9 +279,9 @@ pub const Msg = struct {
|
|||
|
||||
pub fn printToFile(msg: *const Msg, file: fs.File, color: Color) !void {
|
||||
const color_on = switch (color) {
|
||||
Color.Auto => file.isTty(),
|
||||
Color.On => true,
|
||||
Color.Off => false,
|
||||
.Auto => file.isTty(),
|
||||
.On => true,
|
||||
.Off => false,
|
||||
};
|
||||
var stream = &file.outStream().stream;
|
||||
return msg.printToStream(stream, color_on);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
const Scope = @import("scope.zig").Scope;
|
||||
const ast = std.zig.ast;
|
||||
|
@ -33,13 +32,13 @@ pub const IrVal = union(enum) {
|
|||
|
||||
pub fn dump(self: IrVal) void {
|
||||
switch (self) {
|
||||
IrVal.Unknown => std.debug.warn("Unknown"),
|
||||
IrVal.KnownType => |typ| {
|
||||
.Unknown => std.debug.warn("Unknown"),
|
||||
.KnownType => |typ| {
|
||||
std.debug.warn("KnownType(");
|
||||
typ.dump();
|
||||
std.debug.warn(")");
|
||||
},
|
||||
IrVal.KnownValue => |value| {
|
||||
.KnownValue => |value| {
|
||||
std.debug.warn("KnownValue(");
|
||||
value.dump();
|
||||
std.debug.warn(")");
|
||||
|
@ -113,37 +112,37 @@ pub const Inst = struct {
|
|||
|
||||
pub async fn analyze(base: *Inst, ira: *Analyze) Analyze.Error!*Inst {
|
||||
switch (base.id) {
|
||||
Id.Return => return @fieldParentPtr(Return, "base", base).analyze(ira),
|
||||
Id.Const => return @fieldParentPtr(Const, "base", base).analyze(ira),
|
||||
Id.Call => return @fieldParentPtr(Call, "base", base).analyze(ira),
|
||||
Id.DeclRef => return @fieldParentPtr(DeclRef, "base", base).analyze(ira),
|
||||
Id.Ref => return @fieldParentPtr(Ref, "base", base).analyze(ira),
|
||||
Id.DeclVar => return @fieldParentPtr(DeclVar, "base", base).analyze(ira),
|
||||
Id.CheckVoidStmt => return @fieldParentPtr(CheckVoidStmt, "base", base).analyze(ira),
|
||||
Id.Phi => return @fieldParentPtr(Phi, "base", base).analyze(ira),
|
||||
Id.Br => return @fieldParentPtr(Br, "base", base).analyze(ira),
|
||||
Id.AddImplicitReturnType => return @fieldParentPtr(AddImplicitReturnType, "base", base).analyze(ira),
|
||||
Id.PtrType => return @fieldParentPtr(PtrType, "base", base).analyze(ira),
|
||||
Id.VarPtr => return @fieldParentPtr(VarPtr, "base", base).analyze(ira),
|
||||
Id.LoadPtr => return @fieldParentPtr(LoadPtr, "base", base).analyze(ira),
|
||||
.Return => return @fieldParentPtr(Return, "base", base).analyze(ira),
|
||||
.Const => return @fieldParentPtr(Const, "base", base).analyze(ira),
|
||||
.Call => return @fieldParentPtr(Call, "base", base).analyze(ira),
|
||||
.DeclRef => return @fieldParentPtr(DeclRef, "base", base).analyze(ira),
|
||||
.Ref => return @fieldParentPtr(Ref, "base", base).analyze(ira),
|
||||
.DeclVar => return @fieldParentPtr(DeclVar, "base", base).analyze(ira),
|
||||
.CheckVoidStmt => return @fieldParentPtr(CheckVoidStmt, "base", base).analyze(ira),
|
||||
.Phi => return @fieldParentPtr(Phi, "base", base).analyze(ira),
|
||||
.Br => return @fieldParentPtr(Br, "base", base).analyze(ira),
|
||||
.AddImplicitReturnType => return @fieldParentPtr(AddImplicitReturnType, "base", base).analyze(ira),
|
||||
.PtrType => return @fieldParentPtr(PtrType, "base", base).analyze(ira),
|
||||
.VarPtr => return @fieldParentPtr(VarPtr, "base", base).analyze(ira),
|
||||
.LoadPtr => return @fieldParentPtr(LoadPtr, "base", base).analyze(ira),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(base: *Inst, ofile: *ObjectFile, fn_val: *Value.Fn) (error{OutOfMemory}!?*llvm.Value) {
|
||||
switch (base.id) {
|
||||
Id.Return => return @fieldParentPtr(Return, "base", base).render(ofile, fn_val),
|
||||
Id.Const => return @fieldParentPtr(Const, "base", base).render(ofile, fn_val),
|
||||
Id.Call => return @fieldParentPtr(Call, "base", base).render(ofile, fn_val),
|
||||
Id.VarPtr => return @fieldParentPtr(VarPtr, "base", base).render(ofile, fn_val),
|
||||
Id.LoadPtr => return @fieldParentPtr(LoadPtr, "base", base).render(ofile, fn_val),
|
||||
Id.DeclRef => unreachable,
|
||||
Id.PtrType => unreachable,
|
||||
Id.Ref => @panic("TODO"),
|
||||
Id.DeclVar => @panic("TODO"),
|
||||
Id.CheckVoidStmt => @panic("TODO"),
|
||||
Id.Phi => @panic("TODO"),
|
||||
Id.Br => @panic("TODO"),
|
||||
Id.AddImplicitReturnType => @panic("TODO"),
|
||||
.Return => return @fieldParentPtr(Return, "base", base).render(ofile, fn_val),
|
||||
.Const => return @fieldParentPtr(Const, "base", base).render(ofile, fn_val),
|
||||
.Call => return @fieldParentPtr(Call, "base", base).render(ofile, fn_val),
|
||||
.VarPtr => return @fieldParentPtr(VarPtr, "base", base).render(ofile, fn_val),
|
||||
.LoadPtr => return @fieldParentPtr(LoadPtr, "base", base).render(ofile, fn_val),
|
||||
.DeclRef => unreachable,
|
||||
.PtrType => unreachable,
|
||||
.Ref => @panic("TODO"),
|
||||
.DeclVar => @panic("TODO"),
|
||||
.CheckVoidStmt => @panic("TODO"),
|
||||
.Phi => @panic("TODO"),
|
||||
.Br => @panic("TODO"),
|
||||
.AddImplicitReturnType => @panic("TODO"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,7 +164,7 @@ pub const Inst = struct {
|
|||
param.ref_count -= 1;
|
||||
const child = param.child orelse return error.SemanticAnalysisFailed;
|
||||
switch (child.val) {
|
||||
IrVal.Unknown => return error.SemanticAnalysisFailed,
|
||||
.Unknown => return error.SemanticAnalysisFailed,
|
||||
else => return child,
|
||||
}
|
||||
}
|
||||
|
@ -213,9 +212,9 @@ pub const Inst = struct {
|
|||
/// asserts that the type is known
|
||||
fn getKnownType(self: *Inst) *Type {
|
||||
switch (self.val) {
|
||||
IrVal.KnownType => |typ| return typ,
|
||||
IrVal.KnownValue => |value| return value.typ,
|
||||
IrVal.Unknown => unreachable,
|
||||
.KnownType => |typ| return typ,
|
||||
.KnownValue => |value| return value.typ,
|
||||
.Unknown => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,14 +224,14 @@ pub const Inst = struct {
|
|||
|
||||
pub fn isNoReturn(base: *const Inst) bool {
|
||||
switch (base.val) {
|
||||
IrVal.Unknown => return false,
|
||||
IrVal.KnownValue => |x| return x.typ.id == Type.Id.NoReturn,
|
||||
IrVal.KnownType => |typ| return typ.id == Type.Id.NoReturn,
|
||||
.Unknown => return false,
|
||||
.KnownValue => |x| return x.typ.id == .NoReturn,
|
||||
.KnownType => |typ| return typ.id == .NoReturn,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn isCompTime(base: *const Inst) bool {
|
||||
return base.val == IrVal.KnownValue;
|
||||
return base.val == .KnownValue;
|
||||
}
|
||||
|
||||
pub fn linkToParent(self: *Inst, parent: *Inst) void {
|
||||
|
@ -445,8 +444,8 @@ pub const Inst = struct {
|
|||
.child_type = elem_type,
|
||||
.mut = self.params.mut,
|
||||
.vol = self.params.volatility,
|
||||
.size = Type.Pointer.Size.One,
|
||||
.alignment = Type.Pointer.Align.Abi,
|
||||
.size = .One,
|
||||
.alignment = .Abi,
|
||||
});
|
||||
// TODO: potentially set the hint that this is a stack pointer. But it might not be - this
|
||||
// could be a ref of a global, for example
|
||||
|
@ -479,20 +478,20 @@ pub const Inst = struct {
|
|||
else => return error.SemanticAnalysisFailed,
|
||||
};
|
||||
switch (self.params.decl.id) {
|
||||
Decl.Id.CompTime => unreachable,
|
||||
Decl.Id.Var => return error.Unimplemented,
|
||||
Decl.Id.Fn => {
|
||||
.CompTime => unreachable,
|
||||
.Var => return error.Unimplemented,
|
||||
.Fn => {
|
||||
const fn_decl = @fieldParentPtr(Decl.Fn, "base", self.params.decl);
|
||||
const decl_val = switch (fn_decl.value) {
|
||||
Decl.Fn.Val.Unresolved => unreachable,
|
||||
Decl.Fn.Val.Fn => |fn_val| &fn_val.base,
|
||||
Decl.Fn.Val.FnProto => |fn_proto| &fn_proto.base,
|
||||
.Unresolved => unreachable,
|
||||
.Fn => |fn_val| &fn_val.base,
|
||||
.FnProto => |fn_proto| &fn_proto.base,
|
||||
};
|
||||
switch (self.params.lval) {
|
||||
LVal.None => {
|
||||
.None => {
|
||||
return ira.irb.buildConstValue(self.base.scope, self.base.span, decl_val);
|
||||
},
|
||||
LVal.Ptr => return error.Unimplemented,
|
||||
.Ptr => return error.Unimplemented,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -519,20 +518,20 @@ pub const Inst = struct {
|
|||
|
||||
pub async fn analyze(self: *const VarPtr, ira: *Analyze) !*Inst {
|
||||
switch (self.params.var_scope.data) {
|
||||
Scope.Var.Data.Const => @panic("TODO"),
|
||||
Scope.Var.Data.Param => |param| {
|
||||
.Const => @panic("TODO"),
|
||||
.Param => |param| {
|
||||
const new_inst = try ira.irb.build(
|
||||
Inst.VarPtr,
|
||||
.VarPtr,
|
||||
self.base.scope,
|
||||
self.base.span,
|
||||
Inst.VarPtr.Params{ .var_scope = self.params.var_scope },
|
||||
);
|
||||
const ptr_type = try Type.Pointer.get(ira.irb.comp, Type.Pointer.Key{
|
||||
.child_type = param.typ,
|
||||
.mut = Type.Pointer.Mut.Const,
|
||||
.vol = Type.Pointer.Vol.Non,
|
||||
.size = Type.Pointer.Size.One,
|
||||
.alignment = Type.Pointer.Align.Abi,
|
||||
.mut = .Const,
|
||||
.vol = .Non,
|
||||
.size = .One,
|
||||
.alignment = .Abi,
|
||||
});
|
||||
new_inst.val = IrVal{ .KnownType = &ptr_type.base };
|
||||
return new_inst;
|
||||
|
@ -542,8 +541,8 @@ pub const Inst = struct {
|
|||
|
||||
pub fn render(self: *VarPtr, ofile: *ObjectFile, fn_val: *Value.Fn) *llvm.Value {
|
||||
switch (self.params.var_scope.data) {
|
||||
Scope.Var.Data.Const => unreachable, // turned into Inst.Const in analyze pass
|
||||
Scope.Var.Data.Param => |param| return param.llvm_value,
|
||||
.Const => unreachable, // turned into Inst.Const in analyze pass
|
||||
.Param => |param| return param.llvm_value,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -567,7 +566,7 @@ pub const Inst = struct {
|
|||
pub async fn analyze(self: *const LoadPtr, ira: *Analyze) !*Inst {
|
||||
const target = try self.params.target.getAsParam();
|
||||
const target_type = target.getKnownType();
|
||||
if (target_type.id != Type.Id.Pointer) {
|
||||
if (target_type.id != .Pointer) {
|
||||
try ira.addCompileError(self.base.span, "dereference of non pointer type '{}'", target_type.name);
|
||||
return error.SemanticAnalysisFailed;
|
||||
}
|
||||
|
@ -715,7 +714,7 @@ pub const Inst = struct {
|
|||
|
||||
pub fn analyze(self: *const CheckVoidStmt, ira: *Analyze) !*Inst {
|
||||
const target = try self.params.target.getAsParam();
|
||||
if (target.getKnownType().id != Type.Id.Void) {
|
||||
if (target.getKnownType().id != .Void) {
|
||||
try ira.addCompileError(self.base.span, "expression value is ignored");
|
||||
return error.SemanticAnalysisFailed;
|
||||
}
|
||||
|
@ -838,7 +837,7 @@ pub const Inst = struct {
|
|||
const target = try self.params.target.getAsParam();
|
||||
const target_type = target.getKnownType();
|
||||
switch (target_type.id) {
|
||||
Type.Id.ErrorUnion => {
|
||||
.ErrorUnion => {
|
||||
return error.Unimplemented;
|
||||
// if (instr_is_comptime(value)) {
|
||||
// ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad);
|
||||
|
@ -868,7 +867,7 @@ pub const Inst = struct {
|
|||
// ir_build_test_err_from(&ira->new_irb, &instruction->base, value);
|
||||
// return ira->codegen->builtin_types.entry_bool;
|
||||
},
|
||||
Type.Id.ErrorSet => {
|
||||
.ErrorSet => {
|
||||
return ira.irb.buildConstBool(self.base.scope, self.base.span, true);
|
||||
},
|
||||
else => {
|
||||
|
@ -1081,120 +1080,120 @@ pub const Builder = struct {
|
|||
|
||||
pub async fn genNode(irb: *Builder, node: *ast.Node, scope: *Scope, lval: LVal) Error!*Inst {
|
||||
switch (node.id) {
|
||||
ast.Node.Id.Root => unreachable,
|
||||
ast.Node.Id.Use => unreachable,
|
||||
ast.Node.Id.TestDecl => unreachable,
|
||||
ast.Node.Id.VarDecl => return error.Unimplemented,
|
||||
ast.Node.Id.Defer => return error.Unimplemented,
|
||||
ast.Node.Id.InfixOp => return error.Unimplemented,
|
||||
ast.Node.Id.PrefixOp => {
|
||||
.Root => unreachable,
|
||||
.Use => unreachable,
|
||||
.TestDecl => unreachable,
|
||||
.VarDecl => return error.Unimplemented,
|
||||
.Defer => return error.Unimplemented,
|
||||
.InfixOp => return error.Unimplemented,
|
||||
.PrefixOp => {
|
||||
const prefix_op = @fieldParentPtr(ast.Node.PrefixOp, "base", node);
|
||||
switch (prefix_op.op) {
|
||||
ast.Node.PrefixOp.Op.AddressOf => return error.Unimplemented,
|
||||
ast.Node.PrefixOp.Op.ArrayType => |n| return error.Unimplemented,
|
||||
ast.Node.PrefixOp.Op.Await => return error.Unimplemented,
|
||||
ast.Node.PrefixOp.Op.BitNot => return error.Unimplemented,
|
||||
ast.Node.PrefixOp.Op.BoolNot => return error.Unimplemented,
|
||||
ast.Node.PrefixOp.Op.Cancel => return error.Unimplemented,
|
||||
ast.Node.PrefixOp.Op.OptionalType => return error.Unimplemented,
|
||||
ast.Node.PrefixOp.Op.Negation => return error.Unimplemented,
|
||||
ast.Node.PrefixOp.Op.NegationWrap => return error.Unimplemented,
|
||||
ast.Node.PrefixOp.Op.Resume => return error.Unimplemented,
|
||||
ast.Node.PrefixOp.Op.PtrType => |ptr_info| {
|
||||
.AddressOf => return error.Unimplemented,
|
||||
.ArrayType => |n| return error.Unimplemented,
|
||||
.Await => return error.Unimplemented,
|
||||
.BitNot => return error.Unimplemented,
|
||||
.BoolNot => return error.Unimplemented,
|
||||
.Cancel => return error.Unimplemented,
|
||||
.OptionalType => return error.Unimplemented,
|
||||
.Negation => return error.Unimplemented,
|
||||
.NegationWrap => return error.Unimplemented,
|
||||
.Resume => return error.Unimplemented,
|
||||
.PtrType => |ptr_info| {
|
||||
const inst = try irb.genPtrType(prefix_op, ptr_info, scope);
|
||||
return irb.lvalWrap(scope, inst, lval);
|
||||
},
|
||||
ast.Node.PrefixOp.Op.SliceType => |ptr_info| return error.Unimplemented,
|
||||
ast.Node.PrefixOp.Op.Try => return error.Unimplemented,
|
||||
.SliceType => |ptr_info| return error.Unimplemented,
|
||||
.Try => return error.Unimplemented,
|
||||
}
|
||||
},
|
||||
ast.Node.Id.SuffixOp => {
|
||||
.SuffixOp => {
|
||||
const suffix_op = @fieldParentPtr(ast.Node.SuffixOp, "base", node);
|
||||
switch (suffix_op.op) {
|
||||
@TagType(ast.Node.SuffixOp.Op).Call => |*call| {
|
||||
.Call => |*call| {
|
||||
const inst = try irb.genCall(suffix_op, call, scope);
|
||||
return irb.lvalWrap(scope, inst, lval);
|
||||
},
|
||||
@TagType(ast.Node.SuffixOp.Op).ArrayAccess => |n| return error.Unimplemented,
|
||||
@TagType(ast.Node.SuffixOp.Op).Slice => |slice| return error.Unimplemented,
|
||||
@TagType(ast.Node.SuffixOp.Op).ArrayInitializer => |init_list| return error.Unimplemented,
|
||||
@TagType(ast.Node.SuffixOp.Op).StructInitializer => |init_list| return error.Unimplemented,
|
||||
@TagType(ast.Node.SuffixOp.Op).Deref => return error.Unimplemented,
|
||||
@TagType(ast.Node.SuffixOp.Op).UnwrapOptional => return error.Unimplemented,
|
||||
.ArrayAccess => |n| return error.Unimplemented,
|
||||
.Slice => |slice| return error.Unimplemented,
|
||||
.ArrayInitializer => |init_list| return error.Unimplemented,
|
||||
.StructInitializer => |init_list| return error.Unimplemented,
|
||||
.Deref => return error.Unimplemented,
|
||||
.UnwrapOptional => return error.Unimplemented,
|
||||
}
|
||||
},
|
||||
ast.Node.Id.Switch => return error.Unimplemented,
|
||||
ast.Node.Id.While => return error.Unimplemented,
|
||||
ast.Node.Id.For => return error.Unimplemented,
|
||||
ast.Node.Id.If => return error.Unimplemented,
|
||||
ast.Node.Id.ControlFlowExpression => {
|
||||
.Switch => return error.Unimplemented,
|
||||
.While => return error.Unimplemented,
|
||||
.For => return error.Unimplemented,
|
||||
.If => return error.Unimplemented,
|
||||
.ControlFlowExpression => {
|
||||
const control_flow_expr = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", node);
|
||||
return irb.genControlFlowExpr(control_flow_expr, scope, lval);
|
||||
},
|
||||
ast.Node.Id.Suspend => return error.Unimplemented,
|
||||
ast.Node.Id.VarType => return error.Unimplemented,
|
||||
ast.Node.Id.ErrorType => return error.Unimplemented,
|
||||
ast.Node.Id.FnProto => return error.Unimplemented,
|
||||
ast.Node.Id.PromiseType => return error.Unimplemented,
|
||||
ast.Node.Id.IntegerLiteral => {
|
||||
.Suspend => return error.Unimplemented,
|
||||
.VarType => return error.Unimplemented,
|
||||
.ErrorType => return error.Unimplemented,
|
||||
.FnProto => return error.Unimplemented,
|
||||
.PromiseType => return error.Unimplemented,
|
||||
.IntegerLiteral => {
|
||||
const int_lit = @fieldParentPtr(ast.Node.IntegerLiteral, "base", node);
|
||||
return irb.lvalWrap(scope, try irb.genIntLit(int_lit, scope), lval);
|
||||
},
|
||||
ast.Node.Id.FloatLiteral => return error.Unimplemented,
|
||||
ast.Node.Id.StringLiteral => {
|
||||
.FloatLiteral => return error.Unimplemented,
|
||||
.StringLiteral => {
|
||||
const str_lit = @fieldParentPtr(ast.Node.StringLiteral, "base", node);
|
||||
const inst = try irb.genStrLit(str_lit, scope);
|
||||
return irb.lvalWrap(scope, inst, lval);
|
||||
},
|
||||
ast.Node.Id.MultilineStringLiteral => return error.Unimplemented,
|
||||
ast.Node.Id.CharLiteral => return error.Unimplemented,
|
||||
ast.Node.Id.BoolLiteral => return error.Unimplemented,
|
||||
ast.Node.Id.NullLiteral => return error.Unimplemented,
|
||||
ast.Node.Id.UndefinedLiteral => return error.Unimplemented,
|
||||
ast.Node.Id.Unreachable => return error.Unimplemented,
|
||||
ast.Node.Id.Identifier => {
|
||||
.MultilineStringLiteral => return error.Unimplemented,
|
||||
.CharLiteral => return error.Unimplemented,
|
||||
.BoolLiteral => return error.Unimplemented,
|
||||
.NullLiteral => return error.Unimplemented,
|
||||
.UndefinedLiteral => return error.Unimplemented,
|
||||
.Unreachable => return error.Unimplemented,
|
||||
.Identifier => {
|
||||
const identifier = @fieldParentPtr(ast.Node.Identifier, "base", node);
|
||||
return irb.genIdentifier(identifier, scope, lval);
|
||||
},
|
||||
ast.Node.Id.GroupedExpression => {
|
||||
.GroupedExpression => {
|
||||
const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", node);
|
||||
return irb.genNode(grouped_expr.expr, scope, lval);
|
||||
},
|
||||
ast.Node.Id.BuiltinCall => return error.Unimplemented,
|
||||
ast.Node.Id.ErrorSetDecl => return error.Unimplemented,
|
||||
ast.Node.Id.ContainerDecl => return error.Unimplemented,
|
||||
ast.Node.Id.Asm => return error.Unimplemented,
|
||||
ast.Node.Id.Comptime => return error.Unimplemented,
|
||||
ast.Node.Id.Block => {
|
||||
.BuiltinCall => return error.Unimplemented,
|
||||
.ErrorSetDecl => return error.Unimplemented,
|
||||
.ContainerDecl => return error.Unimplemented,
|
||||
.Asm => return error.Unimplemented,
|
||||
.Comptime => return error.Unimplemented,
|
||||
.Block => {
|
||||
const block = @fieldParentPtr(ast.Node.Block, "base", node);
|
||||
const inst = try irb.genBlock(block, scope);
|
||||
return irb.lvalWrap(scope, inst, lval);
|
||||
},
|
||||
ast.Node.Id.DocComment => return error.Unimplemented,
|
||||
ast.Node.Id.SwitchCase => return error.Unimplemented,
|
||||
ast.Node.Id.SwitchElse => return error.Unimplemented,
|
||||
ast.Node.Id.Else => return error.Unimplemented,
|
||||
ast.Node.Id.Payload => return error.Unimplemented,
|
||||
ast.Node.Id.PointerPayload => return error.Unimplemented,
|
||||
ast.Node.Id.PointerIndexPayload => return error.Unimplemented,
|
||||
ast.Node.Id.ContainerField => return error.Unimplemented,
|
||||
ast.Node.Id.ErrorTag => return error.Unimplemented,
|
||||
ast.Node.Id.AsmInput => return error.Unimplemented,
|
||||
ast.Node.Id.AsmOutput => return error.Unimplemented,
|
||||
ast.Node.Id.ParamDecl => return error.Unimplemented,
|
||||
ast.Node.Id.FieldInitializer => return error.Unimplemented,
|
||||
ast.Node.Id.EnumLiteral => return error.Unimplemented,
|
||||
.DocComment => return error.Unimplemented,
|
||||
.SwitchCase => return error.Unimplemented,
|
||||
.SwitchElse => return error.Unimplemented,
|
||||
.Else => return error.Unimplemented,
|
||||
.Payload => return error.Unimplemented,
|
||||
.PointerPayload => return error.Unimplemented,
|
||||
.PointerIndexPayload => return error.Unimplemented,
|
||||
.ContainerField => return error.Unimplemented,
|
||||
.ErrorTag => return error.Unimplemented,
|
||||
.AsmInput => return error.Unimplemented,
|
||||
.AsmOutput => return error.Unimplemented,
|
||||
.ParamDecl => return error.Unimplemented,
|
||||
.FieldInitializer => return error.Unimplemented,
|
||||
.EnumLiteral => return error.Unimplemented,
|
||||
}
|
||||
}
|
||||
|
||||
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, LVal.None);
|
||||
const fn_ref = try irb.genNode(suffix_op.lhs, scope, .None);
|
||||
|
||||
const args = try irb.arena().alloc(*Inst, call.params.len);
|
||||
var it = call.params.iterator(0);
|
||||
var i: usize = 0;
|
||||
while (it.next()) |arg_node_ptr| : (i += 1) {
|
||||
args[i] = try irb.genNode(arg_node_ptr.*, scope, LVal.None);
|
||||
args[i] = try irb.genNode(arg_node_ptr.*, scope, .None);
|
||||
}
|
||||
|
||||
//bool is_async = node->data.fn_call_expr.is_async;
|
||||
|
@ -1239,7 +1238,7 @@ pub const Builder = struct {
|
|||
//} else {
|
||||
// align_value = nullptr;
|
||||
//}
|
||||
const child_type = try irb.genNode(prefix_op.rhs, scope, LVal.None);
|
||||
const child_type = try irb.genNode(prefix_op.rhs, scope, .None);
|
||||
|
||||
//uint32_t bit_offset_start = 0;
|
||||
//if (node->data.pointer_type.bit_offset_start != nullptr) {
|
||||
|
@ -1273,9 +1272,9 @@ pub const Builder = struct {
|
|||
|
||||
return irb.build(Inst.PtrType, scope, Span.node(&prefix_op.base), Inst.PtrType.Params{
|
||||
.child_type = child_type,
|
||||
.mut = Type.Pointer.Mut.Mut,
|
||||
.vol = Type.Pointer.Vol.Non,
|
||||
.size = Type.Pointer.Size.Many,
|
||||
.mut = .Mut,
|
||||
.vol = .Non,
|
||||
.size = .Many,
|
||||
.alignment = null,
|
||||
});
|
||||
}
|
||||
|
@ -1287,15 +1286,15 @@ pub const Builder = struct {
|
|||
var scope = target_scope;
|
||||
while (true) {
|
||||
switch (scope.id) {
|
||||
Scope.Id.CompTime => return true,
|
||||
Scope.Id.FnDef => return false,
|
||||
Scope.Id.Decls => unreachable,
|
||||
Scope.Id.Root => unreachable,
|
||||
Scope.Id.AstTree => unreachable,
|
||||
Scope.Id.Block,
|
||||
Scope.Id.Defer,
|
||||
Scope.Id.DeferExpr,
|
||||
Scope.Id.Var,
|
||||
.CompTime => return true,
|
||||
.FnDef => return false,
|
||||
.Decls => unreachable,
|
||||
.Root => unreachable,
|
||||
.AstTree => unreachable,
|
||||
.Block,
|
||||
.Defer,
|
||||
.DeferExpr,
|
||||
.Var,
|
||||
=> scope = scope.parent.?,
|
||||
}
|
||||
}
|
||||
|
@ -1374,8 +1373,8 @@ pub const Builder = struct {
|
|||
const ptr_val = try Value.Ptr.createArrayElemPtr(
|
||||
irb.comp,
|
||||
array_val,
|
||||
Type.Pointer.Mut.Const,
|
||||
Type.Pointer.Size.Many,
|
||||
.Const,
|
||||
.Many,
|
||||
0,
|
||||
);
|
||||
defer ptr_val.base.deref(irb.comp);
|
||||
|
@ -1438,7 +1437,7 @@ pub const Builder = struct {
|
|||
child_scope = &defer_child_scope.base;
|
||||
continue;
|
||||
}
|
||||
const statement_value = try irb.genNode(statement_node, child_scope, LVal.None);
|
||||
const statement_value = try irb.genNode(statement_node, child_scope, .None);
|
||||
|
||||
is_continuation_unreachable = statement_value.isNoReturn();
|
||||
if (is_continuation_unreachable) {
|
||||
|
@ -1481,7 +1480,7 @@ pub const Builder = struct {
|
|||
try block_scope.incoming_values.append(
|
||||
try irb.buildConstVoid(parent_scope, Span.token(block.rbrace), true),
|
||||
);
|
||||
_ = try irb.genDefersForBlock(child_scope, outer_block_scope, Scope.Defer.Kind.ScopeExit);
|
||||
_ = try irb.genDefersForBlock(child_scope, outer_block_scope, .ScopeExit);
|
||||
|
||||
_ = try irb.buildGen(Inst.Br, parent_scope, Span.token(block.rbrace), Inst.Br.Params{
|
||||
.dest_block = block_scope.end_block,
|
||||
|
@ -1496,7 +1495,7 @@ pub const Builder = struct {
|
|||
});
|
||||
}
|
||||
|
||||
_ = try irb.genDefersForBlock(child_scope, outer_block_scope, Scope.Defer.Kind.ScopeExit);
|
||||
_ = try irb.genDefersForBlock(child_scope, outer_block_scope, .ScopeExit);
|
||||
return irb.buildConstVoid(child_scope, Span.token(block.rbrace), true);
|
||||
}
|
||||
|
||||
|
@ -1507,9 +1506,9 @@ pub const Builder = struct {
|
|||
lval: LVal,
|
||||
) !*Inst {
|
||||
switch (control_flow_expr.kind) {
|
||||
ast.Node.ControlFlowExpression.Kind.Break => |arg| return error.Unimplemented,
|
||||
ast.Node.ControlFlowExpression.Kind.Continue => |arg| return error.Unimplemented,
|
||||
ast.Node.ControlFlowExpression.Kind.Return => {
|
||||
.Break => |arg| return error.Unimplemented,
|
||||
.Continue => |arg| return error.Unimplemented,
|
||||
.Return => {
|
||||
const src_span = Span.token(control_flow_expr.ltoken);
|
||||
if (scope.findFnDef() == null) {
|
||||
try irb.comp.addCompileError(
|
||||
|
@ -1534,7 +1533,7 @@ pub const Builder = struct {
|
|||
|
||||
const outer_scope = irb.begin_scope.?;
|
||||
const return_value = if (control_flow_expr.rhs) |rhs| blk: {
|
||||
break :blk try irb.genNode(rhs, scope, LVal.None);
|
||||
break :blk try irb.genNode(rhs, scope, .None);
|
||||
} else blk: {
|
||||
break :blk try irb.buildConstVoid(scope, src_span, true);
|
||||
};
|
||||
|
@ -1545,7 +1544,7 @@ pub const Builder = struct {
|
|||
const err_block = try irb.createBasicBlock(scope, c"ErrRetErr");
|
||||
const ok_block = try irb.createBasicBlock(scope, c"ErrRetOk");
|
||||
if (!have_err_defers) {
|
||||
_ = try irb.genDefersForBlock(scope, outer_scope, Scope.Defer.Kind.ScopeExit);
|
||||
_ = try irb.genDefersForBlock(scope, outer_scope, .ScopeExit);
|
||||
}
|
||||
|
||||
const is_err = try irb.build(
|
||||
|
@ -1568,7 +1567,7 @@ pub const Builder = struct {
|
|||
|
||||
try irb.setCursorAtEndAndAppendBlock(err_block);
|
||||
if (have_err_defers) {
|
||||
_ = try irb.genDefersForBlock(scope, outer_scope, Scope.Defer.Kind.ErrorExit);
|
||||
_ = try irb.genDefersForBlock(scope, outer_scope, .ErrorExit);
|
||||
}
|
||||
if (irb.comp.have_err_ret_tracing and !irb.isCompTime(scope)) {
|
||||
_ = try irb.build(Inst.SaveErrRetAddr, scope, src_span, Inst.SaveErrRetAddr.Params{});
|
||||
|
@ -1580,7 +1579,7 @@ pub const Builder = struct {
|
|||
|
||||
try irb.setCursorAtEndAndAppendBlock(ok_block);
|
||||
if (have_err_defers) {
|
||||
_ = try irb.genDefersForBlock(scope, outer_scope, Scope.Defer.Kind.ScopeExit);
|
||||
_ = try irb.genDefersForBlock(scope, outer_scope, .ScopeExit);
|
||||
}
|
||||
_ = try irb.build(Inst.Br, scope, src_span, Inst.Br.Params{
|
||||
.dest_block = ret_stmt_block,
|
||||
|
@ -1590,7 +1589,7 @@ pub const Builder = struct {
|
|||
try irb.setCursorAtEndAndAppendBlock(ret_stmt_block);
|
||||
return irb.genAsyncReturn(scope, src_span, return_value, false);
|
||||
} else {
|
||||
_ = try irb.genDefersForBlock(scope, outer_scope, Scope.Defer.Kind.ScopeExit);
|
||||
_ = try irb.genDefersForBlock(scope, outer_scope, .ScopeExit);
|
||||
return irb.genAsyncReturn(scope, src_span, return_value, false);
|
||||
}
|
||||
},
|
||||
|
@ -1616,8 +1615,8 @@ pub const Builder = struct {
|
|||
switch (lval) {
|
||||
// if (lval == LValPtr) {
|
||||
// return ir_build_ref(irb, scope, node, value, false, false);
|
||||
LVal.Ptr => return error.Unimplemented,
|
||||
LVal.None => return irb.buildConstValue(scope, src_span, &primitive_type.base),
|
||||
.Ptr => return error.Unimplemented,
|
||||
.None => return irb.buildConstValue(scope, src_span, &primitive_type.base),
|
||||
}
|
||||
}
|
||||
} else |err| switch (err) {
|
||||
|
@ -1629,22 +1628,22 @@ pub const Builder = struct {
|
|||
}
|
||||
|
||||
switch (irb.findIdent(scope, name)) {
|
||||
Ident.Decl => |decl| {
|
||||
.Decl => |decl| {
|
||||
return irb.build(Inst.DeclRef, scope, src_span, Inst.DeclRef.Params{
|
||||
.decl = decl,
|
||||
.lval = lval,
|
||||
});
|
||||
},
|
||||
Ident.VarScope => |var_scope| {
|
||||
.VarScope => |var_scope| {
|
||||
const var_ptr = try irb.build(Inst.VarPtr, scope, src_span, Inst.VarPtr.Params{ .var_scope = var_scope });
|
||||
switch (lval) {
|
||||
LVal.Ptr => return var_ptr,
|
||||
LVal.None => {
|
||||
.Ptr => return var_ptr,
|
||||
.None => {
|
||||
return irb.build(Inst.LoadPtr, scope, src_span, Inst.LoadPtr.Params{ .target = var_ptr });
|
||||
},
|
||||
}
|
||||
},
|
||||
Ident.NotFound => {},
|
||||
.NotFound => {},
|
||||
}
|
||||
|
||||
//if (node->owner->any_imports_failed) {
|
||||
|
@ -1671,25 +1670,25 @@ pub const Builder = struct {
|
|||
var scope = inner_scope;
|
||||
while (scope != outer_scope) {
|
||||
switch (scope.id) {
|
||||
Scope.Id.Defer => {
|
||||
.Defer => {
|
||||
const defer_scope = @fieldParentPtr(Scope.Defer, "base", scope);
|
||||
switch (defer_scope.kind) {
|
||||
Scope.Defer.Kind.ScopeExit => result.scope_exit += 1,
|
||||
Scope.Defer.Kind.ErrorExit => result.error_exit += 1,
|
||||
.ScopeExit => result.scope_exit += 1,
|
||||
.ErrorExit => result.error_exit += 1,
|
||||
}
|
||||
scope = scope.parent orelse break;
|
||||
},
|
||||
Scope.Id.FnDef => break,
|
||||
.FnDef => break,
|
||||
|
||||
Scope.Id.CompTime,
|
||||
Scope.Id.Block,
|
||||
Scope.Id.Decls,
|
||||
Scope.Id.Root,
|
||||
Scope.Id.Var,
|
||||
.CompTime,
|
||||
.Block,
|
||||
.Decls,
|
||||
.Root,
|
||||
.Var,
|
||||
=> scope = scope.parent orelse break,
|
||||
|
||||
Scope.Id.DeferExpr => unreachable,
|
||||
Scope.Id.AstTree => unreachable,
|
||||
.DeferExpr => unreachable,
|
||||
.AstTree => unreachable,
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -1705,18 +1704,18 @@ pub const Builder = struct {
|
|||
var is_noreturn = false;
|
||||
while (true) {
|
||||
switch (scope.id) {
|
||||
Scope.Id.Defer => {
|
||||
.Defer => {
|
||||
const defer_scope = @fieldParentPtr(Scope.Defer, "base", scope);
|
||||
const generate = switch (defer_scope.kind) {
|
||||
Scope.Defer.Kind.ScopeExit => true,
|
||||
Scope.Defer.Kind.ErrorExit => gen_kind == Scope.Defer.Kind.ErrorExit,
|
||||
.ScopeExit => true,
|
||||
.ErrorExit => gen_kind == .ErrorExit,
|
||||
};
|
||||
if (generate) {
|
||||
const defer_expr_scope = defer_scope.defer_expr_scope;
|
||||
const instruction = try irb.genNode(
|
||||
defer_expr_scope.expr_node,
|
||||
&defer_expr_scope.base,
|
||||
LVal.None,
|
||||
.None,
|
||||
);
|
||||
if (instruction.isNoReturn()) {
|
||||
is_noreturn = true;
|
||||
|
@ -1730,32 +1729,32 @@ pub const Builder = struct {
|
|||
}
|
||||
}
|
||||
},
|
||||
Scope.Id.FnDef,
|
||||
Scope.Id.Decls,
|
||||
Scope.Id.Root,
|
||||
.FnDef,
|
||||
.Decls,
|
||||
.Root,
|
||||
=> return is_noreturn,
|
||||
|
||||
Scope.Id.CompTime,
|
||||
Scope.Id.Block,
|
||||
Scope.Id.Var,
|
||||
.CompTime,
|
||||
.Block,
|
||||
.Var,
|
||||
=> scope = scope.parent orelse return is_noreturn,
|
||||
|
||||
Scope.Id.DeferExpr => unreachable,
|
||||
Scope.Id.AstTree => unreachable,
|
||||
.DeferExpr => unreachable,
|
||||
.AstTree => unreachable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lvalWrap(irb: *Builder, scope: *Scope, instruction: *Inst, lval: LVal) !*Inst {
|
||||
switch (lval) {
|
||||
LVal.None => return instruction,
|
||||
LVal.Ptr => {
|
||||
.None => return instruction,
|
||||
.Ptr => {
|
||||
// We needed a pointer to a value, but we got a value. So we create
|
||||
// an instruction which just makes a const pointer of it.
|
||||
return irb.build(Inst.Ref, scope, instruction.span, Inst.Ref.Params{
|
||||
.target = instruction,
|
||||
.mut = Type.Pointer.Mut.Const,
|
||||
.volatility = Type.Pointer.Vol.Non,
|
||||
.mut = .Const,
|
||||
.volatility = .Non,
|
||||
});
|
||||
},
|
||||
}
|
||||
|
@ -1781,9 +1780,9 @@ pub const Builder = struct {
|
|||
.scope = scope,
|
||||
.debug_id = self.next_debug_id,
|
||||
.val = switch (I.ir_val_init) {
|
||||
IrVal.Init.Unknown => IrVal.Unknown,
|
||||
IrVal.Init.NoReturn => IrVal{ .KnownValue = &Value.NoReturn.get(self.comp).base },
|
||||
IrVal.Init.Void => IrVal{ .KnownValue = &Value.Void.get(self.comp).base },
|
||||
.Unknown => IrVal.Unknown,
|
||||
.NoReturn => IrVal{ .KnownValue = &Value.NoReturn.get(self.comp).base },
|
||||
.Void => IrVal{ .KnownValue = &Value.Void.get(self.comp).base },
|
||||
},
|
||||
.ref_count = 0,
|
||||
.span = span,
|
||||
|
@ -1813,9 +1812,9 @@ pub const Builder = struct {
|
|||
for (@field(inst.params, @memberName(I.Params, i))) |other|
|
||||
other.ref(self);
|
||||
},
|
||||
Type.Pointer.Mut,
|
||||
Type.Pointer.Vol,
|
||||
Type.Pointer.Size,
|
||||
.Mut,
|
||||
.Vol,
|
||||
.Size,
|
||||
LVal,
|
||||
*Decl,
|
||||
*Scope.Var,
|
||||
|
@ -1915,8 +1914,8 @@ pub const Builder = struct {
|
|||
var s = scope;
|
||||
while (true) {
|
||||
switch (s.id) {
|
||||
Scope.Id.Root => return Ident.NotFound,
|
||||
Scope.Id.Decls => {
|
||||
.Root => return .NotFound,
|
||||
.Decls => {
|
||||
const decls = @fieldParentPtr(Scope.Decls, "base", s);
|
||||
const locked_table = decls.table.acquireRead();
|
||||
defer locked_table.release();
|
||||
|
@ -1924,7 +1923,7 @@ pub const Builder = struct {
|
|||
return Ident{ .Decl = entry.value };
|
||||
}
|
||||
},
|
||||
Scope.Id.Var => {
|
||||
.Var => {
|
||||
const var_scope = @fieldParentPtr(Scope.Var, "base", s);
|
||||
if (mem.eql(u8, var_scope.name, name)) {
|
||||
return Ident{ .VarScope = var_scope };
|
||||
|
@ -2047,7 +2046,7 @@ const Analyze = struct {
|
|||
fn implicitCast(self: *Analyze, target: *Inst, optional_dest_type: ?*Type) Analyze.Error!*Inst {
|
||||
const dest_type = optional_dest_type orelse return target;
|
||||
const from_type = target.getKnownType();
|
||||
if (from_type == dest_type or from_type.id == Type.Id.NoReturn) return target;
|
||||
if (from_type == dest_type or from_type.id == .NoReturn) return target;
|
||||
return self.analyzeCast(target, target, dest_type);
|
||||
}
|
||||
|
||||
|
@ -2311,7 +2310,7 @@ const Analyze = struct {
|
|||
//}
|
||||
|
||||
// cast from comptime-known integer to another integer where the value fits
|
||||
if (target.isCompTime() and (from_type.id == Type.Id.Int or from_type.id == Type.Id.ComptimeInt)) cast: {
|
||||
if (target.isCompTime() and (from_type.id == .Int or from_type.id == .ComptimeInt)) cast: {
|
||||
const target_val = target.val.KnownValue;
|
||||
const from_int = &target_val.cast(Value.Int).?.big_int;
|
||||
const fits = fits: {
|
||||
|
@ -2534,7 +2533,7 @@ pub async fn gen(
|
|||
entry_block.ref(&irb); // Entry block gets a reference because we enter it to begin.
|
||||
try irb.setCursorAtEndAndAppendBlock(entry_block);
|
||||
|
||||
const result = try irb.genNode(body_node, scope, LVal.None);
|
||||
const result = try irb.genNode(body_node, scope, .None);
|
||||
if (!result.isNoReturn()) {
|
||||
// no need for save_err_ret_addr because this cannot return error
|
||||
_ = try irb.genAsyncReturn(scope, Span.token(body_node.lastToken()), result, true);
|
||||
|
|
|
@ -73,7 +73,7 @@ pub const LibCInstallation = struct {
|
|||
if (std.mem.eql(u8, name, key)) {
|
||||
found_keys[i].found = true;
|
||||
switch (@typeInfo(@typeOf(@field(self, key)))) {
|
||||
builtin.TypeId.Optional => {
|
||||
.Optional => {
|
||||
if (value.len == 0) {
|
||||
@field(self, key) = null;
|
||||
} else {
|
||||
|
@ -208,7 +208,7 @@ pub const LibCInstallation = struct {
|
|||
}
|
||||
|
||||
switch (exec_result.term) {
|
||||
std.ChildProcess.Term.Exited => |code| {
|
||||
.Exited => |code| {
|
||||
if (code != 0) return error.CCompilerExitCode;
|
||||
},
|
||||
else => {
|
||||
|
@ -284,9 +284,9 @@ pub const LibCInstallation = struct {
|
|||
const stream = &std.io.BufferOutStream.init(&result_buf).stream;
|
||||
try stream.print("{}\\Lib\\{}\\ucrt\\", search.path, search.version);
|
||||
switch (builtin.arch) {
|
||||
builtin.Arch.i386 => try stream.write("x86"),
|
||||
builtin.Arch.x86_64 => try stream.write("x64"),
|
||||
builtin.Arch.aarch64 => try stream.write("arm"),
|
||||
.i386 => try stream.write("x86"),
|
||||
.x86_64 => try stream.write("x64"),
|
||||
.aarch64 => try stream.write("arm"),
|
||||
else => return error.UnsupportedArchitecture,
|
||||
}
|
||||
const ucrt_lib_path = try fs.path.join(
|
||||
|
@ -362,9 +362,9 @@ pub const LibCInstallation = struct {
|
|||
const stream = &std.io.BufferOutStream.init(&result_buf).stream;
|
||||
try stream.print("{}\\Lib\\{}\\um\\", search.path, search.version);
|
||||
switch (builtin.arch) {
|
||||
builtin.Arch.i386 => try stream.write("x86\\"),
|
||||
builtin.Arch.x86_64 => try stream.write("x64\\"),
|
||||
builtin.Arch.aarch64 => try stream.write("arm\\"),
|
||||
.i386 => try stream.write("x86\\"),
|
||||
.x86_64 => try stream.write("x64\\"),
|
||||
.aarch64 => try stream.write("arm\\"),
|
||||
else => return error.UnsupportedArchitecture,
|
||||
}
|
||||
const kernel32_path = try fs.path.join(
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const c = @import("c.zig");
|
||||
const builtin = @import("builtin");
|
||||
const ObjectFormat = builtin.ObjectFormat;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
const Target = std.Target;
|
||||
const ObjectFormat = Target.ObjectFormat;
|
||||
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
|
@ -26,7 +25,7 @@ pub async fn link(comp: *Compilation) !void {
|
|||
.comp = comp,
|
||||
.arena = std.heap.ArenaAllocator.init(comp.gpa()),
|
||||
.args = undefined,
|
||||
.link_in_crt = comp.haveLibC() and comp.kind == Compilation.Kind.Exe,
|
||||
.link_in_crt = comp.haveLibC() and comp.kind == .Exe,
|
||||
.link_err = {},
|
||||
.link_msg = undefined,
|
||||
.libc = undefined,
|
||||
|
@ -41,13 +40,13 @@ pub async fn link(comp: *Compilation) !void {
|
|||
} else {
|
||||
ctx.out_file_path = try std.Buffer.init(&ctx.arena.allocator, comp.name.toSliceConst());
|
||||
switch (comp.kind) {
|
||||
Compilation.Kind.Exe => {
|
||||
.Exe => {
|
||||
try ctx.out_file_path.append(comp.target.exeFileExt());
|
||||
},
|
||||
Compilation.Kind.Lib => {
|
||||
.Lib => {
|
||||
try ctx.out_file_path.append(comp.target.libFileExt(comp.is_static));
|
||||
},
|
||||
Compilation.Kind.Obj => {
|
||||
.Obj => {
|
||||
try ctx.out_file_path.append(comp.target.objFileExt());
|
||||
},
|
||||
}
|
||||
|
@ -121,21 +120,21 @@ fn linkDiagCallbackErrorable(ctx: *Context, msg: []const u8) !void {
|
|||
|
||||
fn toExternObjectFormatType(ofmt: ObjectFormat) c.ZigLLVM_ObjectFormatType {
|
||||
return switch (ofmt) {
|
||||
ObjectFormat.unknown => c.ZigLLVM_UnknownObjectFormat,
|
||||
ObjectFormat.coff => c.ZigLLVM_COFF,
|
||||
ObjectFormat.elf => c.ZigLLVM_ELF,
|
||||
ObjectFormat.macho => c.ZigLLVM_MachO,
|
||||
ObjectFormat.wasm => c.ZigLLVM_Wasm,
|
||||
.unknown => c.ZigLLVM_UnknownObjectFormat,
|
||||
.coff => c.ZigLLVM_COFF,
|
||||
.elf => c.ZigLLVM_ELF,
|
||||
.macho => c.ZigLLVM_MachO,
|
||||
.wasm => c.ZigLLVM_Wasm,
|
||||
};
|
||||
}
|
||||
|
||||
fn constructLinkerArgs(ctx: *Context) !void {
|
||||
switch (ctx.comp.target.getObjectFormat()) {
|
||||
ObjectFormat.unknown => unreachable,
|
||||
ObjectFormat.coff => return constructLinkerArgsCoff(ctx),
|
||||
ObjectFormat.elf => return constructLinkerArgsElf(ctx),
|
||||
ObjectFormat.macho => return constructLinkerArgsMachO(ctx),
|
||||
ObjectFormat.wasm => return constructLinkerArgsWasm(ctx),
|
||||
.unknown => unreachable,
|
||||
.coff => return constructLinkerArgsCoff(ctx),
|
||||
.elf => return constructLinkerArgsElf(ctx),
|
||||
.macho => return constructLinkerArgsMachO(ctx),
|
||||
.wasm => return constructLinkerArgsWasm(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,9 +323,9 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
|
|||
}
|
||||
|
||||
switch (ctx.comp.target.getArch()) {
|
||||
builtin.Arch.i386 => try ctx.args.append(c"-MACHINE:X86"),
|
||||
builtin.Arch.x86_64 => try ctx.args.append(c"-MACHINE:X64"),
|
||||
builtin.Arch.aarch64 => try ctx.args.append(c"-MACHINE:ARM"),
|
||||
.i386 => try ctx.args.append(c"-MACHINE:X86"),
|
||||
.x86_64 => try ctx.args.append(c"-MACHINE:X64"),
|
||||
.aarch64 => try ctx.args.append(c"-MACHINE:ARM"),
|
||||
else => return error.UnsupportedLinkArchitecture,
|
||||
}
|
||||
|
||||
|
@ -336,7 +335,7 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
|
|||
try ctx.args.append(c"/SUBSYSTEM:console");
|
||||
}
|
||||
|
||||
const is_library = ctx.comp.kind == Compilation.Kind.Lib;
|
||||
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);
|
||||
|
@ -349,7 +348,7 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
|
|||
|
||||
if (ctx.link_in_crt) {
|
||||
const lib_str = if (ctx.comp.is_static) "lib" else "";
|
||||
const d_str = if (ctx.comp.build_mode == builtin.Mode.Debug) "d" else "";
|
||||
const d_str = if (ctx.comp.build_mode == .Debug) "d" else "";
|
||||
|
||||
if (ctx.comp.is_static) {
|
||||
const cmt_lib_name = try std.fmt.allocPrint(&ctx.arena.allocator, "libcmt{}.lib\x00", d_str);
|
||||
|
@ -400,7 +399,7 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
|
|||
try addFnObjects(ctx);
|
||||
|
||||
switch (ctx.comp.kind) {
|
||||
Compilation.Kind.Exe, Compilation.Kind.Lib => {
|
||||
.Exe, .Lib => {
|
||||
if (!ctx.comp.haveLibC()) {
|
||||
@panic("TODO");
|
||||
//Buf *builtin_o_path = build_o(g, "builtin");
|
||||
|
@ -412,7 +411,7 @@ fn constructLinkerArgsCoff(ctx: *Context) !void {
|
|||
//Buf *compiler_rt_o_path = build_compiler_rt(g);
|
||||
//lj->args.append(buf_ptr(compiler_rt_o_path));
|
||||
},
|
||||
Compilation.Kind.Obj => {},
|
||||
.Obj => {},
|
||||
}
|
||||
|
||||
//Buf *def_contents = buf_alloc();
|
||||
|
@ -469,7 +468,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
|
|||
try ctx.args.append(c"-export_dynamic");
|
||||
}
|
||||
|
||||
const is_lib = ctx.comp.kind == Compilation.Kind.Lib;
|
||||
const is_lib = ctx.comp.kind == .Lib;
|
||||
const shared = !ctx.comp.is_static and is_lib;
|
||||
if (ctx.comp.is_static) {
|
||||
try ctx.args.append(c"-static");
|
||||
|
@ -512,14 +511,14 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
|
|||
|
||||
const platform = try DarwinPlatform.get(ctx.comp);
|
||||
switch (platform.kind) {
|
||||
DarwinPlatform.Kind.MacOS => try ctx.args.append(c"-macosx_version_min"),
|
||||
DarwinPlatform.Kind.IPhoneOS => try ctx.args.append(c"-iphoneos_version_min"),
|
||||
DarwinPlatform.Kind.IPhoneOSSimulator => try ctx.args.append(c"-ios_simulator_version_min"),
|
||||
.MacOS => try ctx.args.append(c"-macosx_version_min"),
|
||||
.IPhoneOS => try ctx.args.append(c"-iphoneos_version_min"),
|
||||
.IPhoneOSSimulator => try ctx.args.append(c"-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);
|
||||
|
||||
if (ctx.comp.kind == Compilation.Kind.Exe) {
|
||||
if (ctx.comp.kind == .Exe) {
|
||||
if (ctx.comp.is_static) {
|
||||
try ctx.args.append(c"-no_pie");
|
||||
} else {
|
||||
|
@ -542,7 +541,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
|
|||
try ctx.args.append(c"-lcrt0.o");
|
||||
} else {
|
||||
switch (platform.kind) {
|
||||
DarwinPlatform.Kind.MacOS => {
|
||||
.MacOS => {
|
||||
if (platform.versionLessThan(10, 5)) {
|
||||
try ctx.args.append(c"-lcrt1.o");
|
||||
} else if (platform.versionLessThan(10, 6)) {
|
||||
|
@ -551,8 +550,8 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
|
|||
try ctx.args.append(c"-lcrt1.10.6.o");
|
||||
}
|
||||
},
|
||||
DarwinPlatform.Kind.IPhoneOS => {
|
||||
if (ctx.comp.target.getArch() == builtin.Arch.aarch64) {
|
||||
.IPhoneOS => {
|
||||
if (ctx.comp.target.getArch() == .aarch64) {
|
||||
// iOS does not need any crt1 files for arm64
|
||||
} else if (platform.versionLessThan(3, 1)) {
|
||||
try ctx.args.append(c"-lcrt1.o");
|
||||
|
@ -560,7 +559,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
|
|||
try ctx.args.append(c"-lcrt1.3.1.o");
|
||||
}
|
||||
},
|
||||
DarwinPlatform.Kind.IPhoneOSSimulator => {}, // no crt1.o needed
|
||||
.IPhoneOSSimulator => {}, // no crt1.o needed
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -605,7 +604,7 @@ fn constructLinkerArgsMachO(ctx: *Context) !void {
|
|||
try ctx.args.append(c"dynamic_lookup");
|
||||
}
|
||||
|
||||
if (platform.kind == DarwinPlatform.Kind.MacOS) {
|
||||
if (platform.kind == .MacOS) {
|
||||
if (platform.versionLessThan(10, 5)) {
|
||||
try ctx.args.append(c"-lgcc_s.10.4");
|
||||
} else if (platform.versionLessThan(10, 6)) {
|
||||
|
@ -659,17 +658,17 @@ const DarwinPlatform = struct {
|
|||
fn get(comp: *Compilation) !DarwinPlatform {
|
||||
var result: DarwinPlatform = undefined;
|
||||
const ver_str = switch (comp.darwin_version_min) {
|
||||
Compilation.DarwinVersionMin.MacOS => |ver| blk: {
|
||||
result.kind = Kind.MacOS;
|
||||
.MacOS => |ver| blk: {
|
||||
result.kind = .MacOS;
|
||||
break :blk ver;
|
||||
},
|
||||
Compilation.DarwinVersionMin.Ios => |ver| blk: {
|
||||
result.kind = Kind.IPhoneOS;
|
||||
.Ios => |ver| blk: {
|
||||
result.kind = .IPhoneOS;
|
||||
break :blk ver;
|
||||
},
|
||||
Compilation.DarwinVersionMin.None => blk: {
|
||||
.None => blk: {
|
||||
assert(comp.target.getOs() == .macosx);
|
||||
result.kind = Kind.MacOS;
|
||||
result.kind = .MacOS;
|
||||
break :blk "10.14";
|
||||
},
|
||||
};
|
||||
|
@ -686,11 +685,11 @@ const DarwinPlatform = struct {
|
|||
return error.InvalidDarwinVersionString;
|
||||
}
|
||||
|
||||
if (result.kind == Kind.IPhoneOS) {
|
||||
if (result.kind == .IPhoneOS) {
|
||||
switch (comp.target.getArch()) {
|
||||
builtin.Arch.i386,
|
||||
builtin.Arch.x86_64,
|
||||
=> result.kind = Kind.IPhoneOSSimulator,
|
||||
.i386,
|
||||
.x86_64,
|
||||
=> result.kind = .IPhoneOSSimulator,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
const builtin = @import("builtin");
|
||||
const c = @import("c.zig");
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
@ -269,7 +268,7 @@ pub const FnInline = extern enum {
|
|||
};
|
||||
|
||||
fn removeNullability(comptime T: type) type {
|
||||
comptime assert(@typeInfo(T).Pointer.size == @import("builtin").TypeInfo.Pointer.Size.C);
|
||||
comptime assert(@typeInfo(T).Pointer.size == .C);
|
||||
return *T.Child;
|
||||
}
|
||||
|
||||
|
|
|
@ -266,16 +266,16 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
|
|||
const build_mode = blk: {
|
||||
if (flags.single("mode")) |mode_flag| {
|
||||
if (mem.eql(u8, mode_flag, "debug")) {
|
||||
break :blk builtin.Mode.Debug;
|
||||
break :blk std.builtin.Mode.Debug;
|
||||
} else if (mem.eql(u8, mode_flag, "release-fast")) {
|
||||
break :blk builtin.Mode.ReleaseFast;
|
||||
break :blk std.builtin.Mode.ReleaseFast;
|
||||
} else if (mem.eql(u8, mode_flag, "release-safe")) {
|
||||
break :blk builtin.Mode.ReleaseSafe;
|
||||
break :blk std.builtin.Mode.ReleaseSafe;
|
||||
} else if (mem.eql(u8, mode_flag, "release-small")) {
|
||||
break :blk builtin.Mode.ReleaseSmall;
|
||||
break :blk std.builtin.Mode.ReleaseSmall;
|
||||
} else unreachable;
|
||||
} else {
|
||||
break :blk builtin.Mode.Debug;
|
||||
break :blk std.builtin.Mode.Debug;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -475,13 +475,13 @@ async fn processBuildEvents(comp: *Compilation, color: errmsg.Color) void {
|
|||
count += 1;
|
||||
|
||||
switch (build_event) {
|
||||
Compilation.Event.Ok => {
|
||||
.Ok => {
|
||||
stderr.print("Build {} succeeded\n", count) catch process.exit(1);
|
||||
},
|
||||
Compilation.Event.Error => |err| {
|
||||
.Error => |err| {
|
||||
stderr.print("Build {} failed: {}\n", count, @errorName(err)) catch process.exit(1);
|
||||
},
|
||||
Compilation.Event.Fail => |msgs| {
|
||||
.Fail => |msgs| {
|
||||
stderr.print("Build {} compile errors:\n", count) catch process.exit(1);
|
||||
for (msgs) |msg| {
|
||||
defer msg.destroy();
|
||||
|
@ -795,8 +795,8 @@ fn cmdTargets(allocator: *Allocator, args: []const []const u8) !void {
|
|||
try stdout.write("Operating Systems:\n");
|
||||
{
|
||||
comptime var i: usize = 0;
|
||||
inline while (i < @memberCount(builtin.Os)) : (i += 1) {
|
||||
comptime const os_tag = @memberName(builtin.Os, i);
|
||||
inline while (i < @memberCount(Target.Os)) : (i += 1) {
|
||||
comptime const os_tag = @memberName(Target.Os, i);
|
||||
// NOTE: Cannot use empty string, see #918.
|
||||
comptime const native_str = if (comptime mem.eql(u8, os_tag, @tagName(builtin.os))) " (native)\n" else "\n";
|
||||
|
||||
|
@ -808,8 +808,8 @@ fn cmdTargets(allocator: *Allocator, args: []const []const u8) !void {
|
|||
try stdout.write("C ABIs:\n");
|
||||
{
|
||||
comptime var i: usize = 0;
|
||||
inline while (i < @memberCount(builtin.Abi)) : (i += 1) {
|
||||
comptime const abi_tag = @memberName(builtin.Abi, i);
|
||||
inline while (i < @memberCount(Target.Abi)) : (i += 1) {
|
||||
comptime const abi_tag = @memberName(Target.Abi, i);
|
||||
// NOTE: Cannot use empty string, see #918.
|
||||
comptime const native_str = if (comptime mem.eql(u8, abi_tag, @tagName(builtin.abi))) " (native)\n" else "\n";
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const Allocator = mem.Allocator;
|
||||
const Decl = @import("decl.zig").Decl;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
|
@ -28,15 +27,15 @@ pub const Scope = struct {
|
|||
if (base.ref_count.decr() == 1) {
|
||||
if (base.parent) |parent| parent.deref(comp);
|
||||
switch (base.id) {
|
||||
Id.Root => @fieldParentPtr(Root, "base", base).destroy(comp),
|
||||
Id.Decls => @fieldParentPtr(Decls, "base", base).destroy(comp),
|
||||
Id.Block => @fieldParentPtr(Block, "base", base).destroy(comp),
|
||||
Id.FnDef => @fieldParentPtr(FnDef, "base", base).destroy(comp),
|
||||
Id.CompTime => @fieldParentPtr(CompTime, "base", base).destroy(comp),
|
||||
Id.Defer => @fieldParentPtr(Defer, "base", base).destroy(comp),
|
||||
Id.DeferExpr => @fieldParentPtr(DeferExpr, "base", base).destroy(comp),
|
||||
Id.Var => @fieldParentPtr(Var, "base", base).destroy(comp),
|
||||
Id.AstTree => @fieldParentPtr(AstTree, "base", base).destroy(comp),
|
||||
.Root => @fieldParentPtr(Root, "base", base).destroy(comp),
|
||||
.Decls => @fieldParentPtr(Decls, "base", base).destroy(comp),
|
||||
.Block => @fieldParentPtr(Block, "base", base).destroy(comp),
|
||||
.FnDef => @fieldParentPtr(FnDef, "base", base).destroy(comp),
|
||||
.CompTime => @fieldParentPtr(CompTime, "base", base).destroy(comp),
|
||||
.Defer => @fieldParentPtr(Defer, "base", base).destroy(comp),
|
||||
.DeferExpr => @fieldParentPtr(DeferExpr, "base", base).destroy(comp),
|
||||
.Var => @fieldParentPtr(Var, "base", base).destroy(comp),
|
||||
.AstTree => @fieldParentPtr(AstTree, "base", base).destroy(comp),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +45,7 @@ pub const Scope = struct {
|
|||
while (scope.parent) |parent| {
|
||||
scope = parent;
|
||||
}
|
||||
assert(scope.id == Id.Root);
|
||||
assert(scope.id == .Root);
|
||||
return @fieldParentPtr(Root, "base", scope);
|
||||
}
|
||||
|
||||
|
@ -54,17 +53,17 @@ pub const Scope = struct {
|
|||
var scope = base;
|
||||
while (true) {
|
||||
switch (scope.id) {
|
||||
Id.FnDef => return @fieldParentPtr(FnDef, "base", scope),
|
||||
Id.Root, Id.Decls => return null,
|
||||
.FnDef => return @fieldParentPtr(FnDef, "base", scope),
|
||||
.Root, .Decls => return null,
|
||||
|
||||
Id.Block,
|
||||
Id.Defer,
|
||||
Id.DeferExpr,
|
||||
Id.CompTime,
|
||||
Id.Var,
|
||||
.Block,
|
||||
.Defer,
|
||||
.DeferExpr,
|
||||
.CompTime,
|
||||
.Var,
|
||||
=> scope = scope.parent.?,
|
||||
|
||||
Id.AstTree => unreachable,
|
||||
.AstTree => unreachable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,20 +72,20 @@ pub const Scope = struct {
|
|||
var scope = base;
|
||||
while (true) {
|
||||
switch (scope.id) {
|
||||
Id.DeferExpr => return @fieldParentPtr(DeferExpr, "base", scope),
|
||||
.DeferExpr => return @fieldParentPtr(DeferExpr, "base", scope),
|
||||
|
||||
Id.FnDef,
|
||||
Id.Decls,
|
||||
.FnDef,
|
||||
.Decls,
|
||||
=> return null,
|
||||
|
||||
Id.Block,
|
||||
Id.Defer,
|
||||
Id.CompTime,
|
||||
Id.Root,
|
||||
Id.Var,
|
||||
.Block,
|
||||
.Defer,
|
||||
.CompTime,
|
||||
.Root,
|
||||
.Var,
|
||||
=> scope = scope.parent orelse return null,
|
||||
|
||||
Id.AstTree => unreachable,
|
||||
.AstTree => unreachable,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +122,7 @@ pub const Scope = struct {
|
|||
const self = try comp.gpa().create(Root);
|
||||
self.* = Root{
|
||||
.base = Scope{
|
||||
.id = Id.Root,
|
||||
.id = .Root,
|
||||
.parent = null,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
|
@ -155,7 +154,7 @@ pub const Scope = struct {
|
|||
.base = undefined,
|
||||
.tree = tree,
|
||||
};
|
||||
self.base.init(Id.AstTree, &root_scope.base);
|
||||
self.base.init(.AstTree, &root_scope.base);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -186,7 +185,7 @@ pub const Scope = struct {
|
|||
.base = undefined,
|
||||
.table = event.RwLocked(Decl.Table).init(Decl.Table.init(comp.gpa())),
|
||||
};
|
||||
self.base.init(Id.Decls, parent);
|
||||
self.base.init(.Decls, parent);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -219,15 +218,15 @@ pub const Scope = struct {
|
|||
|
||||
fn get(self: Safety, comp: *Compilation) bool {
|
||||
return switch (self) {
|
||||
Safety.Auto => switch (comp.build_mode) {
|
||||
builtin.Mode.Debug,
|
||||
builtin.Mode.ReleaseSafe,
|
||||
.Auto => switch (comp.build_mode) {
|
||||
.Debug,
|
||||
.ReleaseSafe,
|
||||
=> true,
|
||||
builtin.Mode.ReleaseFast,
|
||||
builtin.Mode.ReleaseSmall,
|
||||
.ReleaseFast,
|
||||
.ReleaseSmall,
|
||||
=> false,
|
||||
},
|
||||
@TagType(Safety).Manual => |man| man.enabled,
|
||||
.Manual => |man| man.enabled,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -243,7 +242,7 @@ pub const Scope = struct {
|
|||
.is_comptime = undefined,
|
||||
.safety = Safety.Auto,
|
||||
};
|
||||
self.base.init(Id.Block, parent);
|
||||
self.base.init(.Block, parent);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -266,7 +265,7 @@ pub const Scope = struct {
|
|||
.base = undefined,
|
||||
.fn_val = null,
|
||||
};
|
||||
self.base.init(Id.FnDef, parent);
|
||||
self.base.init(.FnDef, parent);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -282,7 +281,7 @@ pub const Scope = struct {
|
|||
pub fn create(comp: *Compilation, parent: *Scope) !*CompTime {
|
||||
const self = try comp.gpa().create(CompTime);
|
||||
self.* = CompTime{ .base = undefined };
|
||||
self.base.init(Id.CompTime, parent);
|
||||
self.base.init(.CompTime, parent);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -314,7 +313,7 @@ pub const Scope = struct {
|
|||
.defer_expr_scope = defer_expr_scope,
|
||||
.kind = kind,
|
||||
};
|
||||
self.base.init(Id.Defer, parent);
|
||||
self.base.init(.Defer, parent);
|
||||
defer_expr_scope.base.ref();
|
||||
return self;
|
||||
}
|
||||
|
@ -338,7 +337,7 @@ pub const Scope = struct {
|
|||
.expr_node = expr_node,
|
||||
.reported_err = false,
|
||||
};
|
||||
self.base.init(Id.DeferExpr, parent);
|
||||
self.base.init(.DeferExpr, parent);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -404,14 +403,14 @@ pub const Scope = struct {
|
|||
.src_node = src_node,
|
||||
.data = undefined,
|
||||
};
|
||||
self.base.init(Id.Var, parent);
|
||||
self.base.init(.Var, parent);
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Var, comp: *Compilation) void {
|
||||
switch (self.data) {
|
||||
Data.Param => {},
|
||||
Data.Const => |value| value.deref(comp),
|
||||
.Param => {},
|
||||
.Const => |value| value.deref(comp),
|
||||
}
|
||||
comp.gpa().destroy(self);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// This is Zig code that is used by both stage1 and stage2.
|
||||
// The prototypes in src/userland.h must match these definitions.
|
||||
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const io = std.io;
|
||||
const mem = std.mem;
|
||||
|
@ -358,9 +357,9 @@ fn printErrMsgToFile(
|
|||
color: errmsg.Color,
|
||||
) !void {
|
||||
const color_on = switch (color) {
|
||||
errmsg.Color.Auto => file.isTty(),
|
||||
errmsg.Color.On => true,
|
||||
errmsg.Color.Off => false,
|
||||
.Auto => file.isTty(),
|
||||
.On => true,
|
||||
.Off => false,
|
||||
};
|
||||
const lok_token = parse_error.loc();
|
||||
const span = errmsg.Span{
|
||||
|
@ -425,8 +424,8 @@ export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextRes
|
|||
const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text");
|
||||
return stage2_DepNextResult{
|
||||
.type_id = switch (token.id) {
|
||||
.target => stage2_DepNextResult.TypeId.target,
|
||||
.prereq => stage2_DepNextResult.TypeId.prereq,
|
||||
.target => .target,
|
||||
.prereq => .prereq,
|
||||
},
|
||||
.textz = textz.toSlice().ptr,
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const builtin = @import("builtin");
|
||||
const Target = std.Target;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
const introspect = @import("introspect.zig");
|
||||
|
@ -45,7 +44,7 @@ pub const TestContext = struct {
|
|||
errdefer self.zig_compiler.deinit();
|
||||
|
||||
self.group = std.event.Group(anyerror!void).init(allocator);
|
||||
errdefer self.group.deinit();
|
||||
errdefer self.group.wait();
|
||||
|
||||
self.zig_lib_dir = try introspect.resolveZigLibDir(allocator);
|
||||
errdefer allocator.free(self.zig_lib_dir);
|
||||
|
@ -95,7 +94,7 @@ pub const TestContext = struct {
|
|||
file1_path,
|
||||
Target.Native,
|
||||
Compilation.Kind.Obj,
|
||||
builtin.Mode.Debug,
|
||||
.Debug,
|
||||
true, // is_static
|
||||
self.zig_lib_dir,
|
||||
);
|
||||
|
@ -129,7 +128,7 @@ pub const TestContext = struct {
|
|||
file1_path,
|
||||
Target.Native,
|
||||
Compilation.Kind.Exe,
|
||||
builtin.Mode.Debug,
|
||||
.Debug,
|
||||
false,
|
||||
self.zig_lib_dir,
|
||||
);
|
||||
|
@ -154,7 +153,7 @@ pub const TestContext = struct {
|
|||
const build_event = comp.events.get();
|
||||
|
||||
switch (build_event) {
|
||||
Compilation.Event.Ok => {
|
||||
.Ok => {
|
||||
const argv = []const []const u8{exe_file_2};
|
||||
// TODO use event loop
|
||||
const child = try std.ChildProcess.exec(allocator, argv, null, null, 1024 * 1024);
|
||||
|
@ -172,8 +171,8 @@ pub const TestContext = struct {
|
|||
return error.OutputMismatch;
|
||||
}
|
||||
},
|
||||
Compilation.Event.Error => |err| return err,
|
||||
Compilation.Event.Fail => |msgs| {
|
||||
.Error => |err| return err,
|
||||
.Fail => |msgs| {
|
||||
var stderr = try std.io.getStdErr();
|
||||
try stderr.write("build incorrectly failed:\n");
|
||||
for (msgs) |msg| {
|
||||
|
@ -196,13 +195,13 @@ pub const TestContext = struct {
|
|||
const build_event = comp.events.get();
|
||||
|
||||
switch (build_event) {
|
||||
Compilation.Event.Ok => {
|
||||
.Ok => {
|
||||
@panic("build incorrectly succeeded");
|
||||
},
|
||||
Compilation.Event.Error => |err| {
|
||||
.Error => |err| {
|
||||
@panic("build incorrectly failed");
|
||||
},
|
||||
Compilation.Event.Fail => |msgs| {
|
||||
.Fail => |msgs| {
|
||||
testing.expect(msgs.len != 0);
|
||||
for (msgs) |msg| {
|
||||
if (mem.endsWith(u8, msg.realpath, path) and mem.eql(u8, msg.text, text)) {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// and stage2. Currently the only way it is used is with `zig translate-c-2`.
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const ast = std.zig.ast;
|
||||
const Token = std.zig.Token;
|
||||
|
@ -14,7 +13,7 @@ pub const Mode = enum {
|
|||
};
|
||||
|
||||
// TODO merge with Type.Fn.CallingConvention
|
||||
const CallingConvention = builtin.TypeInfo.CallingConvention;
|
||||
const CallingConvention = std.builtin.TypeInfo.CallingConvention;
|
||||
|
||||
pub const ClangErrMsg = Stage2ErrorMsg;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const builtin = std.builtin;
|
||||
const Scope = @import("scope.zig").Scope;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
const Value = @import("value.zig").Value;
|
||||
|
@ -20,32 +20,32 @@ pub const Type = struct {
|
|||
|
||||
pub fn destroy(base: *Type, comp: *Compilation) void {
|
||||
switch (base.id) {
|
||||
Id.Struct => @fieldParentPtr(Struct, "base", base).destroy(comp),
|
||||
Id.Fn => @fieldParentPtr(Fn, "base", base).destroy(comp),
|
||||
Id.Type => @fieldParentPtr(MetaType, "base", base).destroy(comp),
|
||||
Id.Void => @fieldParentPtr(Void, "base", base).destroy(comp),
|
||||
Id.Bool => @fieldParentPtr(Bool, "base", base).destroy(comp),
|
||||
Id.NoReturn => @fieldParentPtr(NoReturn, "base", base).destroy(comp),
|
||||
Id.Int => @fieldParentPtr(Int, "base", base).destroy(comp),
|
||||
Id.Float => @fieldParentPtr(Float, "base", base).destroy(comp),
|
||||
Id.Pointer => @fieldParentPtr(Pointer, "base", base).destroy(comp),
|
||||
Id.Array => @fieldParentPtr(Array, "base", base).destroy(comp),
|
||||
Id.ComptimeFloat => @fieldParentPtr(ComptimeFloat, "base", base).destroy(comp),
|
||||
Id.ComptimeInt => @fieldParentPtr(ComptimeInt, "base", base).destroy(comp),
|
||||
Id.EnumLiteral => @fieldParentPtr(EnumLiteral, "base", base).destroy(comp),
|
||||
Id.Undefined => @fieldParentPtr(Undefined, "base", base).destroy(comp),
|
||||
Id.Null => @fieldParentPtr(Null, "base", base).destroy(comp),
|
||||
Id.Optional => @fieldParentPtr(Optional, "base", base).destroy(comp),
|
||||
Id.ErrorUnion => @fieldParentPtr(ErrorUnion, "base", base).destroy(comp),
|
||||
Id.ErrorSet => @fieldParentPtr(ErrorSet, "base", base).destroy(comp),
|
||||
Id.Enum => @fieldParentPtr(Enum, "base", base).destroy(comp),
|
||||
Id.Union => @fieldParentPtr(Union, "base", base).destroy(comp),
|
||||
Id.BoundFn => @fieldParentPtr(BoundFn, "base", base).destroy(comp),
|
||||
Id.ArgTuple => @fieldParentPtr(ArgTuple, "base", base).destroy(comp),
|
||||
Id.Opaque => @fieldParentPtr(Opaque, "base", base).destroy(comp),
|
||||
Id.Frame => @fieldParentPtr(Frame, "base", base).destroy(comp),
|
||||
Id.AnyFrame => @fieldParentPtr(AnyFrame, "base", base).destroy(comp),
|
||||
Id.Vector => @fieldParentPtr(Vector, "base", base).destroy(comp),
|
||||
.Struct => @fieldParentPtr(Struct, "base", base).destroy(comp),
|
||||
.Fn => @fieldParentPtr(Fn, "base", base).destroy(comp),
|
||||
.Type => @fieldParentPtr(MetaType, "base", base).destroy(comp),
|
||||
.Void => @fieldParentPtr(Void, "base", base).destroy(comp),
|
||||
.Bool => @fieldParentPtr(Bool, "base", base).destroy(comp),
|
||||
.NoReturn => @fieldParentPtr(NoReturn, "base", base).destroy(comp),
|
||||
.Int => @fieldParentPtr(Int, "base", base).destroy(comp),
|
||||
.Float => @fieldParentPtr(Float, "base", base).destroy(comp),
|
||||
.Pointer => @fieldParentPtr(Pointer, "base", base).destroy(comp),
|
||||
.Array => @fieldParentPtr(Array, "base", base).destroy(comp),
|
||||
.ComptimeFloat => @fieldParentPtr(ComptimeFloat, "base", base).destroy(comp),
|
||||
.ComptimeInt => @fieldParentPtr(ComptimeInt, "base", base).destroy(comp),
|
||||
.EnumLiteral => @fieldParentPtr(EnumLiteral, "base", base).destroy(comp),
|
||||
.Undefined => @fieldParentPtr(Undefined, "base", base).destroy(comp),
|
||||
.Null => @fieldParentPtr(Null, "base", base).destroy(comp),
|
||||
.Optional => @fieldParentPtr(Optional, "base", base).destroy(comp),
|
||||
.ErrorUnion => @fieldParentPtr(ErrorUnion, "base", base).destroy(comp),
|
||||
.ErrorSet => @fieldParentPtr(ErrorSet, "base", base).destroy(comp),
|
||||
.Enum => @fieldParentPtr(Enum, "base", base).destroy(comp),
|
||||
.Union => @fieldParentPtr(Union, "base", base).destroy(comp),
|
||||
.BoundFn => @fieldParentPtr(BoundFn, "base", base).destroy(comp),
|
||||
.ArgTuple => @fieldParentPtr(ArgTuple, "base", base).destroy(comp),
|
||||
.Opaque => @fieldParentPtr(Opaque, "base", base).destroy(comp),
|
||||
.Frame => @fieldParentPtr(Frame, "base", base).destroy(comp),
|
||||
.AnyFrame => @fieldParentPtr(AnyFrame, "base", base).destroy(comp),
|
||||
.Vector => @fieldParentPtr(Vector, "base", base).destroy(comp),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,108 +55,108 @@ pub const Type = struct {
|
|||
llvm_context: *llvm.Context,
|
||||
) (error{OutOfMemory}!*llvm.Type) {
|
||||
switch (base.id) {
|
||||
Id.Struct => return @fieldParentPtr(Struct, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.Fn => return @fieldParentPtr(Fn, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.Type => unreachable,
|
||||
Id.Void => unreachable,
|
||||
Id.Bool => return @fieldParentPtr(Bool, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.NoReturn => unreachable,
|
||||
Id.Int => return @fieldParentPtr(Int, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.Float => return @fieldParentPtr(Float, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.Pointer => return @fieldParentPtr(Pointer, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.Array => return @fieldParentPtr(Array, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.ComptimeFloat => unreachable,
|
||||
Id.ComptimeInt => unreachable,
|
||||
Id.EnumLiteral => unreachable,
|
||||
Id.Undefined => unreachable,
|
||||
Id.Null => unreachable,
|
||||
Id.Optional => return @fieldParentPtr(Optional, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.ErrorUnion => return @fieldParentPtr(ErrorUnion, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.ErrorSet => return @fieldParentPtr(ErrorSet, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.Enum => return @fieldParentPtr(Enum, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.Union => return @fieldParentPtr(Union, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.BoundFn => return @fieldParentPtr(BoundFn, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.ArgTuple => unreachable,
|
||||
Id.Opaque => return @fieldParentPtr(Opaque, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.Frame => return @fieldParentPtr(Frame, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.AnyFrame => return @fieldParentPtr(AnyFrame, "base", base).getLlvmType(allocator, llvm_context),
|
||||
Id.Vector => return @fieldParentPtr(Vector, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.Struct => return @fieldParentPtr(Struct, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.Fn => return @fieldParentPtr(Fn, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.Type => unreachable,
|
||||
.Void => unreachable,
|
||||
.Bool => return @fieldParentPtr(Bool, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.NoReturn => unreachable,
|
||||
.Int => return @fieldParentPtr(Int, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.Float => return @fieldParentPtr(Float, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.Pointer => return @fieldParentPtr(Pointer, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.Array => return @fieldParentPtr(Array, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.ComptimeFloat => unreachable,
|
||||
.ComptimeInt => unreachable,
|
||||
.EnumLiteral => unreachable,
|
||||
.Undefined => unreachable,
|
||||
.Null => unreachable,
|
||||
.Optional => return @fieldParentPtr(Optional, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.ErrorUnion => return @fieldParentPtr(ErrorUnion, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.ErrorSet => return @fieldParentPtr(ErrorSet, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.Enum => return @fieldParentPtr(Enum, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.Union => return @fieldParentPtr(Union, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.BoundFn => return @fieldParentPtr(BoundFn, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.ArgTuple => unreachable,
|
||||
.Opaque => return @fieldParentPtr(Opaque, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.Frame => return @fieldParentPtr(Frame, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.AnyFrame => return @fieldParentPtr(AnyFrame, "base", base).getLlvmType(allocator, llvm_context),
|
||||
.Vector => return @fieldParentPtr(Vector, "base", base).getLlvmType(allocator, llvm_context),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handleIsPtr(base: *Type) bool {
|
||||
switch (base.id) {
|
||||
Id.Type,
|
||||
Id.ComptimeFloat,
|
||||
Id.ComptimeInt,
|
||||
Id.EnumLiteral,
|
||||
Id.Undefined,
|
||||
Id.Null,
|
||||
Id.BoundFn,
|
||||
Id.ArgTuple,
|
||||
Id.Opaque,
|
||||
.Type,
|
||||
.ComptimeFloat,
|
||||
.ComptimeInt,
|
||||
.EnumLiteral,
|
||||
.Undefined,
|
||||
.Null,
|
||||
.BoundFn,
|
||||
.ArgTuple,
|
||||
.Opaque,
|
||||
=> unreachable,
|
||||
|
||||
Id.NoReturn,
|
||||
Id.Void,
|
||||
Id.Bool,
|
||||
Id.Int,
|
||||
Id.Float,
|
||||
Id.Pointer,
|
||||
Id.ErrorSet,
|
||||
Id.Enum,
|
||||
Id.Fn,
|
||||
Id.Frame,
|
||||
Id.AnyFrame,
|
||||
Id.Vector,
|
||||
.NoReturn,
|
||||
.Void,
|
||||
.Bool,
|
||||
.Int,
|
||||
.Float,
|
||||
.Pointer,
|
||||
.ErrorSet,
|
||||
.Enum,
|
||||
.Fn,
|
||||
.Frame,
|
||||
.AnyFrame,
|
||||
.Vector,
|
||||
=> return false,
|
||||
|
||||
Id.Struct => @panic("TODO"),
|
||||
Id.Array => @panic("TODO"),
|
||||
Id.Optional => @panic("TODO"),
|
||||
Id.ErrorUnion => @panic("TODO"),
|
||||
Id.Union => @panic("TODO"),
|
||||
.Struct => @panic("TODO"),
|
||||
.Array => @panic("TODO"),
|
||||
.Optional => @panic("TODO"),
|
||||
.ErrorUnion => @panic("TODO"),
|
||||
.Union => @panic("TODO"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hasBits(base: *Type) bool {
|
||||
switch (base.id) {
|
||||
Id.Type,
|
||||
Id.ComptimeFloat,
|
||||
Id.ComptimeInt,
|
||||
Id.EnumLiteral,
|
||||
Id.Undefined,
|
||||
Id.Null,
|
||||
Id.BoundFn,
|
||||
Id.ArgTuple,
|
||||
Id.Opaque,
|
||||
.Type,
|
||||
.ComptimeFloat,
|
||||
.ComptimeInt,
|
||||
.EnumLiteral,
|
||||
.Undefined,
|
||||
.Null,
|
||||
.BoundFn,
|
||||
.ArgTuple,
|
||||
.Opaque,
|
||||
=> unreachable,
|
||||
|
||||
Id.Void,
|
||||
Id.NoReturn,
|
||||
.Void,
|
||||
.NoReturn,
|
||||
=> return false,
|
||||
|
||||
Id.Bool,
|
||||
Id.Int,
|
||||
Id.Float,
|
||||
Id.Fn,
|
||||
Id.Frame,
|
||||
Id.AnyFrame,
|
||||
Id.Vector,
|
||||
.Bool,
|
||||
.Int,
|
||||
.Float,
|
||||
.Fn,
|
||||
.Frame,
|
||||
.AnyFrame,
|
||||
.Vector,
|
||||
=> return true,
|
||||
|
||||
Id.Pointer => {
|
||||
.Pointer => {
|
||||
const ptr_type = @fieldParentPtr(Pointer, "base", base);
|
||||
return ptr_type.key.child_type.hasBits();
|
||||
},
|
||||
|
||||
Id.ErrorSet => @panic("TODO"),
|
||||
Id.Enum => @panic("TODO"),
|
||||
Id.Struct => @panic("TODO"),
|
||||
Id.Array => @panic("TODO"),
|
||||
Id.Optional => @panic("TODO"),
|
||||
Id.ErrorUnion => @panic("TODO"),
|
||||
Id.Union => @panic("TODO"),
|
||||
.ErrorSet => @panic("TODO"),
|
||||
.Enum => @panic("TODO"),
|
||||
.Struct => @panic("TODO"),
|
||||
.Array => @panic("TODO"),
|
||||
.Optional => @panic("TODO"),
|
||||
.ErrorUnion => @panic("TODO"),
|
||||
.Union => @panic("TODO"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ pub const Type = struct {
|
|||
fn init(base: *Type, comp: *Compilation, id: Id, name: []const u8) void {
|
||||
base.* = Type{
|
||||
.base = Value{
|
||||
.id = Value.Id.Type,
|
||||
.id = .Type,
|
||||
.typ = &MetaType.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
|
@ -272,11 +272,11 @@ pub const Type = struct {
|
|||
var result: u32 = 0;
|
||||
result +%= hashAny(self.alignment, 0);
|
||||
switch (self.data) {
|
||||
Kind.Generic => |generic| {
|
||||
.Generic => |generic| {
|
||||
result +%= hashAny(generic.param_count, 1);
|
||||
result +%= hashAny(generic.cc, 3);
|
||||
},
|
||||
Kind.Normal => |normal| {
|
||||
.Normal => |normal| {
|
||||
result +%= hashAny(normal.return_type, 4);
|
||||
result +%= hashAny(normal.is_var_args, 5);
|
||||
result +%= hashAny(normal.cc, 6);
|
||||
|
@ -294,14 +294,14 @@ pub const Type = struct {
|
|||
if (self.alignment) |self_align| {
|
||||
if (self_align != other.alignment.?) return false;
|
||||
}
|
||||
if (@TagType(Data)(self.data) != @TagType(Data)(other.data)) return false;
|
||||
if (self.data != other.data) return false;
|
||||
switch (self.data) {
|
||||
Kind.Generic => |*self_generic| {
|
||||
.Generic => |*self_generic| {
|
||||
const other_generic = &other.data.Generic;
|
||||
if (self_generic.param_count != other_generic.param_count) return false;
|
||||
if (self_generic.cc != other_generic.cc) return false;
|
||||
},
|
||||
Kind.Normal => |*self_normal| {
|
||||
.Normal => |*self_normal| {
|
||||
const other_normal = &other.data.Normal;
|
||||
if (self_normal.cc != other_normal.cc) return false;
|
||||
if (self_normal.is_var_args != other_normal.is_var_args) return false;
|
||||
|
@ -318,8 +318,8 @@ pub const Type = struct {
|
|||
|
||||
pub fn deref(key: Key, comp: *Compilation) void {
|
||||
switch (key.data) {
|
||||
Kind.Generic => {},
|
||||
Kind.Normal => |normal| {
|
||||
.Generic => {},
|
||||
.Normal => |normal| {
|
||||
normal.return_type.base.deref(comp);
|
||||
for (normal.params) |param| {
|
||||
param.typ.base.deref(comp);
|
||||
|
@ -330,8 +330,8 @@ pub const Type = struct {
|
|||
|
||||
pub fn ref(key: Key) void {
|
||||
switch (key.data) {
|
||||
Kind.Generic => {},
|
||||
Kind.Normal => |normal| {
|
||||
.Generic => {},
|
||||
.Normal => |normal| {
|
||||
normal.return_type.base.ref();
|
||||
for (normal.params) |param| {
|
||||
param.typ.base.ref();
|
||||
|
@ -361,8 +361,8 @@ pub const Type = struct {
|
|||
|
||||
pub fn paramCount(self: *Fn) usize {
|
||||
return switch (self.key.data) {
|
||||
Kind.Generic => |generic| generic.param_count,
|
||||
Kind.Normal => |normal| normal.params.len,
|
||||
.Generic => |generic| generic.param_count,
|
||||
.Normal => |normal| normal.params.len,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -396,7 +396,7 @@ pub const Type = struct {
|
|||
const name_stream = &std.io.BufferOutStream.init(&name_buf).stream;
|
||||
|
||||
switch (key.data) {
|
||||
Kind.Generic => |generic| {
|
||||
.Generic => |generic| {
|
||||
self.non_key = NonKey{ .Generic = {} };
|
||||
const cc_str = ccFnTypeStr(generic.cc);
|
||||
try name_stream.write(cc_str);
|
||||
|
@ -412,7 +412,7 @@ pub const Type = struct {
|
|||
}
|
||||
try name_stream.write(" var");
|
||||
},
|
||||
Kind.Normal => |normal| {
|
||||
.Normal => |normal| {
|
||||
self.non_key = NonKey{
|
||||
.Normal = NonKey.Normal{ .variable_list = std.ArrayList(*Scope.Var).init(comp.gpa()) },
|
||||
};
|
||||
|
@ -435,7 +435,7 @@ pub const Type = struct {
|
|||
},
|
||||
}
|
||||
|
||||
self.base.init(comp, Id.Fn, name_buf.toOwnedSlice());
|
||||
self.base.init(comp, .Fn, name_buf.toOwnedSlice());
|
||||
|
||||
{
|
||||
const held = comp.fn_type_table.acquire();
|
||||
|
@ -449,8 +449,8 @@ pub const Type = struct {
|
|||
pub fn destroy(self: *Fn, comp: *Compilation) void {
|
||||
self.key.deref(comp);
|
||||
switch (self.key.data) {
|
||||
Kind.Generic => {},
|
||||
Kind.Normal => {
|
||||
.Generic => {},
|
||||
.Normal => {
|
||||
self.non_key.Normal.variable_list.deinit();
|
||||
},
|
||||
}
|
||||
|
@ -460,7 +460,7 @@ pub const Type = struct {
|
|||
pub fn getLlvmType(self: *Fn, allocator: *Allocator, llvm_context: *llvm.Context) !*llvm.Type {
|
||||
const normal = &self.key.data.Normal;
|
||||
const llvm_return_type = switch (normal.return_type.id) {
|
||||
Type.Id.Void => llvm.VoidTypeInContext(llvm_context) orelse return error.OutOfMemory,
|
||||
.Void => llvm.VoidTypeInContext(llvm_context) orelse return error.OutOfMemory,
|
||||
else => try normal.return_type.getLlvmType(allocator, llvm_context),
|
||||
};
|
||||
const llvm_param_types = try allocator.alloc(*llvm.Type, normal.params.len);
|
||||
|
@ -588,7 +588,7 @@ pub const Type = struct {
|
|||
const name = try std.fmt.allocPrint(comp.gpa(), "{c}{}", u_or_i, key.bit_count);
|
||||
errdefer comp.gpa().free(name);
|
||||
|
||||
self.base.init(comp, Id.Int, name);
|
||||
self.base.init(comp, .Int, name);
|
||||
|
||||
{
|
||||
const held = comp.int_type_table.acquire();
|
||||
|
@ -650,8 +650,8 @@ pub const Type = struct {
|
|||
pub fn hash(self: *const Key) u32 {
|
||||
var result: u32 = 0;
|
||||
result +%= switch (self.alignment) {
|
||||
Align.Abi => 0xf201c090,
|
||||
Align.Override => |x| hashAny(x, 0),
|
||||
.Abi => 0xf201c090,
|
||||
.Override => |x| hashAny(x, 0),
|
||||
};
|
||||
result +%= hashAny(self.child_type, 1);
|
||||
result +%= hashAny(self.mut, 2);
|
||||
|
@ -670,8 +670,8 @@ pub const Type = struct {
|
|||
return false;
|
||||
}
|
||||
switch (self.alignment) {
|
||||
Align.Abi => return true,
|
||||
Align.Override => |x| return x == other.alignment.Override,
|
||||
.Abi => return true,
|
||||
.Override => |x| return x == other.alignment.Override,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -714,8 +714,8 @@ pub const Type = struct {
|
|||
|
||||
pub async fn getAlignAsInt(self: *Pointer, comp: *Compilation) u32 {
|
||||
switch (self.key.alignment) {
|
||||
Align.Abi => return self.key.child_type.getAbiAlignment(comp),
|
||||
Align.Override => |alignment| return alignment,
|
||||
.Abi => return self.key.child_type.getAbiAlignment(comp),
|
||||
.Override => |alignment| return alignment,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -725,11 +725,11 @@ pub const Type = struct {
|
|||
) !*Pointer {
|
||||
var normal_key = key;
|
||||
switch (key.alignment) {
|
||||
Align.Abi => {},
|
||||
Align.Override => |alignment| {
|
||||
.Abi => {},
|
||||
.Override => |alignment| {
|
||||
const abi_align = try key.child_type.getAbiAlignment(comp);
|
||||
if (abi_align == alignment) {
|
||||
normal_key.alignment = Align.Abi;
|
||||
normal_key.alignment = .Abi;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -752,21 +752,21 @@ pub const Type = struct {
|
|||
errdefer comp.gpa().destroy(self);
|
||||
|
||||
const size_str = switch (self.key.size) {
|
||||
Size.One => "*",
|
||||
Size.Many => "[*]",
|
||||
Size.Slice => "[]",
|
||||
Size.C => "[*c]",
|
||||
.One => "*",
|
||||
.Many => "[*]",
|
||||
.Slice => "[]",
|
||||
.C => "[*c]",
|
||||
};
|
||||
const mut_str = switch (self.key.mut) {
|
||||
Mut.Const => "const ",
|
||||
Mut.Mut => "",
|
||||
.Const => "const ",
|
||||
.Mut => "",
|
||||
};
|
||||
const vol_str = switch (self.key.vol) {
|
||||
Vol.Volatile => "volatile ",
|
||||
Vol.Non => "",
|
||||
.Volatile => "volatile ",
|
||||
.Non => "",
|
||||
};
|
||||
const name = switch (self.key.alignment) {
|
||||
Align.Abi => try std.fmt.allocPrint(
|
||||
.Abi => try std.fmt.allocPrint(
|
||||
comp.gpa(),
|
||||
"{}{}{}{}",
|
||||
size_str,
|
||||
|
@ -774,7 +774,7 @@ pub const Type = struct {
|
|||
vol_str,
|
||||
self.key.child_type.name,
|
||||
),
|
||||
Align.Override => |alignment| try std.fmt.allocPrint(
|
||||
.Override => |alignment| try std.fmt.allocPrint(
|
||||
comp.gpa(),
|
||||
"{}align<{}> {}{}{}",
|
||||
size_str,
|
||||
|
@ -786,7 +786,7 @@ pub const Type = struct {
|
|||
};
|
||||
errdefer comp.gpa().free(name);
|
||||
|
||||
self.base.init(comp, Id.Pointer, name);
|
||||
self.base.init(comp, .Pointer, name);
|
||||
|
||||
{
|
||||
const held = comp.ptr_type_table.acquire();
|
||||
|
@ -854,7 +854,7 @@ pub const Type = struct {
|
|||
const name = try std.fmt.allocPrint(comp.gpa(), "[{}]{}", key.len, key.elem_type.name);
|
||||
errdefer comp.gpa().free(name);
|
||||
|
||||
self.base.init(comp, Id.Array, name);
|
||||
self.base.init(comp, .Array, name);
|
||||
|
||||
{
|
||||
const held = comp.array_type_table.acquire();
|
||||
|
@ -1054,7 +1054,7 @@ pub const Type = struct {
|
|||
|
||||
fn hashAny(x: var, comptime seed: u64) u32 {
|
||||
switch (@typeInfo(@typeOf(x))) {
|
||||
builtin.TypeId.Int => |info| {
|
||||
.Int => |info| {
|
||||
comptime var rng = comptime std.rand.DefaultPrng.init(seed);
|
||||
const unsigned_x = @bitCast(@IntType(false, info.bits), x);
|
||||
if (info.bits <= 32) {
|
||||
|
@ -1063,21 +1063,21 @@ fn hashAny(x: var, comptime seed: u64) u32 {
|
|||
return @truncate(u32, unsigned_x *% comptime rng.random.scalar(@typeOf(unsigned_x)));
|
||||
}
|
||||
},
|
||||
builtin.TypeId.Pointer => |info| {
|
||||
.Pointer => |info| {
|
||||
switch (info.size) {
|
||||
builtin.TypeInfo.Pointer.Size.One => return hashAny(@ptrToInt(x), seed),
|
||||
builtin.TypeInfo.Pointer.Size.Many => @compileError("implement hash function"),
|
||||
builtin.TypeInfo.Pointer.Size.Slice => @compileError("implement hash function"),
|
||||
builtin.TypeInfo.Pointer.Size.C => unreachable,
|
||||
.One => return hashAny(@ptrToInt(x), seed),
|
||||
.Many => @compileError("implement hash function"),
|
||||
.Slice => @compileError("implement hash function"),
|
||||
.C => unreachable,
|
||||
}
|
||||
},
|
||||
builtin.TypeId.Enum => return hashAny(@enumToInt(x), seed),
|
||||
builtin.TypeId.Bool => {
|
||||
.Enum => return hashAny(@enumToInt(x), seed),
|
||||
.Bool => {
|
||||
comptime var rng = comptime std.rand.DefaultPrng.init(seed);
|
||||
const vals = comptime [2]u32{ rng.random.scalar(u32), rng.random.scalar(u32) };
|
||||
return vals[@boolToInt(x)];
|
||||
},
|
||||
builtin.TypeId.Optional => {
|
||||
.Optional => {
|
||||
if (x) |non_opt| {
|
||||
return hashAny(non_opt, seed);
|
||||
} else {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const Scope = @import("scope.zig").Scope;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
const ObjectFile = @import("codegen.zig").ObjectFile;
|
||||
|
@ -24,15 +23,15 @@ pub const Value = struct {
|
|||
if (base.ref_count.decr() == 1) {
|
||||
base.typ.base.deref(comp);
|
||||
switch (base.id) {
|
||||
Id.Type => @fieldParentPtr(Type, "base", base).destroy(comp),
|
||||
Id.Fn => @fieldParentPtr(Fn, "base", base).destroy(comp),
|
||||
Id.FnProto => @fieldParentPtr(FnProto, "base", base).destroy(comp),
|
||||
Id.Void => @fieldParentPtr(Void, "base", base).destroy(comp),
|
||||
Id.Bool => @fieldParentPtr(Bool, "base", base).destroy(comp),
|
||||
Id.NoReturn => @fieldParentPtr(NoReturn, "base", base).destroy(comp),
|
||||
Id.Ptr => @fieldParentPtr(Ptr, "base", base).destroy(comp),
|
||||
Id.Int => @fieldParentPtr(Int, "base", base).destroy(comp),
|
||||
Id.Array => @fieldParentPtr(Array, "base", base).destroy(comp),
|
||||
.Type => @fieldParentPtr(Type, "base", base).destroy(comp),
|
||||
.Fn => @fieldParentPtr(Fn, "base", base).destroy(comp),
|
||||
.FnProto => @fieldParentPtr(FnProto, "base", base).destroy(comp),
|
||||
.Void => @fieldParentPtr(Void, "base", base).destroy(comp),
|
||||
.Bool => @fieldParentPtr(Bool, "base", base).destroy(comp),
|
||||
.NoReturn => @fieldParentPtr(NoReturn, "base", base).destroy(comp),
|
||||
.Ptr => @fieldParentPtr(Ptr, "base", base).destroy(comp),
|
||||
.Int => @fieldParentPtr(Int, "base", base).destroy(comp),
|
||||
.Array => @fieldParentPtr(Array, "base", base).destroy(comp),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,15 +58,15 @@ pub const Value = struct {
|
|||
|
||||
pub fn getLlvmConst(base: *Value, ofile: *ObjectFile) (error{OutOfMemory}!?*llvm.Value) {
|
||||
switch (base.id) {
|
||||
Id.Type => unreachable,
|
||||
Id.Fn => return @fieldParentPtr(Fn, "base", base).getLlvmConst(ofile),
|
||||
Id.FnProto => return @fieldParentPtr(FnProto, "base", base).getLlvmConst(ofile),
|
||||
Id.Void => return null,
|
||||
Id.Bool => return @fieldParentPtr(Bool, "base", base).getLlvmConst(ofile),
|
||||
Id.NoReturn => unreachable,
|
||||
Id.Ptr => return @fieldParentPtr(Ptr, "base", base).getLlvmConst(ofile),
|
||||
Id.Int => return @fieldParentPtr(Int, "base", base).getLlvmConst(ofile),
|
||||
Id.Array => return @fieldParentPtr(Array, "base", base).getLlvmConst(ofile),
|
||||
.Type => unreachable,
|
||||
.Fn => return @fieldParentPtr(Fn, "base", base).getLlvmConst(ofile),
|
||||
.FnProto => return @fieldParentPtr(FnProto, "base", base).getLlvmConst(ofile),
|
||||
.Void => return null,
|
||||
.Bool => return @fieldParentPtr(Bool, "base", base).getLlvmConst(ofile),
|
||||
.NoReturn => unreachable,
|
||||
.Ptr => return @fieldParentPtr(Ptr, "base", base).getLlvmConst(ofile),
|
||||
.Int => return @fieldParentPtr(Int, "base", base).getLlvmConst(ofile),
|
||||
.Array => return @fieldParentPtr(Array, "base", base).getLlvmConst(ofile),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,15 +82,15 @@ pub const Value = struct {
|
|||
|
||||
pub fn copy(base: *Value, comp: *Compilation) (error{OutOfMemory}!*Value) {
|
||||
switch (base.id) {
|
||||
Id.Type => unreachable,
|
||||
Id.Fn => unreachable,
|
||||
Id.FnProto => unreachable,
|
||||
Id.Void => unreachable,
|
||||
Id.Bool => unreachable,
|
||||
Id.NoReturn => unreachable,
|
||||
Id.Ptr => unreachable,
|
||||
Id.Array => unreachable,
|
||||
Id.Int => return &(try @fieldParentPtr(Int, "base", base).copy(comp)).base,
|
||||
.Type => unreachable,
|
||||
.Fn => unreachable,
|
||||
.FnProto => unreachable,
|
||||
.Void => unreachable,
|
||||
.Bool => unreachable,
|
||||
.NoReturn => unreachable,
|
||||
.Ptr => unreachable,
|
||||
.Array => unreachable,
|
||||
.Int => return &(try @fieldParentPtr(Int, "base", base).copy(comp)).base,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,7 +137,7 @@ pub const Value = struct {
|
|||
const self = try comp.gpa().create(FnProto);
|
||||
self.* = FnProto{
|
||||
.base = Value{
|
||||
.id = Value.Id.FnProto,
|
||||
.id = .FnProto,
|
||||
.typ = &fn_type.base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
|
@ -202,7 +201,7 @@ pub const Value = struct {
|
|||
const self = try comp.gpa().create(Fn);
|
||||
self.* = Fn{
|
||||
.base = Value{
|
||||
.id = Value.Id.Fn,
|
||||
.id = .Fn,
|
||||
.typ = &fn_type.base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
|
@ -359,7 +358,7 @@ pub const Value = struct {
|
|||
const self = try comp.gpa().create(Value.Ptr);
|
||||
self.* = Value.Ptr{
|
||||
.base = Value{
|
||||
.id = Value.Id.Ptr,
|
||||
.id = .Ptr,
|
||||
.typ = &ptr_type.base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
|
@ -385,8 +384,8 @@ pub const Value = struct {
|
|||
const llvm_type = self.base.typ.getLlvmType(ofile.arena, ofile.context);
|
||||
// TODO carefully port the logic from codegen.cpp:gen_const_val_ptr
|
||||
switch (self.special) {
|
||||
Special.Scalar => |scalar| @panic("TODO"),
|
||||
Special.BaseArray => |base_array| {
|
||||
.Scalar => |scalar| @panic("TODO"),
|
||||
.BaseArray => |base_array| {
|
||||
// TODO put this in one .o file only, and after that, generate extern references to it
|
||||
const array_llvm_value = (try base_array.val.getLlvmConst(ofile)).?;
|
||||
const ptr_bit_count = ofile.comp.target_ptr_bits;
|
||||
|
@ -401,9 +400,9 @@ pub const Value = struct {
|
|||
@intCast(c_uint, indices.len),
|
||||
) orelse return error.OutOfMemory;
|
||||
},
|
||||
Special.BaseStruct => |base_struct| @panic("TODO"),
|
||||
Special.HardCodedAddr => |addr| @panic("TODO"),
|
||||
Special.Discard => unreachable,
|
||||
.BaseStruct => |base_struct| @panic("TODO"),
|
||||
.HardCodedAddr => |addr| @panic("TODO"),
|
||||
.Discard => unreachable,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -437,7 +436,7 @@ pub const Value = struct {
|
|||
const self = try comp.gpa().create(Value.Array);
|
||||
self.* = Value.Array{
|
||||
.base = Value{
|
||||
.id = Value.Id.Array,
|
||||
.id = .Array,
|
||||
.typ = &array_type.base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
|
@ -450,22 +449,22 @@ pub const Value = struct {
|
|||
|
||||
pub fn destroy(self: *Array, comp: *Compilation) void {
|
||||
switch (self.special) {
|
||||
Special.Undefined => {},
|
||||
Special.OwnedBuffer => |buf| {
|
||||
.Undefined => {},
|
||||
.OwnedBuffer => |buf| {
|
||||
comp.gpa().free(buf);
|
||||
},
|
||||
Special.Explicit => {},
|
||||
.Explicit => {},
|
||||
}
|
||||
comp.gpa().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmConst(self: *Array, ofile: *ObjectFile) !?*llvm.Value {
|
||||
switch (self.special) {
|
||||
Special.Undefined => {
|
||||
.Undefined => {
|
||||
const llvm_type = try self.base.typ.getLlvmType(ofile.arena, ofile.context);
|
||||
return llvm.GetUndef(llvm_type);
|
||||
},
|
||||
Special.OwnedBuffer => |buf| {
|
||||
.OwnedBuffer => |buf| {
|
||||
const dont_null_terminate = 1;
|
||||
const llvm_str_init = llvm.ConstStringInContext(
|
||||
ofile.context,
|
||||
|
@ -482,7 +481,7 @@ pub const Value = struct {
|
|||
llvm.SetAlignment(global, llvm.ABIAlignmentOfType(ofile.comp.target_data_ref, str_init_type));
|
||||
return global;
|
||||
},
|
||||
Special.Explicit => @panic("TODO"),
|
||||
.Explicit => @panic("TODO"),
|
||||
}
|
||||
|
||||
//{
|
||||
|
@ -517,7 +516,7 @@ pub const Value = struct {
|
|||
const self = try comp.gpa().create(Value.Int);
|
||||
self.* = Value.Int{
|
||||
.base = Value{
|
||||
.id = Value.Id.Int,
|
||||
.id = .Int,
|
||||
.typ = typ,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
|
@ -536,7 +535,7 @@ pub const Value = struct {
|
|||
|
||||
pub fn getLlvmConst(self: *Int, ofile: *ObjectFile) !?*llvm.Value {
|
||||
switch (self.base.typ.id) {
|
||||
Type.Id.Int => {
|
||||
.Int => {
|
||||
const type_ref = try self.base.typ.getLlvmType(ofile.arena, ofile.context);
|
||||
if (self.big_int.len() == 0) {
|
||||
return llvm.ConstNull(type_ref);
|
||||
|
@ -554,7 +553,7 @@ pub const Value = struct {
|
|||
};
|
||||
return if (self.big_int.isPositive()) unsigned_val else llvm.ConstNeg(unsigned_val);
|
||||
},
|
||||
Type.Id.ComptimeInt => unreachable,
|
||||
.ComptimeInt => unreachable,
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
@ -566,7 +565,7 @@ pub const Value = struct {
|
|||
const new = try comp.gpa().create(Value.Int);
|
||||
new.* = Value.Int{
|
||||
.base = Value{
|
||||
.id = Value.Id.Int,
|
||||
.id = .Int,
|
||||
.typ = old.base.typ,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue