mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 23:23:07 +00:00
stage2: add initial implementation of func arguments in LLVM backend
The following works:
```
export fn _start() noreturn {
assert(true);
exit();
}
fn assert(cond: bool) void {}
fn exit() noreturn {
unreachable;
}
```
This commit is contained in:
parent
4a32d4f288
commit
ec3aedffb1
@ -301,6 +301,7 @@ pub const LLVMIRModule = struct {
|
||||
.call => try self.genCall(inst.castTag(.call).?),
|
||||
.unreach => self.genUnreach(inst.castTag(.unreach).?),
|
||||
.retvoid => self.genRetVoid(inst.castTag(.retvoid).?),
|
||||
.arg => self.genArg(inst.castTag(.arg).?),
|
||||
.dbg_stmt => {
|
||||
// TODO: implement debug info
|
||||
},
|
||||
@ -319,11 +320,23 @@ pub const LLVMIRModule = struct {
|
||||
const zig_fn_type = func.owner_decl.typed_value.most_recent.typed_value.ty;
|
||||
const llvm_fn = try self.resolveLLVMFunction(func);
|
||||
|
||||
// TODO: handle more arguments, inst.args
|
||||
const num_args = inst.args.len;
|
||||
|
||||
const llvm_param_vals = try self.gpa.alloc(*const llvm.ValueRef, num_args);
|
||||
defer self.gpa.free(llvm_param_vals);
|
||||
|
||||
for (inst.args) |arg, i| {
|
||||
llvm_param_vals[i] = try self.resolveInst(arg);
|
||||
}
|
||||
|
||||
// TODO: LLVMBuildCall2 handles opaque function pointers, according to llvm docs
|
||||
// Do we need that?
|
||||
const call = self.builder.buildCall(llvm_fn, null, 0, "");
|
||||
const call = self.builder.buildCall(
|
||||
llvm_fn,
|
||||
if (num_args == 0) null else llvm_param_vals.ptr,
|
||||
@intCast(c_uint, num_args),
|
||||
"",
|
||||
);
|
||||
|
||||
if (zig_fn_type.fnReturnType().zigTypeTag() == .NoReturn) {
|
||||
_ = self.builder.buildUnreachable();
|
||||
@ -340,6 +353,10 @@ pub const LLVMIRModule = struct {
|
||||
_ = self.builder.buildUnreachable();
|
||||
}
|
||||
|
||||
fn genArg(self: *LLVMIRModule, inst: *Inst.Arg) void {
|
||||
// TODO: implement this
|
||||
}
|
||||
|
||||
fn genBreakpoint(self: *LLVMIRModule, inst: *Inst.NoOp) !void {
|
||||
// TODO: Store this function somewhere such that we dont have to add it again
|
||||
const fn_type = llvm.TypeRef.functionType(llvm.voidType(), null, 0, false);
|
||||
@ -348,6 +365,25 @@ pub const LLVMIRModule = struct {
|
||||
_ = self.builder.buildCall(func, null, 0, "");
|
||||
}
|
||||
|
||||
fn resolveInst(self: *LLVMIRModule, inst: *ir.Inst) !*const llvm.ValueRef {
|
||||
if (inst.castTag(.constant)) |const_inst| {
|
||||
return self.genTypedValue(inst.src, .{ .ty = inst.ty, .val = const_inst.val });
|
||||
}
|
||||
return self.fail(inst.src, "TODO implement resolveInst", .{});
|
||||
}
|
||||
|
||||
fn genTypedValue(self: *LLVMIRModule, src: usize, typed_value: TypedValue) !*const llvm.ValueRef {
|
||||
const llvm_type = self.getLLVMType(typed_value.ty);
|
||||
|
||||
if (typed_value.val.isUndef())
|
||||
return llvm_type.getUndef();
|
||||
|
||||
switch (typed_value.ty.zigTypeTag()) {
|
||||
.Bool => return if (typed_value.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull(),
|
||||
else => return self.fail(src, "TODO implement const of type '{}'", .{typed_value.ty}),
|
||||
}
|
||||
}
|
||||
|
||||
/// If the llvm function does not exist, create it
|
||||
fn resolveLLVMFunction(self: *LLVMIRModule, func: *Module.Fn) !*const llvm.ValueRef {
|
||||
// TODO: do we want to store this in our own datastructure?
|
||||
|
||||
@ -36,6 +36,15 @@ pub const ValueRef = opaque {
|
||||
pub const TypeRef = opaque {
|
||||
pub const functionType = LLVMFunctionType;
|
||||
extern fn LLVMFunctionType(ReturnType: *const TypeRef, ParamTypes: ?[*]*const TypeRef, ParamCount: c_uint, IsVarArg: LLVMBool) *const TypeRef;
|
||||
|
||||
pub const constNull = LLVMConstNull;
|
||||
extern fn LLVMConstNull(Ty: *const TypeRef) *const ValueRef;
|
||||
|
||||
pub const constAllOnes = LLVMConstAllOnes;
|
||||
extern fn LLVMConstAllOnes(Ty: *const TypeRef) *const ValueRef;
|
||||
|
||||
pub const getUndef = LLVMGetUndef;
|
||||
extern fn LLVMGetUndef(Ty: *const TypeRef) *const ValueRef;
|
||||
};
|
||||
|
||||
pub const ModuleRef = opaque {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user