self hosted compiler: use enum literals

master
Vexu 2019-11-07 08:31:00 +02:00
parent 7000316113
commit c6076a1360
No known key found for this signature in database
GPG Key ID: 5AEABFCAFF5CD8D6
17 changed files with 608 additions and 620 deletions

View File

@ -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"),

View File

@ -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()) {

View File

@ -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,
};
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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(

View File

@ -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 => {},
}
}

View File

@ -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;
}

View File

@ -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";

View File

@ -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);
}

View File

@ -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,
};

View File

@ -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)) {

View File

@ -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;

View File

@ -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 {

View File

@ -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),
},