mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
rename Module to Compilation
and CompilationUnit to ObjectFile
This commit is contained in:
parent
69e50ad2f5
commit
28c3d4809b
@ -1,7 +1,5 @@
|
||||
const std = @import("std");
|
||||
// TODO codegen pretends that Module is renamed to Build because I plan to
|
||||
// do that refactor at some point
|
||||
const Build = @import("module.zig").Module;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
// we go through llvm instead of c for 2 reasons:
|
||||
// 1. to avoid accidentally calling the non-thread-safe functions
|
||||
// 2. patch up some of the types to remove nullability
|
||||
@ -11,51 +9,51 @@ const Value = @import("value.zig").Value;
|
||||
const Type = @import("type.zig").Type;
|
||||
const event = std.event;
|
||||
|
||||
pub async fn renderToLlvm(build: *Build, fn_val: *Value.Fn, code: *ir.Code) !void {
|
||||
pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code) !void {
|
||||
fn_val.base.ref();
|
||||
defer fn_val.base.deref(build);
|
||||
defer code.destroy(build.a());
|
||||
defer fn_val.base.deref(comp);
|
||||
defer code.destroy(comp.a());
|
||||
|
||||
const llvm_handle = try build.event_loop_local.getAnyLlvmContext();
|
||||
defer llvm_handle.release(build.event_loop_local);
|
||||
const llvm_handle = try comp.event_loop_local.getAnyLlvmContext();
|
||||
defer llvm_handle.release(comp.event_loop_local);
|
||||
|
||||
const context = llvm_handle.node.data;
|
||||
|
||||
const module = llvm.ModuleCreateWithNameInContext(build.name.ptr(), context) orelse return error.OutOfMemory;
|
||||
const module = llvm.ModuleCreateWithNameInContext(comp.name.ptr(), context) orelse return error.OutOfMemory;
|
||||
defer llvm.DisposeModule(module);
|
||||
|
||||
const builder = llvm.CreateBuilderInContext(context) orelse return error.OutOfMemory;
|
||||
defer llvm.DisposeBuilder(builder);
|
||||
|
||||
var cunit = CompilationUnit{
|
||||
.build = build,
|
||||
var ofile = ObjectFile{
|
||||
.comp = comp,
|
||||
.module = module,
|
||||
.builder = builder,
|
||||
.context = context,
|
||||
.lock = event.Lock.init(build.loop),
|
||||
.lock = event.Lock.init(comp.loop),
|
||||
};
|
||||
|
||||
try renderToLlvmModule(&cunit, fn_val, code);
|
||||
try renderToLlvmModule(&ofile, fn_val, code);
|
||||
|
||||
if (build.verbose_llvm_ir) {
|
||||
llvm.DumpModule(cunit.module);
|
||||
if (comp.verbose_llvm_ir) {
|
||||
llvm.DumpModule(ofile.module);
|
||||
}
|
||||
}
|
||||
|
||||
pub const CompilationUnit = struct {
|
||||
build: *Build,
|
||||
pub const ObjectFile = struct {
|
||||
comp: *Compilation,
|
||||
module: llvm.ModuleRef,
|
||||
builder: llvm.BuilderRef,
|
||||
context: llvm.ContextRef,
|
||||
lock: event.Lock,
|
||||
|
||||
fn a(self: *CompilationUnit) *std.mem.Allocator {
|
||||
return self.build.a();
|
||||
fn a(self: *ObjectFile) *std.mem.Allocator {
|
||||
return self.comp.a();
|
||||
}
|
||||
};
|
||||
|
||||
pub fn renderToLlvmModule(cunit: *CompilationUnit, fn_val: *Value.Fn, code: *ir.Code) !void {
|
||||
pub fn renderToLlvmModule(ofile: *ObjectFile, fn_val: *Value.Fn, code: *ir.Code) !void {
|
||||
// TODO audit more of codegen.cpp:fn_llvm_value and port more logic
|
||||
const llvm_fn_type = try fn_val.base.typeof.getLlvmType(cunit);
|
||||
const llvm_fn = llvm.AddFunction(cunit.module, fn_val.symbol_name.ptr(), llvm_fn_type);
|
||||
const llvm_fn_type = try fn_val.base.typeof.getLlvmType(ofile);
|
||||
const llvm_fn = llvm.AddFunction(ofile.module, fn_val.symbol_name.ptr(), llvm_fn_type);
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ pub const LlvmHandle = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const Module = struct {
|
||||
pub const Compilation = struct {
|
||||
event_loop_local: *EventLoopLocal,
|
||||
loop: *event.Loop,
|
||||
name: Buffer,
|
||||
@ -239,7 +239,7 @@ pub const Module = struct {
|
||||
build_mode: builtin.Mode,
|
||||
zig_lib_dir: []const u8,
|
||||
cache_dir: []const u8,
|
||||
) !*Module {
|
||||
) !*Compilation {
|
||||
const loop = event_loop_local.loop;
|
||||
|
||||
var name_buffer = try Buffer.init(loop.allocator, name);
|
||||
@ -248,7 +248,7 @@ pub const Module = struct {
|
||||
const events = try event.Channel(Event).create(loop, 0);
|
||||
errdefer events.destroy();
|
||||
|
||||
const module = try loop.allocator.create(Module{
|
||||
const comp = try loop.allocator.create(Compilation{
|
||||
.loop = loop,
|
||||
.event_loop_local = event_loop_local,
|
||||
.events = events,
|
||||
@ -315,12 +315,12 @@ pub const Module = struct {
|
||||
.noreturn_type = undefined,
|
||||
.noreturn_value = undefined,
|
||||
});
|
||||
try module.initTypes();
|
||||
return module;
|
||||
try comp.initTypes();
|
||||
return comp;
|
||||
}
|
||||
|
||||
fn initTypes(module: *Module) !void {
|
||||
module.meta_type = try module.a().create(Type.MetaType{
|
||||
fn initTypes(comp: *Compilation) !void {
|
||||
comp.meta_type = try comp.a().create(Type.MetaType{
|
||||
.base = Type{
|
||||
.base = Value{
|
||||
.id = Value.Id.Type,
|
||||
@ -331,86 +331,86 @@ pub const Module = struct {
|
||||
},
|
||||
.value = undefined,
|
||||
});
|
||||
module.meta_type.value = &module.meta_type.base;
|
||||
module.meta_type.base.base.typeof = &module.meta_type.base;
|
||||
errdefer module.a().destroy(module.meta_type);
|
||||
comp.meta_type.value = &comp.meta_type.base;
|
||||
comp.meta_type.base.base.typeof = &comp.meta_type.base;
|
||||
errdefer comp.a().destroy(comp.meta_type);
|
||||
|
||||
module.void_type = try module.a().create(Type.Void{
|
||||
comp.void_type = try comp.a().create(Type.Void{
|
||||
.base = Type{
|
||||
.base = Value{
|
||||
.id = Value.Id.Type,
|
||||
.typeof = &Type.MetaType.get(module).base,
|
||||
.typeof = &Type.MetaType.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
.id = builtin.TypeId.Void,
|
||||
},
|
||||
});
|
||||
errdefer module.a().destroy(module.void_type);
|
||||
errdefer comp.a().destroy(comp.void_type);
|
||||
|
||||
module.noreturn_type = try module.a().create(Type.NoReturn{
|
||||
comp.noreturn_type = try comp.a().create(Type.NoReturn{
|
||||
.base = Type{
|
||||
.base = Value{
|
||||
.id = Value.Id.Type,
|
||||
.typeof = &Type.MetaType.get(module).base,
|
||||
.typeof = &Type.MetaType.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
.id = builtin.TypeId.NoReturn,
|
||||
},
|
||||
});
|
||||
errdefer module.a().destroy(module.noreturn_type);
|
||||
errdefer comp.a().destroy(comp.noreturn_type);
|
||||
|
||||
module.bool_type = try module.a().create(Type.Bool{
|
||||
comp.bool_type = try comp.a().create(Type.Bool{
|
||||
.base = Type{
|
||||
.base = Value{
|
||||
.id = Value.Id.Type,
|
||||
.typeof = &Type.MetaType.get(module).base,
|
||||
.typeof = &Type.MetaType.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
.id = builtin.TypeId.Bool,
|
||||
},
|
||||
});
|
||||
errdefer module.a().destroy(module.bool_type);
|
||||
errdefer comp.a().destroy(comp.bool_type);
|
||||
|
||||
module.void_value = try module.a().create(Value.Void{
|
||||
comp.void_value = try comp.a().create(Value.Void{
|
||||
.base = Value{
|
||||
.id = Value.Id.Void,
|
||||
.typeof = &Type.Void.get(module).base,
|
||||
.typeof = &Type.Void.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
});
|
||||
errdefer module.a().destroy(module.void_value);
|
||||
errdefer comp.a().destroy(comp.void_value);
|
||||
|
||||
module.true_value = try module.a().create(Value.Bool{
|
||||
comp.true_value = try comp.a().create(Value.Bool{
|
||||
.base = Value{
|
||||
.id = Value.Id.Bool,
|
||||
.typeof = &Type.Bool.get(module).base,
|
||||
.typeof = &Type.Bool.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
.x = true,
|
||||
});
|
||||
errdefer module.a().destroy(module.true_value);
|
||||
errdefer comp.a().destroy(comp.true_value);
|
||||
|
||||
module.false_value = try module.a().create(Value.Bool{
|
||||
comp.false_value = try comp.a().create(Value.Bool{
|
||||
.base = Value{
|
||||
.id = Value.Id.Bool,
|
||||
.typeof = &Type.Bool.get(module).base,
|
||||
.typeof = &Type.Bool.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
.x = false,
|
||||
});
|
||||
errdefer module.a().destroy(module.false_value);
|
||||
errdefer comp.a().destroy(comp.false_value);
|
||||
|
||||
module.noreturn_value = try module.a().create(Value.NoReturn{
|
||||
comp.noreturn_value = try comp.a().create(Value.NoReturn{
|
||||
.base = Value{
|
||||
.id = Value.Id.NoReturn,
|
||||
.typeof = &Type.NoReturn.get(module).base,
|
||||
.typeof = &Type.NoReturn.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
});
|
||||
errdefer module.a().destroy(module.noreturn_value);
|
||||
errdefer comp.a().destroy(comp.noreturn_value);
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Module) void {
|
||||
pub fn destroy(self: *Compilation) void {
|
||||
self.noreturn_value.base.deref(self);
|
||||
self.void_value.base.deref(self);
|
||||
self.false_value.base.deref(self);
|
||||
@ -425,7 +425,7 @@ pub const Module = struct {
|
||||
self.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn build(self: *Module) !void {
|
||||
pub fn build(self: *Compilation) !void {
|
||||
if (self.llvm_argv.len != 0) {
|
||||
var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.a(), [][]const []const u8{
|
||||
[][]const u8{"zig (LLVM option parsing)"},
|
||||
@ -439,7 +439,7 @@ pub const Module = struct {
|
||||
_ = try async<self.a()> self.buildAsync();
|
||||
}
|
||||
|
||||
async fn buildAsync(self: *Module) void {
|
||||
async fn buildAsync(self: *Compilation) void {
|
||||
while (true) {
|
||||
// TODO directly awaiting async should guarantee memory allocation elision
|
||||
// TODO also async before suspending should guarantee memory allocation elision
|
||||
@ -474,7 +474,7 @@ pub const Module = struct {
|
||||
}
|
||||
}
|
||||
|
||||
async fn addRootSrc(self: *Module) !void {
|
||||
async fn addRootSrc(self: *Compilation) !void {
|
||||
const root_src_path = self.root_src_path orelse @panic("TODO handle null root src path");
|
||||
// TODO async/await os.path.real
|
||||
const root_src_real_path = os.path.real(self.a(), root_src_path) catch |err| {
|
||||
@ -550,7 +550,7 @@ pub const Module = struct {
|
||||
try await (async self.build_group.wait() catch unreachable);
|
||||
}
|
||||
|
||||
async fn addTopLevelDecl(self: *Module, decl: *Decl) !void {
|
||||
async fn addTopLevelDecl(self: *Compilation, decl: *Decl) !void {
|
||||
const is_export = decl.isExported(&decl.parsed_file.tree);
|
||||
|
||||
if (is_export) {
|
||||
@ -559,7 +559,7 @@ pub const Module = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn addCompileError(self: *Module, parsed_file: *ParsedFile, span: Span, comptime fmt: []const u8, args: ...) !void {
|
||||
fn addCompileError(self: *Compilation, parsed_file: *ParsedFile, span: Span, comptime fmt: []const u8, args: ...) !void {
|
||||
const text = try std.fmt.allocPrint(self.loop.allocator, fmt, args);
|
||||
errdefer self.loop.allocator.free(text);
|
||||
|
||||
@ -567,7 +567,7 @@ pub const Module = struct {
|
||||
}
|
||||
|
||||
async fn addCompileErrorAsync(
|
||||
self: *Module,
|
||||
self: *Compilation,
|
||||
parsed_file: *ParsedFile,
|
||||
span: Span,
|
||||
text: []u8,
|
||||
@ -586,7 +586,7 @@ pub const Module = struct {
|
||||
try compile_errors.value.append(msg);
|
||||
}
|
||||
|
||||
async fn verifyUniqueSymbol(self: *Module, decl: *Decl) !void {
|
||||
async fn verifyUniqueSymbol(self: *Compilation, decl: *Decl) !void {
|
||||
const exported_symbol_names = await (async self.exported_symbol_names.acquire() catch unreachable);
|
||||
defer exported_symbol_names.release();
|
||||
|
||||
@ -601,12 +601,12 @@ pub const Module = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn link(self: *Module, out_file: ?[]const u8) !void {
|
||||
pub fn link(self: *Compilation, out_file: ?[]const u8) !void {
|
||||
warn("TODO link");
|
||||
return error.Todo;
|
||||
}
|
||||
|
||||
pub fn addLinkLib(self: *Module, name: []const u8, provided_explicitly: bool) !*LinkLib {
|
||||
pub fn addLinkLib(self: *Compilation, name: []const u8, provided_explicitly: bool) !*LinkLib {
|
||||
const is_libc = mem.eql(u8, name, "c");
|
||||
|
||||
if (is_libc) {
|
||||
@ -634,7 +634,7 @@ pub const Module = struct {
|
||||
return link_lib;
|
||||
}
|
||||
|
||||
fn a(self: Module) *mem.Allocator {
|
||||
fn a(self: Compilation) *mem.Allocator {
|
||||
return self.loop.allocator;
|
||||
}
|
||||
};
|
||||
@ -657,9 +657,9 @@ fn parseVisibToken(tree: *ast.Tree, optional_token_index: ?ast.TokenIndex) Visib
|
||||
}
|
||||
|
||||
/// This declaration has been blessed as going into the final code generation.
|
||||
pub async fn resolveDecl(module: *Module, decl: *Decl) !void {
|
||||
pub async fn resolveDecl(comp: *Compilation, decl: *Decl) !void {
|
||||
if (@atomicRmw(u8, &decl.resolution_in_progress, AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst) == 0) {
|
||||
decl.resolution.data = await (async generateDecl(module, decl) catch unreachable);
|
||||
decl.resolution.data = await (async generateDecl(comp, decl) catch unreachable);
|
||||
decl.resolution.resolve();
|
||||
return decl.resolution.data;
|
||||
} else {
|
||||
@ -668,42 +668,42 @@ pub async fn resolveDecl(module: *Module, decl: *Decl) !void {
|
||||
}
|
||||
|
||||
/// The function that actually does the generation.
|
||||
async fn generateDecl(module: *Module, decl: *Decl) !void {
|
||||
async fn generateDecl(comp: *Compilation, decl: *Decl) !void {
|
||||
switch (decl.id) {
|
||||
Decl.Id.Var => @panic("TODO"),
|
||||
Decl.Id.Fn => {
|
||||
const fn_decl = @fieldParentPtr(Decl.Fn, "base", decl);
|
||||
return await (async generateDeclFn(module, fn_decl) catch unreachable);
|
||||
return await (async generateDeclFn(comp, fn_decl) catch unreachable);
|
||||
},
|
||||
Decl.Id.CompTime => @panic("TODO"),
|
||||
}
|
||||
}
|
||||
|
||||
async fn generateDeclFn(module: *Module, fn_decl: *Decl.Fn) !void {
|
||||
async fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void {
|
||||
const body_node = fn_decl.fn_proto.body_node orelse @panic("TODO extern fn proto decl");
|
||||
|
||||
const fndef_scope = try Scope.FnDef.create(module, fn_decl.base.parent_scope);
|
||||
defer fndef_scope.base.deref(module);
|
||||
const fndef_scope = try Scope.FnDef.create(comp, fn_decl.base.parent_scope);
|
||||
defer fndef_scope.base.deref(comp);
|
||||
|
||||
// TODO actually look at the return type of the AST
|
||||
const return_type = &Type.Void.get(module).base;
|
||||
defer return_type.base.deref(module);
|
||||
const return_type = &Type.Void.get(comp).base;
|
||||
defer return_type.base.deref(comp);
|
||||
|
||||
const is_var_args = false;
|
||||
const params = ([*]Type.Fn.Param)(undefined)[0..0];
|
||||
const fn_type = try Type.Fn.create(module, return_type, params, is_var_args);
|
||||
defer fn_type.base.base.deref(module);
|
||||
const fn_type = try Type.Fn.create(comp, return_type, params, is_var_args);
|
||||
defer fn_type.base.base.deref(comp);
|
||||
|
||||
var symbol_name = try std.Buffer.init(module.a(), fn_decl.base.name);
|
||||
var symbol_name = try std.Buffer.init(comp.a(), fn_decl.base.name);
|
||||
errdefer symbol_name.deinit();
|
||||
|
||||
const fn_val = try Value.Fn.create(module, fn_type, fndef_scope, symbol_name);
|
||||
defer fn_val.base.deref(module);
|
||||
const fn_val = try Value.Fn.create(comp, fn_type, fndef_scope, symbol_name);
|
||||
defer fn_val.base.deref(comp);
|
||||
|
||||
fn_decl.value = Decl.Fn.Val{ .Ok = fn_val };
|
||||
|
||||
const unanalyzed_code = (await (async ir.gen(
|
||||
module,
|
||||
comp,
|
||||
body_node,
|
||||
&fndef_scope.base,
|
||||
Span.token(body_node.lastToken()),
|
||||
@ -715,15 +715,15 @@ async fn generateDeclFn(module: *Module, fn_decl: *Decl.Fn) !void {
|
||||
error.SemanticAnalysisFailed => return {},
|
||||
else => return err,
|
||||
};
|
||||
defer unanalyzed_code.destroy(module.a());
|
||||
defer unanalyzed_code.destroy(comp.a());
|
||||
|
||||
if (module.verbose_ir) {
|
||||
if (comp.verbose_ir) {
|
||||
std.debug.warn("unanalyzed:\n");
|
||||
unanalyzed_code.dump();
|
||||
}
|
||||
|
||||
const analyzed_code = (await (async ir.analyze(
|
||||
module,
|
||||
comp,
|
||||
fn_decl.base.parsed_file,
|
||||
unanalyzed_code,
|
||||
null,
|
||||
@ -734,14 +734,14 @@ async fn generateDeclFn(module: *Module, fn_decl: *Decl.Fn) !void {
|
||||
error.SemanticAnalysisFailed => return {},
|
||||
else => return err,
|
||||
};
|
||||
errdefer analyzed_code.destroy(module.a());
|
||||
errdefer analyzed_code.destroy(comp.a());
|
||||
|
||||
if (module.verbose_ir) {
|
||||
if (comp.verbose_ir) {
|
||||
std.debug.warn("analyzed:\n");
|
||||
analyzed_code.dump();
|
||||
}
|
||||
|
||||
// Kick off rendering to LLVM module, but it doesn't block the fn decl
|
||||
// Kick off rendering to LLVM comp, but it doesn't block the fn decl
|
||||
// analysis from being complete.
|
||||
try module.build_group.call(codegen.renderToLlvm, module, fn_val, analyzed_code);
|
||||
try comp.build_group.call(codegen.renderToLlvm, comp, fn_val, analyzed_code);
|
||||
}
|
||||
@ -9,13 +9,13 @@ const Value = @import("value.zig").Value;
|
||||
const Token = std.zig.Token;
|
||||
const errmsg = @import("errmsg.zig");
|
||||
const Scope = @import("scope.zig").Scope;
|
||||
const Module = @import("module.zig").Module;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
|
||||
pub const Decl = struct {
|
||||
id: Id,
|
||||
name: []const u8,
|
||||
visib: Visib,
|
||||
resolution: event.Future(Module.BuildError!void),
|
||||
resolution: event.Future(Compilation.BuildError!void),
|
||||
resolution_in_progress: u8,
|
||||
parsed_file: *ParsedFile,
|
||||
parent_scope: *Scope,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const Module = @import("module.zig").Module;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
const Scope = @import("scope.zig").Scope;
|
||||
const ast = std.zig.ast;
|
||||
const Allocator = std.mem.Allocator;
|
||||
@ -243,7 +243,7 @@ pub const Instruction = struct {
|
||||
Value.Ptr.Mut.CompTimeConst,
|
||||
self.params.mut,
|
||||
self.params.volatility,
|
||||
val.typeof.getAbiAlignment(ira.irb.module),
|
||||
val.typeof.getAbiAlignment(ira.irb.comp),
|
||||
);
|
||||
}
|
||||
|
||||
@ -254,12 +254,12 @@ pub const Instruction = struct {
|
||||
});
|
||||
const elem_type = target.getKnownType();
|
||||
const ptr_type = Type.Pointer.get(
|
||||
ira.irb.module,
|
||||
ira.irb.comp,
|
||||
elem_type,
|
||||
self.params.mut,
|
||||
self.params.volatility,
|
||||
Type.Pointer.Size.One,
|
||||
elem_type.getAbiAlignment(ira.irb.module),
|
||||
elem_type.getAbiAlignment(ira.irb.comp),
|
||||
);
|
||||
// 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
|
||||
@ -417,7 +417,7 @@ pub const Code = struct {
|
||||
arena: std.heap.ArenaAllocator,
|
||||
return_type: ?*Type,
|
||||
|
||||
/// allocator is module.a()
|
||||
/// allocator is comp.a()
|
||||
pub fn destroy(self: *Code, allocator: *Allocator) void {
|
||||
self.arena.deinit();
|
||||
allocator.destroy(self);
|
||||
@ -437,7 +437,7 @@ pub const Code = struct {
|
||||
};
|
||||
|
||||
pub const Builder = struct {
|
||||
module: *Module,
|
||||
comp: *Compilation,
|
||||
code: *Code,
|
||||
current_basic_block: *BasicBlock,
|
||||
next_debug_id: usize,
|
||||
@ -446,17 +446,17 @@ pub const Builder = struct {
|
||||
|
||||
pub const Error = Analyze.Error;
|
||||
|
||||
pub fn init(module: *Module, parsed_file: *ParsedFile) !Builder {
|
||||
const code = try module.a().create(Code{
|
||||
pub fn init(comp: *Compilation, parsed_file: *ParsedFile) !Builder {
|
||||
const code = try comp.a().create(Code{
|
||||
.basic_block_list = undefined,
|
||||
.arena = std.heap.ArenaAllocator.init(module.a()),
|
||||
.arena = std.heap.ArenaAllocator.init(comp.a()),
|
||||
.return_type = null,
|
||||
});
|
||||
code.basic_block_list = std.ArrayList(*BasicBlock).init(&code.arena.allocator);
|
||||
errdefer code.destroy(module.a());
|
||||
errdefer code.destroy(comp.a());
|
||||
|
||||
return Builder{
|
||||
.module = module,
|
||||
.comp = comp,
|
||||
.parsed_file = parsed_file,
|
||||
.current_basic_block = undefined,
|
||||
.code = code,
|
||||
@ -466,7 +466,7 @@ pub const Builder = struct {
|
||||
}
|
||||
|
||||
pub fn abort(self: *Builder) void {
|
||||
self.code.destroy(self.module.a());
|
||||
self.code.destroy(self.comp.a());
|
||||
}
|
||||
|
||||
/// Call code.destroy() when done
|
||||
@ -581,7 +581,7 @@ pub const Builder = struct {
|
||||
}
|
||||
|
||||
pub fn genBlock(irb: *Builder, block: *ast.Node.Block, parent_scope: *Scope) !*Instruction {
|
||||
const block_scope = try Scope.Block.create(irb.module, parent_scope);
|
||||
const block_scope = try Scope.Block.create(irb.comp, parent_scope);
|
||||
|
||||
const outer_block_scope = &block_scope.base;
|
||||
var child_scope = outer_block_scope;
|
||||
@ -623,8 +623,8 @@ pub const Builder = struct {
|
||||
Token.Id.Keyword_errdefer => Scope.Defer.Kind.ErrorExit,
|
||||
else => unreachable,
|
||||
};
|
||||
const defer_expr_scope = try Scope.DeferExpr.create(irb.module, parent_scope, defer_node.expr);
|
||||
const defer_child_scope = try Scope.Defer.create(irb.module, parent_scope, kind, defer_expr_scope);
|
||||
const defer_expr_scope = try Scope.DeferExpr.create(irb.comp, parent_scope, defer_node.expr);
|
||||
const defer_child_scope = try Scope.Defer.create(irb.comp, parent_scope, kind, defer_expr_scope);
|
||||
child_scope = &defer_child_scope.base;
|
||||
continue;
|
||||
}
|
||||
@ -770,8 +770,8 @@ pub const Builder = struct {
|
||||
.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.module).base },
|
||||
IrVal.Init.Void => IrVal{ .KnownValue = &Value.Void.get(self.module).base },
|
||||
IrVal.Init.NoReturn => IrVal{ .KnownValue = &Value.NoReturn.get(self.comp).base },
|
||||
IrVal.Init.Void => IrVal{ .KnownValue = &Value.Void.get(self.comp).base },
|
||||
},
|
||||
.ref_count = 0,
|
||||
.span = span,
|
||||
@ -819,13 +819,13 @@ pub const Builder = struct {
|
||||
|
||||
fn buildConstBool(self: *Builder, scope: *Scope, span: Span, x: bool) !*Instruction {
|
||||
const inst = try self.build(Instruction.Const, scope, span, Instruction.Const.Params{});
|
||||
inst.val = IrVal{ .KnownValue = &Value.Bool.get(self.module, x).base };
|
||||
inst.val = IrVal{ .KnownValue = &Value.Bool.get(self.comp, x).base };
|
||||
return inst;
|
||||
}
|
||||
|
||||
fn buildConstVoid(self: *Builder, scope: *Scope, span: Span, is_generated: bool) !*Instruction {
|
||||
const inst = try self.buildExtra(Instruction.Const, scope, span, Instruction.Const.Params{}, is_generated);
|
||||
inst.val = IrVal{ .KnownValue = &Value.Void.get(self.module).base };
|
||||
inst.val = IrVal{ .KnownValue = &Value.Void.get(self.comp).base };
|
||||
return inst;
|
||||
}
|
||||
};
|
||||
@ -850,8 +850,8 @@ const Analyze = struct {
|
||||
OutOfMemory,
|
||||
};
|
||||
|
||||
pub fn init(module: *Module, parsed_file: *ParsedFile, explicit_return_type: ?*Type) !Analyze {
|
||||
var irb = try Builder.init(module, parsed_file);
|
||||
pub fn init(comp: *Compilation, parsed_file: *ParsedFile, explicit_return_type: ?*Type) !Analyze {
|
||||
var irb = try Builder.init(comp, parsed_file);
|
||||
errdefer irb.abort();
|
||||
|
||||
return Analyze{
|
||||
@ -929,12 +929,12 @@ const Analyze = struct {
|
||||
}
|
||||
|
||||
fn addCompileError(self: *Analyze, span: Span, comptime fmt: []const u8, args: ...) !void {
|
||||
return self.irb.module.addCompileError(self.irb.parsed_file, span, fmt, args);
|
||||
return self.irb.comp.addCompileError(self.irb.parsed_file, span, fmt, args);
|
||||
}
|
||||
|
||||
fn resolvePeerTypes(self: *Analyze, expected_type: ?*Type, peers: []const *Instruction) Analyze.Error!*Type {
|
||||
// TODO actual implementation
|
||||
return &Type.Void.get(self.irb.module).base;
|
||||
return &Type.Void.get(self.irb.comp).base;
|
||||
}
|
||||
|
||||
fn implicitCast(self: *Analyze, target: *Instruction, optional_dest_type: ?*Type) Analyze.Error!*Instruction {
|
||||
@ -959,13 +959,13 @@ const Analyze = struct {
|
||||
};
|
||||
|
||||
pub async fn gen(
|
||||
module: *Module,
|
||||
comp: *Compilation,
|
||||
body_node: *ast.Node,
|
||||
scope: *Scope,
|
||||
end_span: Span,
|
||||
parsed_file: *ParsedFile,
|
||||
) !*Code {
|
||||
var irb = try Builder.init(module, parsed_file);
|
||||
var irb = try Builder.init(comp, parsed_file);
|
||||
errdefer irb.abort();
|
||||
|
||||
const entry_block = try irb.createBasicBlock(scope, "Entry");
|
||||
@ -991,8 +991,8 @@ pub async fn gen(
|
||||
return irb.finish();
|
||||
}
|
||||
|
||||
pub async fn analyze(module: *Module, parsed_file: *ParsedFile, old_code: *Code, expected_type: ?*Type) !*Code {
|
||||
var ira = try Analyze.init(module, parsed_file, expected_type);
|
||||
pub async fn analyze(comp: *Compilation, parsed_file: *ParsedFile, old_code: *Code, expected_type: ?*Type) !*Code {
|
||||
var ira = try Analyze.init(comp, parsed_file, expected_type);
|
||||
errdefer ira.abort();
|
||||
|
||||
const old_entry_bb = old_code.basic_block_list.at(0);
|
||||
@ -1025,7 +1025,7 @@ pub async fn analyze(module: *Module, parsed_file: *ParsedFile, old_code: *Code,
|
||||
}
|
||||
|
||||
if (ira.src_implicit_return_type_list.len == 0) {
|
||||
ira.irb.code.return_type = &Type.NoReturn.get(module).base;
|
||||
ira.irb.code.return_type = &Type.NoReturn.get(comp).base;
|
||||
return ira.irb.finish();
|
||||
}
|
||||
|
||||
|
||||
@ -14,8 +14,8 @@ const c = @import("c.zig");
|
||||
const introspect = @import("introspect.zig");
|
||||
const Args = arg.Args;
|
||||
const Flag = arg.Flag;
|
||||
const EventLoopLocal = @import("module.zig").EventLoopLocal;
|
||||
const Module = @import("module.zig").Module;
|
||||
const EventLoopLocal = @import("compilation.zig").EventLoopLocal;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
const Target = @import("target.zig").Target;
|
||||
const errmsg = @import("errmsg.zig");
|
||||
|
||||
@ -258,7 +258,7 @@ const args_build_generic = []Flag{
|
||||
Flag.Arg1("--ver-patch"),
|
||||
};
|
||||
|
||||
fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Module.Kind) !void {
|
||||
fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Compilation.Kind) !void {
|
||||
var flags = try Args.parse(allocator, args_build_generic, args);
|
||||
defer flags.deinit();
|
||||
|
||||
@ -300,14 +300,14 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
|
||||
const emit_type = blk: {
|
||||
if (flags.single("emit")) |emit_flag| {
|
||||
if (mem.eql(u8, emit_flag, "asm")) {
|
||||
break :blk Module.Emit.Assembly;
|
||||
break :blk Compilation.Emit.Assembly;
|
||||
} else if (mem.eql(u8, emit_flag, "bin")) {
|
||||
break :blk Module.Emit.Binary;
|
||||
break :blk Compilation.Emit.Binary;
|
||||
} else if (mem.eql(u8, emit_flag, "llvm-ir")) {
|
||||
break :blk Module.Emit.LlvmIr;
|
||||
break :blk Compilation.Emit.LlvmIr;
|
||||
} else unreachable;
|
||||
} else {
|
||||
break :blk Module.Emit.Binary;
|
||||
break :blk Compilation.Emit.Binary;
|
||||
}
|
||||
};
|
||||
|
||||
@ -370,7 +370,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
|
||||
os.exit(1);
|
||||
}
|
||||
|
||||
if (out_type == Module.Kind.Obj and link_objects.len != 0) {
|
||||
if (out_type == Compilation.Kind.Obj and link_objects.len != 0) {
|
||||
try stderr.write("When building an object file, --object arguments are invalid\n");
|
||||
os.exit(1);
|
||||
}
|
||||
@ -392,7 +392,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
|
||||
var event_loop_local = EventLoopLocal.init(&loop);
|
||||
defer event_loop_local.deinit();
|
||||
|
||||
var module = try Module.create(
|
||||
var comp = try Compilation.create(
|
||||
&event_loop_local,
|
||||
root_name,
|
||||
root_source_file,
|
||||
@ -402,16 +402,16 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
|
||||
zig_lib_dir,
|
||||
full_cache_dir,
|
||||
);
|
||||
defer module.destroy();
|
||||
defer comp.destroy();
|
||||
|
||||
module.version_major = try std.fmt.parseUnsigned(u32, flags.single("ver-major") orelse "0", 10);
|
||||
module.version_minor = try std.fmt.parseUnsigned(u32, flags.single("ver-minor") orelse "0", 10);
|
||||
module.version_patch = try std.fmt.parseUnsigned(u32, flags.single("ver-patch") orelse "0", 10);
|
||||
comp.version_major = try std.fmt.parseUnsigned(u32, flags.single("ver-major") orelse "0", 10);
|
||||
comp.version_minor = try std.fmt.parseUnsigned(u32, flags.single("ver-minor") orelse "0", 10);
|
||||
comp.version_patch = try std.fmt.parseUnsigned(u32, flags.single("ver-patch") orelse "0", 10);
|
||||
|
||||
module.is_test = false;
|
||||
comp.is_test = false;
|
||||
|
||||
module.linker_script = flags.single("linker-script");
|
||||
module.each_lib_rpath = flags.present("each-lib-rpath");
|
||||
comp.linker_script = flags.single("linker-script");
|
||||
comp.each_lib_rpath = flags.present("each-lib-rpath");
|
||||
|
||||
var clang_argv_buf = ArrayList([]const u8).init(allocator);
|
||||
defer clang_argv_buf.deinit();
|
||||
@ -422,51 +422,51 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
|
||||
try clang_argv_buf.append(mllvm);
|
||||
}
|
||||
|
||||
module.llvm_argv = mllvm_flags;
|
||||
module.clang_argv = clang_argv_buf.toSliceConst();
|
||||
comp.llvm_argv = mllvm_flags;
|
||||
comp.clang_argv = clang_argv_buf.toSliceConst();
|
||||
|
||||
module.strip = flags.present("strip");
|
||||
module.is_static = flags.present("static");
|
||||
comp.strip = flags.present("strip");
|
||||
comp.is_static = flags.present("static");
|
||||
|
||||
if (flags.single("libc-lib-dir")) |libc_lib_dir| {
|
||||
module.libc_lib_dir = libc_lib_dir;
|
||||
comp.libc_lib_dir = libc_lib_dir;
|
||||
}
|
||||
if (flags.single("libc-static-lib-dir")) |libc_static_lib_dir| {
|
||||
module.libc_static_lib_dir = libc_static_lib_dir;
|
||||
comp.libc_static_lib_dir = libc_static_lib_dir;
|
||||
}
|
||||
if (flags.single("libc-include-dir")) |libc_include_dir| {
|
||||
module.libc_include_dir = libc_include_dir;
|
||||
comp.libc_include_dir = libc_include_dir;
|
||||
}
|
||||
if (flags.single("msvc-lib-dir")) |msvc_lib_dir| {
|
||||
module.msvc_lib_dir = msvc_lib_dir;
|
||||
comp.msvc_lib_dir = msvc_lib_dir;
|
||||
}
|
||||
if (flags.single("kernel32-lib-dir")) |kernel32_lib_dir| {
|
||||
module.kernel32_lib_dir = kernel32_lib_dir;
|
||||
comp.kernel32_lib_dir = kernel32_lib_dir;
|
||||
}
|
||||
if (flags.single("dynamic-linker")) |dynamic_linker| {
|
||||
module.dynamic_linker = dynamic_linker;
|
||||
comp.dynamic_linker = dynamic_linker;
|
||||
}
|
||||
|
||||
module.verbose_tokenize = flags.present("verbose-tokenize");
|
||||
module.verbose_ast_tree = flags.present("verbose-ast-tree");
|
||||
module.verbose_ast_fmt = flags.present("verbose-ast-fmt");
|
||||
module.verbose_link = flags.present("verbose-link");
|
||||
module.verbose_ir = flags.present("verbose-ir");
|
||||
module.verbose_llvm_ir = flags.present("verbose-llvm-ir");
|
||||
module.verbose_cimport = flags.present("verbose-cimport");
|
||||
comp.verbose_tokenize = flags.present("verbose-tokenize");
|
||||
comp.verbose_ast_tree = flags.present("verbose-ast-tree");
|
||||
comp.verbose_ast_fmt = flags.present("verbose-ast-fmt");
|
||||
comp.verbose_link = flags.present("verbose-link");
|
||||
comp.verbose_ir = flags.present("verbose-ir");
|
||||
comp.verbose_llvm_ir = flags.present("verbose-llvm-ir");
|
||||
comp.verbose_cimport = flags.present("verbose-cimport");
|
||||
|
||||
module.err_color = color;
|
||||
module.lib_dirs = flags.many("library-path");
|
||||
module.darwin_frameworks = flags.many("framework");
|
||||
module.rpath_list = flags.many("rpath");
|
||||
comp.err_color = color;
|
||||
comp.lib_dirs = flags.many("library-path");
|
||||
comp.darwin_frameworks = flags.many("framework");
|
||||
comp.rpath_list = flags.many("rpath");
|
||||
|
||||
if (flags.single("output-h")) |output_h| {
|
||||
module.out_h_path = output_h;
|
||||
comp.out_h_path = output_h;
|
||||
}
|
||||
|
||||
module.windows_subsystem_windows = flags.present("mwindows");
|
||||
module.windows_subsystem_console = flags.present("mconsole");
|
||||
module.linker_rdynamic = flags.present("rdynamic");
|
||||
comp.windows_subsystem_windows = flags.present("mwindows");
|
||||
comp.windows_subsystem_console = flags.present("mconsole");
|
||||
comp.linker_rdynamic = flags.present("rdynamic");
|
||||
|
||||
if (flags.single("mmacosx-version-min") != null and flags.single("mios-version-min") != null) {
|
||||
try stderr.write("-mmacosx-version-min and -mios-version-min options not allowed together\n");
|
||||
@ -474,37 +474,37 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo
|
||||
}
|
||||
|
||||
if (flags.single("mmacosx-version-min")) |ver| {
|
||||
module.darwin_version_min = Module.DarwinVersionMin{ .MacOS = ver };
|
||||
comp.darwin_version_min = Compilation.DarwinVersionMin{ .MacOS = ver };
|
||||
}
|
||||
if (flags.single("mios-version-min")) |ver| {
|
||||
module.darwin_version_min = Module.DarwinVersionMin{ .Ios = ver };
|
||||
comp.darwin_version_min = Compilation.DarwinVersionMin{ .Ios = ver };
|
||||
}
|
||||
|
||||
module.emit_file_type = emit_type;
|
||||
module.link_objects = link_objects;
|
||||
module.assembly_files = assembly_files;
|
||||
module.link_out_file = flags.single("out-file");
|
||||
comp.emit_file_type = emit_type;
|
||||
comp.link_objects = link_objects;
|
||||
comp.assembly_files = assembly_files;
|
||||
comp.link_out_file = flags.single("out-file");
|
||||
|
||||
try module.build();
|
||||
const process_build_events_handle = try async<loop.allocator> processBuildEvents(module, color);
|
||||
try comp.build();
|
||||
const process_build_events_handle = try async<loop.allocator> processBuildEvents(comp, color);
|
||||
defer cancel process_build_events_handle;
|
||||
loop.run();
|
||||
}
|
||||
|
||||
async fn processBuildEvents(module: *Module, color: errmsg.Color) void {
|
||||
async fn processBuildEvents(comp: *Compilation, color: errmsg.Color) void {
|
||||
// TODO directly awaiting async should guarantee memory allocation elision
|
||||
const build_event = await (async module.events.get() catch unreachable);
|
||||
const build_event = await (async comp.events.get() catch unreachable);
|
||||
|
||||
switch (build_event) {
|
||||
Module.Event.Ok => {
|
||||
Compilation.Event.Ok => {
|
||||
std.debug.warn("Build succeeded\n");
|
||||
return;
|
||||
},
|
||||
Module.Event.Error => |err| {
|
||||
Compilation.Event.Error => |err| {
|
||||
std.debug.warn("build failed: {}\n", @errorName(err));
|
||||
os.exit(1);
|
||||
},
|
||||
Module.Event.Fail => |msgs| {
|
||||
Compilation.Event.Fail => |msgs| {
|
||||
for (msgs) |msg| {
|
||||
errmsg.printToFile(&stderr_file, msg, color) catch os.exit(1);
|
||||
}
|
||||
@ -513,15 +513,15 @@ async fn processBuildEvents(module: *Module, color: errmsg.Color) void {
|
||||
}
|
||||
|
||||
fn cmdBuildExe(allocator: *Allocator, args: []const []const u8) !void {
|
||||
return buildOutputType(allocator, args, Module.Kind.Exe);
|
||||
return buildOutputType(allocator, args, Compilation.Kind.Exe);
|
||||
}
|
||||
|
||||
fn cmdBuildLib(allocator: *Allocator, args: []const []const u8) !void {
|
||||
return buildOutputType(allocator, args, Module.Kind.Lib);
|
||||
return buildOutputType(allocator, args, Compilation.Kind.Lib);
|
||||
}
|
||||
|
||||
fn cmdBuildObj(allocator: *Allocator, args: []const []const u8) !void {
|
||||
return buildOutputType(allocator, args, Module.Kind.Obj);
|
||||
return buildOutputType(allocator, args, Compilation.Kind.Obj);
|
||||
}
|
||||
|
||||
const usage_fmt =
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
const std = @import("std");
|
||||
const Allocator = mem.Allocator;
|
||||
const Decl = @import("decl.zig").Decl;
|
||||
const Module = @import("module.zig").Module;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
const mem = std.mem;
|
||||
const ast = std.zig.ast;
|
||||
const Value = @import("value.zig").Value;
|
||||
@ -16,17 +16,17 @@ pub const Scope = struct {
|
||||
base.ref_count += 1;
|
||||
}
|
||||
|
||||
pub fn deref(base: *Scope, module: *Module) void {
|
||||
pub fn deref(base: *Scope, comp: *Compilation) void {
|
||||
base.ref_count -= 1;
|
||||
if (base.ref_count == 0) {
|
||||
if (base.parent) |parent| parent.deref(module);
|
||||
if (base.parent) |parent| parent.deref(comp);
|
||||
switch (base.id) {
|
||||
Id.Decls => @fieldParentPtr(Decls, "base", base).destroy(),
|
||||
Id.Block => @fieldParentPtr(Block, "base", base).destroy(module),
|
||||
Id.FnDef => @fieldParentPtr(FnDef, "base", base).destroy(module),
|
||||
Id.CompTime => @fieldParentPtr(CompTime, "base", base).destroy(module),
|
||||
Id.Defer => @fieldParentPtr(Defer, "base", base).destroy(module),
|
||||
Id.DeferExpr => @fieldParentPtr(DeferExpr, "base", base).destroy(module),
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -61,8 +61,8 @@ pub const Scope = struct {
|
||||
table: Decl.Table,
|
||||
|
||||
/// Creates a Decls scope with 1 reference
|
||||
pub fn create(module: *Module, parent: ?*Scope) !*Decls {
|
||||
const self = try module.a().create(Decls{
|
||||
pub fn create(comp: *Compilation, parent: ?*Scope) !*Decls {
|
||||
const self = try comp.a().create(Decls{
|
||||
.base = Scope{
|
||||
.id = Id.Decls,
|
||||
.parent = parent,
|
||||
@ -70,9 +70,9 @@ pub const Scope = struct {
|
||||
},
|
||||
.table = undefined,
|
||||
});
|
||||
errdefer module.a().destroy(self);
|
||||
errdefer comp.a().destroy(self);
|
||||
|
||||
self.table = Decl.Table.init(module.a());
|
||||
self.table = Decl.Table.init(comp.a());
|
||||
errdefer self.table.deinit();
|
||||
|
||||
if (parent) |p| p.ref();
|
||||
@ -94,8 +94,8 @@ pub const Scope = struct {
|
||||
is_comptime: *ir.Instruction,
|
||||
|
||||
/// Creates a Block scope with 1 reference
|
||||
pub fn create(module: *Module, parent: ?*Scope) !*Block {
|
||||
const self = try module.a().create(Block{
|
||||
pub fn create(comp: *Compilation, parent: ?*Scope) !*Block {
|
||||
const self = try comp.a().create(Block{
|
||||
.base = Scope{
|
||||
.id = Id.Block,
|
||||
.parent = parent,
|
||||
@ -106,14 +106,14 @@ pub const Scope = struct {
|
||||
.end_block = undefined,
|
||||
.is_comptime = undefined,
|
||||
});
|
||||
errdefer module.a().destroy(self);
|
||||
errdefer comp.a().destroy(self);
|
||||
|
||||
if (parent) |p| p.ref();
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Block, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Block, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
@ -125,8 +125,8 @@ pub const Scope = struct {
|
||||
|
||||
/// Creates a FnDef scope with 1 reference
|
||||
/// Must set the fn_val later
|
||||
pub fn create(module: *Module, parent: ?*Scope) !*FnDef {
|
||||
const self = try module.a().create(FnDef{
|
||||
pub fn create(comp: *Compilation, parent: ?*Scope) !*FnDef {
|
||||
const self = try comp.a().create(FnDef{
|
||||
.base = Scope{
|
||||
.id = Id.FnDef,
|
||||
.parent = parent,
|
||||
@ -140,8 +140,8 @@ pub const Scope = struct {
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *FnDef, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *FnDef, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
@ -149,8 +149,8 @@ pub const Scope = struct {
|
||||
base: Scope,
|
||||
|
||||
/// Creates a CompTime scope with 1 reference
|
||||
pub fn create(module: *Module, parent: ?*Scope) !*CompTime {
|
||||
const self = try module.a().create(CompTime{
|
||||
pub fn create(comp: *Compilation, parent: ?*Scope) !*CompTime {
|
||||
const self = try comp.a().create(CompTime{
|
||||
.base = Scope{
|
||||
.id = Id.CompTime,
|
||||
.parent = parent,
|
||||
@ -162,8 +162,8 @@ pub const Scope = struct {
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *CompTime, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *CompTime, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
@ -179,12 +179,12 @@ pub const Scope = struct {
|
||||
|
||||
/// Creates a Defer scope with 1 reference
|
||||
pub fn create(
|
||||
module: *Module,
|
||||
comp: *Compilation,
|
||||
parent: ?*Scope,
|
||||
kind: Kind,
|
||||
defer_expr_scope: *DeferExpr,
|
||||
) !*Defer {
|
||||
const self = try module.a().create(Defer{
|
||||
const self = try comp.a().create(Defer{
|
||||
.base = Scope{
|
||||
.id = Id.Defer,
|
||||
.parent = parent,
|
||||
@ -193,7 +193,7 @@ pub const Scope = struct {
|
||||
.defer_expr_scope = defer_expr_scope,
|
||||
.kind = kind,
|
||||
});
|
||||
errdefer module.a().destroy(self);
|
||||
errdefer comp.a().destroy(self);
|
||||
|
||||
defer_expr_scope.base.ref();
|
||||
|
||||
@ -201,9 +201,9 @@ pub const Scope = struct {
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Defer, module: *Module) void {
|
||||
self.defer_expr_scope.base.deref(module);
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Defer, comp: *Compilation) void {
|
||||
self.defer_expr_scope.base.deref(comp);
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
@ -212,8 +212,8 @@ pub const Scope = struct {
|
||||
expr_node: *ast.Node,
|
||||
|
||||
/// Creates a DeferExpr scope with 1 reference
|
||||
pub fn create(module: *Module, parent: ?*Scope, expr_node: *ast.Node) !*DeferExpr {
|
||||
const self = try module.a().create(DeferExpr{
|
||||
pub fn create(comp: *Compilation, parent: ?*Scope, expr_node: *ast.Node) !*DeferExpr {
|
||||
const self = try comp.a().create(DeferExpr{
|
||||
.base = Scope{
|
||||
.id = Id.DeferExpr,
|
||||
.parent = parent,
|
||||
@ -221,14 +221,14 @@ pub const Scope = struct {
|
||||
},
|
||||
.expr_node = expr_node,
|
||||
});
|
||||
errdefer module.a().destroy(self);
|
||||
errdefer comp.a().destroy(self);
|
||||
|
||||
if (parent) |p| p.ref();
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *DeferExpr, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *DeferExpr, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,11 +2,11 @@ const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const builtin = @import("builtin");
|
||||
const Target = @import("target.zig").Target;
|
||||
const Module = @import("module.zig").Module;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
const introspect = @import("introspect.zig");
|
||||
const assertOrPanic = std.debug.assertOrPanic;
|
||||
const errmsg = @import("errmsg.zig");
|
||||
const EventLoopLocal = @import("module.zig").EventLoopLocal;
|
||||
const EventLoopLocal = @import("compilation.zig").EventLoopLocal;
|
||||
|
||||
test "compile errors" {
|
||||
var ctx: TestContext = undefined;
|
||||
@ -100,42 +100,42 @@ pub const TestContext = struct {
|
||||
// TODO async I/O
|
||||
try std.io.writeFile(allocator, file1_path, source);
|
||||
|
||||
var module = try Module.create(
|
||||
var comp = try Compilation.create(
|
||||
&self.event_loop_local,
|
||||
"test",
|
||||
file1_path,
|
||||
Target.Native,
|
||||
Module.Kind.Obj,
|
||||
Compilation.Kind.Obj,
|
||||
builtin.Mode.Debug,
|
||||
self.zig_lib_dir,
|
||||
self.zig_cache_dir,
|
||||
);
|
||||
errdefer module.destroy();
|
||||
errdefer comp.destroy();
|
||||
|
||||
try module.build();
|
||||
try comp.build();
|
||||
|
||||
try self.group.call(getModuleEvent, module, source, path, line, column, msg);
|
||||
try self.group.call(getModuleEvent, comp, source, path, line, column, msg);
|
||||
}
|
||||
|
||||
async fn getModuleEvent(
|
||||
module: *Module,
|
||||
comp: *Compilation,
|
||||
source: []const u8,
|
||||
path: []const u8,
|
||||
line: usize,
|
||||
column: usize,
|
||||
text: []const u8,
|
||||
) !void {
|
||||
defer module.destroy();
|
||||
const build_event = await (async module.events.get() catch unreachable);
|
||||
defer comp.destroy();
|
||||
const build_event = await (async comp.events.get() catch unreachable);
|
||||
|
||||
switch (build_event) {
|
||||
Module.Event.Ok => {
|
||||
Compilation.Event.Ok => {
|
||||
@panic("build incorrectly succeeded");
|
||||
},
|
||||
Module.Event.Error => |err| {
|
||||
Compilation.Event.Error => |err| {
|
||||
@panic("build incorrectly failed");
|
||||
},
|
||||
Module.Event.Fail => |msgs| {
|
||||
Compilation.Event.Fail => |msgs| {
|
||||
assertOrPanic(msgs.len != 0);
|
||||
for (msgs) |msg| {
|
||||
if (mem.endsWith(u8, msg.path, path) and mem.eql(u8, msg.text, text)) {
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const Scope = @import("scope.zig").Scope;
|
||||
const Module = @import("module.zig").Module;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
const Value = @import("value.zig").Value;
|
||||
const llvm = @import("llvm.zig");
|
||||
const CompilationUnit = @import("codegen.zig").CompilationUnit;
|
||||
const ObjectFile = @import("codegen.zig").ObjectFile;
|
||||
|
||||
pub const Type = struct {
|
||||
base: Value,
|
||||
@ -12,63 +12,63 @@ pub const Type = struct {
|
||||
|
||||
pub const Id = builtin.TypeId;
|
||||
|
||||
pub fn destroy(base: *Type, module: *Module) void {
|
||||
pub fn destroy(base: *Type, comp: *Compilation) void {
|
||||
switch (base.id) {
|
||||
Id.Struct => @fieldParentPtr(Struct, "base", base).destroy(module),
|
||||
Id.Fn => @fieldParentPtr(Fn, "base", base).destroy(module),
|
||||
Id.Type => @fieldParentPtr(MetaType, "base", base).destroy(module),
|
||||
Id.Void => @fieldParentPtr(Void, "base", base).destroy(module),
|
||||
Id.Bool => @fieldParentPtr(Bool, "base", base).destroy(module),
|
||||
Id.NoReturn => @fieldParentPtr(NoReturn, "base", base).destroy(module),
|
||||
Id.Int => @fieldParentPtr(Int, "base", base).destroy(module),
|
||||
Id.Float => @fieldParentPtr(Float, "base", base).destroy(module),
|
||||
Id.Pointer => @fieldParentPtr(Pointer, "base", base).destroy(module),
|
||||
Id.Array => @fieldParentPtr(Array, "base", base).destroy(module),
|
||||
Id.ComptimeFloat => @fieldParentPtr(ComptimeFloat, "base", base).destroy(module),
|
||||
Id.ComptimeInt => @fieldParentPtr(ComptimeInt, "base", base).destroy(module),
|
||||
Id.Undefined => @fieldParentPtr(Undefined, "base", base).destroy(module),
|
||||
Id.Null => @fieldParentPtr(Null, "base", base).destroy(module),
|
||||
Id.Optional => @fieldParentPtr(Optional, "base", base).destroy(module),
|
||||
Id.ErrorUnion => @fieldParentPtr(ErrorUnion, "base", base).destroy(module),
|
||||
Id.ErrorSet => @fieldParentPtr(ErrorSet, "base", base).destroy(module),
|
||||
Id.Enum => @fieldParentPtr(Enum, "base", base).destroy(module),
|
||||
Id.Union => @fieldParentPtr(Union, "base", base).destroy(module),
|
||||
Id.Namespace => @fieldParentPtr(Namespace, "base", base).destroy(module),
|
||||
Id.Block => @fieldParentPtr(Block, "base", base).destroy(module),
|
||||
Id.BoundFn => @fieldParentPtr(BoundFn, "base", base).destroy(module),
|
||||
Id.ArgTuple => @fieldParentPtr(ArgTuple, "base", base).destroy(module),
|
||||
Id.Opaque => @fieldParentPtr(Opaque, "base", base).destroy(module),
|
||||
Id.Promise => @fieldParentPtr(Promise, "base", base).destroy(module),
|
||||
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.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.Namespace => @fieldParentPtr(Namespace, "base", base).destroy(comp),
|
||||
Id.Block => @fieldParentPtr(Block, "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.Promise => @fieldParentPtr(Promise, "base", base).destroy(comp),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getLlvmType(base: *Type, cunit: *CompilationUnit) (error{OutOfMemory}!llvm.TypeRef) {
|
||||
pub fn getLlvmType(base: *Type, ofile: *ObjectFile) (error{OutOfMemory}!llvm.TypeRef) {
|
||||
switch (base.id) {
|
||||
Id.Struct => return @fieldParentPtr(Struct, "base", base).getLlvmType(cunit),
|
||||
Id.Fn => return @fieldParentPtr(Fn, "base", base).getLlvmType(cunit),
|
||||
Id.Struct => return @fieldParentPtr(Struct, "base", base).getLlvmType(ofile),
|
||||
Id.Fn => return @fieldParentPtr(Fn, "base", base).getLlvmType(ofile),
|
||||
Id.Type => unreachable,
|
||||
Id.Void => unreachable,
|
||||
Id.Bool => return @fieldParentPtr(Bool, "base", base).getLlvmType(cunit),
|
||||
Id.Bool => return @fieldParentPtr(Bool, "base", base).getLlvmType(ofile),
|
||||
Id.NoReturn => unreachable,
|
||||
Id.Int => return @fieldParentPtr(Int, "base", base).getLlvmType(cunit),
|
||||
Id.Float => return @fieldParentPtr(Float, "base", base).getLlvmType(cunit),
|
||||
Id.Pointer => return @fieldParentPtr(Pointer, "base", base).getLlvmType(cunit),
|
||||
Id.Array => return @fieldParentPtr(Array, "base", base).getLlvmType(cunit),
|
||||
Id.Int => return @fieldParentPtr(Int, "base", base).getLlvmType(ofile),
|
||||
Id.Float => return @fieldParentPtr(Float, "base", base).getLlvmType(ofile),
|
||||
Id.Pointer => return @fieldParentPtr(Pointer, "base", base).getLlvmType(ofile),
|
||||
Id.Array => return @fieldParentPtr(Array, "base", base).getLlvmType(ofile),
|
||||
Id.ComptimeFloat => unreachable,
|
||||
Id.ComptimeInt => unreachable,
|
||||
Id.Undefined => unreachable,
|
||||
Id.Null => unreachable,
|
||||
Id.Optional => return @fieldParentPtr(Optional, "base", base).getLlvmType(cunit),
|
||||
Id.ErrorUnion => return @fieldParentPtr(ErrorUnion, "base", base).getLlvmType(cunit),
|
||||
Id.ErrorSet => return @fieldParentPtr(ErrorSet, "base", base).getLlvmType(cunit),
|
||||
Id.Enum => return @fieldParentPtr(Enum, "base", base).getLlvmType(cunit),
|
||||
Id.Union => return @fieldParentPtr(Union, "base", base).getLlvmType(cunit),
|
||||
Id.Optional => return @fieldParentPtr(Optional, "base", base).getLlvmType(ofile),
|
||||
Id.ErrorUnion => return @fieldParentPtr(ErrorUnion, "base", base).getLlvmType(ofile),
|
||||
Id.ErrorSet => return @fieldParentPtr(ErrorSet, "base", base).getLlvmType(ofile),
|
||||
Id.Enum => return @fieldParentPtr(Enum, "base", base).getLlvmType(ofile),
|
||||
Id.Union => return @fieldParentPtr(Union, "base", base).getLlvmType(ofile),
|
||||
Id.Namespace => unreachable,
|
||||
Id.Block => unreachable,
|
||||
Id.BoundFn => return @fieldParentPtr(BoundFn, "base", base).getLlvmType(cunit),
|
||||
Id.BoundFn => return @fieldParentPtr(BoundFn, "base", base).getLlvmType(ofile),
|
||||
Id.ArgTuple => unreachable,
|
||||
Id.Opaque => return @fieldParentPtr(Opaque, "base", base).getLlvmType(cunit),
|
||||
Id.Promise => return @fieldParentPtr(Promise, "base", base).getLlvmType(cunit),
|
||||
Id.Opaque => return @fieldParentPtr(Opaque, "base", base).getLlvmType(ofile),
|
||||
Id.Promise => return @fieldParentPtr(Promise, "base", base).getLlvmType(ofile),
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ pub const Type = struct {
|
||||
std.debug.warn("{}", @tagName(base.id));
|
||||
}
|
||||
|
||||
pub fn getAbiAlignment(base: *Type, module: *Module) u32 {
|
||||
pub fn getAbiAlignment(base: *Type, comp: *Compilation) u32 {
|
||||
@panic("TODO getAbiAlignment");
|
||||
}
|
||||
|
||||
@ -84,11 +84,11 @@ pub const Type = struct {
|
||||
base: Type,
|
||||
decls: *Scope.Decls,
|
||||
|
||||
pub fn destroy(self: *Struct, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Struct, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *Struct, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *Struct, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
@ -104,12 +104,12 @@ pub const Type = struct {
|
||||
typeof: *Type,
|
||||
};
|
||||
|
||||
pub fn create(module: *Module, return_type: *Type, params: []Param, is_var_args: bool) !*Fn {
|
||||
const result = try module.a().create(Fn{
|
||||
pub fn create(comp: *Compilation, return_type: *Type, params: []Param, is_var_args: bool) !*Fn {
|
||||
const result = try comp.a().create(Fn{
|
||||
.base = Type{
|
||||
.base = Value{
|
||||
.id = Value.Id.Type,
|
||||
.typeof = &MetaType.get(module).base,
|
||||
.typeof = &MetaType.get(comp).base,
|
||||
.ref_count = std.atomic.Int(usize).init(1),
|
||||
},
|
||||
.id = builtin.TypeId.Fn,
|
||||
@ -118,7 +118,7 @@ pub const Type = struct {
|
||||
.params = params,
|
||||
.is_var_args = is_var_args,
|
||||
});
|
||||
errdefer module.a().destroy(result);
|
||||
errdefer comp.a().destroy(result);
|
||||
|
||||
result.return_type.base.ref();
|
||||
for (result.params) |param| {
|
||||
@ -127,23 +127,23 @@ pub const Type = struct {
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Fn, module: *Module) void {
|
||||
self.return_type.base.deref(module);
|
||||
pub fn destroy(self: *Fn, comp: *Compilation) void {
|
||||
self.return_type.base.deref(comp);
|
||||
for (self.params) |param| {
|
||||
param.typeof.base.deref(module);
|
||||
param.typeof.base.deref(comp);
|
||||
}
|
||||
module.a().destroy(self);
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *Fn, cunit: *CompilationUnit) !llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *Fn, ofile: *ObjectFile) !llvm.TypeRef {
|
||||
const llvm_return_type = switch (self.return_type.id) {
|
||||
Type.Id.Void => llvm.VoidTypeInContext(cunit.context) orelse return error.OutOfMemory,
|
||||
else => try self.return_type.getLlvmType(cunit),
|
||||
Type.Id.Void => llvm.VoidTypeInContext(ofile.context) orelse return error.OutOfMemory,
|
||||
else => try self.return_type.getLlvmType(ofile),
|
||||
};
|
||||
const llvm_param_types = try cunit.a().alloc(llvm.TypeRef, self.params.len);
|
||||
defer cunit.a().free(llvm_param_types);
|
||||
const llvm_param_types = try ofile.a().alloc(llvm.TypeRef, self.params.len);
|
||||
defer ofile.a().free(llvm_param_types);
|
||||
for (llvm_param_types) |*llvm_param_type, i| {
|
||||
llvm_param_type.* = try self.params[i].typeof.getLlvmType(cunit);
|
||||
llvm_param_type.* = try self.params[i].typeof.getLlvmType(ofile);
|
||||
}
|
||||
|
||||
return llvm.FunctionType(
|
||||
@ -160,13 +160,13 @@ pub const Type = struct {
|
||||
value: *Type,
|
||||
|
||||
/// Adds 1 reference to the resulting type
|
||||
pub fn get(module: *Module) *MetaType {
|
||||
module.meta_type.base.base.ref();
|
||||
return module.meta_type;
|
||||
pub fn get(comp: *Compilation) *MetaType {
|
||||
comp.meta_type.base.base.ref();
|
||||
return comp.meta_type;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *MetaType, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *MetaType, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
@ -174,13 +174,13 @@ pub const Type = struct {
|
||||
base: Type,
|
||||
|
||||
/// Adds 1 reference to the resulting type
|
||||
pub fn get(module: *Module) *Void {
|
||||
module.void_type.base.base.ref();
|
||||
return module.void_type;
|
||||
pub fn get(comp: *Compilation) *Void {
|
||||
comp.void_type.base.base.ref();
|
||||
return comp.void_type;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Void, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Void, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
@ -188,16 +188,16 @@ pub const Type = struct {
|
||||
base: Type,
|
||||
|
||||
/// Adds 1 reference to the resulting type
|
||||
pub fn get(module: *Module) *Bool {
|
||||
module.bool_type.base.base.ref();
|
||||
return module.bool_type;
|
||||
pub fn get(comp: *Compilation) *Bool {
|
||||
comp.bool_type.base.base.ref();
|
||||
return comp.bool_type;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Bool, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Bool, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *Bool, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *Bool, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
@ -206,24 +206,24 @@ pub const Type = struct {
|
||||
base: Type,
|
||||
|
||||
/// Adds 1 reference to the resulting type
|
||||
pub fn get(module: *Module) *NoReturn {
|
||||
module.noreturn_type.base.base.ref();
|
||||
return module.noreturn_type;
|
||||
pub fn get(comp: *Compilation) *NoReturn {
|
||||
comp.noreturn_type.base.base.ref();
|
||||
return comp.noreturn_type;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *NoReturn, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *NoReturn, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Int = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *Int, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Int, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *Int, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *Int, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
@ -231,11 +231,11 @@ pub const Type = struct {
|
||||
pub const Float = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *Float, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Float, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *Float, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *Float, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
@ -256,12 +256,12 @@ pub const Type = struct {
|
||||
};
|
||||
pub const Size = builtin.TypeInfo.Pointer.Size;
|
||||
|
||||
pub fn destroy(self: *Pointer, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Pointer, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn get(
|
||||
module: *Module,
|
||||
comp: *Compilation,
|
||||
elem_type: *Type,
|
||||
mut: Mut,
|
||||
vol: Vol,
|
||||
@ -271,7 +271,7 @@ pub const Type = struct {
|
||||
@panic("TODO get pointer");
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *Pointer, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *Pointer, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
@ -279,11 +279,11 @@ pub const Type = struct {
|
||||
pub const Array = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *Array, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Array, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *Array, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *Array, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
@ -291,43 +291,43 @@ pub const Type = struct {
|
||||
pub const ComptimeFloat = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *ComptimeFloat, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *ComptimeFloat, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const ComptimeInt = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *ComptimeInt, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *ComptimeInt, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Undefined = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *Undefined, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Undefined, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Null = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *Null, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Null, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Optional = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *Optional, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Optional, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *Optional, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *Optional, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
@ -335,11 +335,11 @@ pub const Type = struct {
|
||||
pub const ErrorUnion = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *ErrorUnion, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *ErrorUnion, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *ErrorUnion, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *ErrorUnion, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
@ -347,11 +347,11 @@ pub const Type = struct {
|
||||
pub const ErrorSet = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *ErrorSet, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *ErrorSet, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *ErrorSet, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *ErrorSet, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
@ -359,11 +359,11 @@ pub const Type = struct {
|
||||
pub const Enum = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *Enum, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Enum, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *Enum, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *Enum, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
@ -371,11 +371,11 @@ pub const Type = struct {
|
||||
pub const Union = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *Union, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Union, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *Union, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *Union, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
@ -383,27 +383,27 @@ pub const Type = struct {
|
||||
pub const Namespace = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *Namespace, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Namespace, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Block = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *Block, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Block, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const BoundFn = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *BoundFn, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *BoundFn, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *BoundFn, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *BoundFn, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
@ -411,19 +411,19 @@ pub const Type = struct {
|
||||
pub const ArgTuple = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *ArgTuple, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *ArgTuple, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Opaque = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *Opaque, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Opaque, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *Opaque, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *Opaque, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
@ -431,11 +431,11 @@ pub const Type = struct {
|
||||
pub const Promise = struct {
|
||||
base: Type,
|
||||
|
||||
pub fn destroy(self: *Promise, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Promise, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
|
||||
pub fn getLlvmType(self: *Promise, cunit: *CompilationUnit) llvm.TypeRef {
|
||||
pub fn getLlvmType(self: *Promise, ofile: *ObjectFile) llvm.TypeRef {
|
||||
@panic("TODO");
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const Scope = @import("scope.zig").Scope;
|
||||
const Module = @import("module.zig").Module;
|
||||
const Compilation = @import("compilation.zig").Compilation;
|
||||
|
||||
/// Values are ref-counted, heap-allocated, and copy-on-write
|
||||
/// If there is only 1 ref then write need not copy
|
||||
@ -16,16 +16,16 @@ pub const Value = struct {
|
||||
}
|
||||
|
||||
/// Thread-safe
|
||||
pub fn deref(base: *Value, module: *Module) void {
|
||||
pub fn deref(base: *Value, comp: *Compilation) void {
|
||||
if (base.ref_count.decr() == 1) {
|
||||
base.typeof.base.deref(module);
|
||||
base.typeof.base.deref(comp);
|
||||
switch (base.id) {
|
||||
Id.Type => @fieldParentPtr(Type, "base", base).destroy(module),
|
||||
Id.Fn => @fieldParentPtr(Fn, "base", base).destroy(module),
|
||||
Id.Void => @fieldParentPtr(Void, "base", base).destroy(module),
|
||||
Id.Bool => @fieldParentPtr(Bool, "base", base).destroy(module),
|
||||
Id.NoReturn => @fieldParentPtr(NoReturn, "base", base).destroy(module),
|
||||
Id.Ptr => @fieldParentPtr(Ptr, "base", base).destroy(module),
|
||||
Id.Type => @fieldParentPtr(Type, "base", base).destroy(comp),
|
||||
Id.Fn => @fieldParentPtr(Fn, "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),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -68,8 +68,8 @@ pub const Value = struct {
|
||||
|
||||
/// Creates a Fn value with 1 ref
|
||||
/// Takes ownership of symbol_name
|
||||
pub fn create(module: *Module, fn_type: *Type.Fn, fndef_scope: *Scope.FnDef, symbol_name: std.Buffer) !*Fn {
|
||||
const self = try module.a().create(Fn{
|
||||
pub fn create(comp: *Compilation, fn_type: *Type.Fn, fndef_scope: *Scope.FnDef, symbol_name: std.Buffer) !*Fn {
|
||||
const self = try comp.a().create(Fn{
|
||||
.base = Value{
|
||||
.id = Value.Id.Fn,
|
||||
.typeof = &fn_type.base,
|
||||
@ -86,23 +86,23 @@ pub const Value = struct {
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Fn, module: *Module) void {
|
||||
self.fndef_scope.base.deref(module);
|
||||
pub fn destroy(self: *Fn, comp: *Compilation) void {
|
||||
self.fndef_scope.base.deref(comp);
|
||||
self.symbol_name.deinit();
|
||||
module.a().destroy(self);
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Void = struct {
|
||||
base: Value,
|
||||
|
||||
pub fn get(module: *Module) *Void {
|
||||
module.void_value.base.ref();
|
||||
return module.void_value;
|
||||
pub fn get(comp: *Compilation) *Void {
|
||||
comp.void_value.base.ref();
|
||||
return comp.void_value;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Void, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Void, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
@ -110,31 +110,31 @@ pub const Value = struct {
|
||||
base: Value,
|
||||
x: bool,
|
||||
|
||||
pub fn get(module: *Module, x: bool) *Bool {
|
||||
pub fn get(comp: *Compilation, x: bool) *Bool {
|
||||
if (x) {
|
||||
module.true_value.base.ref();
|
||||
return module.true_value;
|
||||
comp.true_value.base.ref();
|
||||
return comp.true_value;
|
||||
} else {
|
||||
module.false_value.base.ref();
|
||||
return module.false_value;
|
||||
comp.false_value.base.ref();
|
||||
return comp.false_value;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroy(self: *Bool, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Bool, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const NoReturn = struct {
|
||||
base: Value,
|
||||
|
||||
pub fn get(module: *Module) *NoReturn {
|
||||
module.noreturn_value.base.ref();
|
||||
return module.noreturn_value;
|
||||
pub fn get(comp: *Compilation) *NoReturn {
|
||||
comp.noreturn_value.base.ref();
|
||||
return comp.noreturn_value;
|
||||
}
|
||||
|
||||
pub fn destroy(self: *NoReturn, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *NoReturn, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
|
||||
@ -147,8 +147,8 @@ pub const Value = struct {
|
||||
RunTime,
|
||||
};
|
||||
|
||||
pub fn destroy(self: *Ptr, module: *Module) void {
|
||||
module.a().destroy(self);
|
||||
pub fn destroy(self: *Ptr, comp: *Compilation) void {
|
||||
comp.a().destroy(self);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user