diff options
| author | Baitinq <[email protected]> | 2025-05-18 23:46:45 +0200 |
|---|---|---|
| committer | Baitinq <[email protected]> | 2025-05-18 23:46:45 +0200 |
| commit | c22f446410de1d04827a2e18b90c6fba47820db0 (patch) | |
| tree | f6c81da08143a612e1c720dd54d369f8555fc9af /src/codegen.zig | |
| parent | Codegen: Don't allow assigning variables of different type (diff) | |
| download | pry-lang-c22f446410de1d04827a2e18b90c6fba47820db0.tar.gz pry-lang-c22f446410de1d04827a2e18b90c6fba47820db0.tar.bz2 pry-lang-c22f446410de1d04827a2e18b90c6fba47820db0.zip | |
Codegen: Fix bug with varargs functions
Diffstat (limited to 'src/codegen.zig')
| -rw-r--r-- | src/codegen.zig | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index c0658f4..7cfaa04 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -353,20 +353,25 @@ pub const CodeGen = struct { var llvm_param_types = std.ArrayList(llvm.LLVMTypeRef).init(self.arena); var param_types = std.ArrayList(*parser.Node).init(self.arena); + var is_varargs: i8 = 0; for (function_definition.parameters) |param| { std.debug.assert(param.PRIMARY_EXPRESSION == .IDENTIFIER); - var param_type = try self.get_llvm_type(param.PRIMARY_EXPRESSION.IDENTIFIER.type.?); - if (param.PRIMARY_EXPRESSION.IDENTIFIER.type.?.TYPE == .FUNCTION_TYPE) { - param_type = llvm.LLVMPointerType(param_type.?, 0); + const param_type = param.PRIMARY_EXPRESSION.IDENTIFIER.type.?; + if (param_type.TYPE == .SIMPLE_TYPE and std.mem.eql(u8, param_type.TYPE.SIMPLE_TYPE.name, "varargs")) { + is_varargs = 1; + } + var llvm_param_type = try self.get_llvm_type(param_type); + if (param_type.TYPE == .FUNCTION_TYPE) { + llvm_param_type = llvm.LLVMPointerType(llvm_param_type, 0); } - try llvm_param_types.append(param_type); - try param_types.append(param.PRIMARY_EXPRESSION.IDENTIFIER.type.?); + try llvm_param_types.append(llvm_param_type); + try param_types.append(param_type); } var return_type = try self.get_llvm_type(function_definition.return_type); if (function_definition.return_type.TYPE == .FUNCTION_TYPE) { return_type = llvm.LLVMPointerType(return_type, 0); } - const function_type = llvm.LLVMFunctionType(return_type, llvm_param_types.items.ptr, @intCast(llvm_param_types.items.len), 0) orelse return CodeGenError.CompilationError; + const function_type = llvm.LLVMFunctionType(return_type, llvm_param_types.items.ptr, @intCast(llvm_param_types.items.len), is_varargs) orelse return CodeGenError.CompilationError; const function = llvm.LLVMAddFunction(self.llvm_module, try std.fmt.allocPrintZ(self.arena, "{s}", .{name orelse "unnamed_func"}), function_type) orelse return CodeGenError.CompilationError; const function_entry = llvm.LLVMAppendBasicBlock(function, "entrypoint") orelse return CodeGenError.CompilationError; llvm.LLVMPositionBuilderAtEnd(self.builder, function_entry); @@ -407,20 +412,20 @@ pub const CodeGen = struct { const param_node = function_definition.parameters[parameters_index]; std.debug.assert(param_node.* == .PRIMARY_EXPRESSION); - const param_type = try self.get_llvm_type(param_node.PRIMARY_EXPRESSION.IDENTIFIER.type.?); - var alloca_param_type = param_type; + const param_type = param_node.PRIMARY_EXPRESSION.IDENTIFIER.type.?; + var llvm_param_type = try self.get_llvm_type(param_type); if (param_node.PRIMARY_EXPRESSION.IDENTIFIER.type.?.TYPE == .FUNCTION_TYPE) { - alloca_param_type = llvm.LLVMPointerType(alloca_param_type.?, 0); + llvm_param_type = llvm.LLVMPointerType(llvm_param_type.?, 0); } // We need to alloca params because we assume all identifiers are alloca - const alloca = llvm.LLVMBuildAlloca(self.builder, alloca_param_type, try std.fmt.allocPrintZ(self.arena, "{s}", .{param_node.PRIMARY_EXPRESSION.IDENTIFIER.name})); + const alloca = llvm.LLVMBuildAlloca(self.builder, llvm_param_type, try std.fmt.allocPrintZ(self.arena, "{s}", .{param_node.PRIMARY_EXPRESSION.IDENTIFIER.name})); _ = llvm.LLVMBuildStore(self.builder, p, alloca); try self.environment.add_variable(param_node.PRIMARY_EXPRESSION.IDENTIFIER.name, try self.create_variable(.{ .value = alloca, .stack_level = null, .node = param_node, - .node_type = param_node.PRIMARY_EXPRESSION.IDENTIFIER.type.?, + .node_type = param_type, })); } |