| ... | @@ -305,11 +305,11 @@ pub const DeclGen = struct { | ... | @@ -305,11 +305,11 @@ pub const DeclGen = struct { |
| 305 | | 305 | |
| 306 | gpa: *Allocator, | 306 | gpa: *Allocator, |
| 307 | | 307 | |
| 308 | fn fail(self: *DeclGen, src: LazySrcLoc, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { | 308 | fn todo(self: *DeclGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { |
| 309 | @setCold(true); | 309 | @setCold(true); |
| 310 | assert(self.err_msg == null); | 310 | assert(self.err_msg == null); |
| 311 | const src_loc = src.toSrcLocWithDecl(self.decl); | 311 | const src_loc = @as(LazySrcLoc, .{ .node_offset = 0 }).toSrcLocWithDecl(self.decl); |
| 312 | self.err_msg = try Module.ErrorMsg.create(self.gpa, src_loc, format, args); | 312 | self.err_msg = try Module.ErrorMsg.create(self.gpa, src_loc, "TODO (LLVM): " ++ format, args); |
| 313 | return error.CodegenFail; | 313 | return error.CodegenFail; |
| 314 | } | 314 | } |
| 315 | | 315 | |
| ... | @@ -325,14 +325,12 @@ pub const DeclGen = struct { | ... | @@ -325,14 +325,12 @@ pub const DeclGen = struct { |
| 325 | const decl = self.decl; | 325 | const decl = self.decl; |
| 326 | const typed_value = decl.typed_value.most_recent.typed_value; | 326 | const typed_value = decl.typed_value.most_recent.typed_value; |
| 327 | | 327 | |
| 328 | const src = decl.srcLoc().lazy; | | |
| 329 | | | |
| 330 | log.debug("gen: {s} type: {}, value: {}", .{ decl.name, typed_value.ty, typed_value.val }); | 328 | log.debug("gen: {s} type: {}, value: {}", .{ decl.name, typed_value.ty, typed_value.val }); |
| 331 | | 329 | |
| 332 | if (typed_value.val.castTag(.function)) |func_payload| { | 330 | if (typed_value.val.castTag(.function)) |func_payload| { |
| 333 | const func = func_payload.data; | 331 | const func = func_payload.data; |
| 334 | | 332 | |
| 335 | const llvm_func = try self.resolveLLVMFunction(func.owner_decl, src); | 333 | const llvm_func = try self.resolveLLVMFunction(func.owner_decl); |
| 336 | | 334 | |
| 337 | // This gets the LLVM values from the function and stores them in `self.args`. | 335 | // This gets the LLVM values from the function and stores them in `self.args`. |
| 338 | const fn_param_len = func.owner_decl.typed_value.most_recent.typed_value.ty.fnParamLen(); | 336 | const fn_param_len = func.owner_decl.typed_value.most_recent.typed_value.ty.fnParamLen(); |
| ... | @@ -369,14 +367,14 @@ pub const DeclGen = struct { | ... | @@ -369,14 +367,14 @@ pub const DeclGen = struct { |
| 369 | | 367 | |
| 370 | try fg.genBody(func.body); | 368 | try fg.genBody(func.body); |
| 371 | } else if (typed_value.val.castTag(.extern_fn)) |extern_fn| { | 369 | } else if (typed_value.val.castTag(.extern_fn)) |extern_fn| { |
| 372 | _ = try self.resolveLLVMFunction(extern_fn.data, src); | 370 | _ = try self.resolveLLVMFunction(extern_fn.data); |
| 373 | } else { | 371 | } else { |
| 374 | _ = try self.resolveGlobalDecl(decl, src); | 372 | _ = try self.resolveGlobalDecl(decl); |
| 375 | } | 373 | } |
| 376 | } | 374 | } |
| 377 | | 375 | |
| 378 | /// If the llvm function does not exist, create it | 376 | /// If the llvm function does not exist, create it |
| 379 | fn resolveLLVMFunction(self: *DeclGen, func: *Module.Decl, src: LazySrcLoc) !*const llvm.Value { | 377 | fn resolveLLVMFunction(self: *DeclGen, func: *Module.Decl) !*const llvm.Value { |
| 380 | // TODO: do we want to store this in our own datastructure? | 378 | // TODO: do we want to store this in our own datastructure? |
| 381 | if (self.llvmModule().getNamedFunction(func.name)) |llvm_fn| return llvm_fn; | 379 | if (self.llvmModule().getNamedFunction(func.name)) |llvm_fn| return llvm_fn; |
| 382 | | 380 | |
| ... | @@ -393,11 +391,11 @@ pub const DeclGen = struct { | ... | @@ -393,11 +391,11 @@ pub const DeclGen = struct { |
| 393 | defer self.gpa.free(llvm_param); | 391 | defer self.gpa.free(llvm_param); |
| 394 | | 392 | |
| 395 | for (fn_param_types) |fn_param, i| { | 393 | for (fn_param_types) |fn_param, i| { |
| 396 | llvm_param[i] = try self.getLLVMType(fn_param, src); | 394 | llvm_param[i] = try self.getLLVMType(fn_param); |
| 397 | } | 395 | } |
| 398 | | 396 | |
| 399 | const fn_type = llvm.Type.functionType( | 397 | const fn_type = llvm.Type.functionType( |
| 400 | try self.getLLVMType(return_type, src), | 398 | try self.getLLVMType(return_type), |
| 401 | if (fn_param_len == 0) null else llvm_param.ptr, | 399 | if (fn_param_len == 0) null else llvm_param.ptr, |
| 402 | @intCast(c_uint, fn_param_len), | 400 | @intCast(c_uint, fn_param_len), |
| 403 | .False, | 401 | .False, |
| ... | @@ -411,15 +409,15 @@ pub const DeclGen = struct { | ... | @@ -411,15 +409,15 @@ pub const DeclGen = struct { |
| 411 | return llvm_fn; | 409 | return llvm_fn; |
| 412 | } | 410 | } |
| 413 | | 411 | |
| 414 | fn resolveGlobalDecl(self: *DeclGen, decl: *Module.Decl, src: LazySrcLoc) error{ OutOfMemory, CodegenFail }!*const llvm.Value { | 412 | fn resolveGlobalDecl(self: *DeclGen, decl: *Module.Decl) error{ OutOfMemory, CodegenFail }!*const llvm.Value { |
| 415 | // TODO: do we want to store this in our own datastructure? | 413 | // TODO: do we want to store this in our own datastructure? |
| 416 | if (self.llvmModule().getNamedGlobal(decl.name)) |val| return val; | 414 | if (self.llvmModule().getNamedGlobal(decl.name)) |val| return val; |
| 417 | | 415 | |
| 418 | const typed_value = decl.typed_value.most_recent.typed_value; | 416 | const typed_value = decl.typed_value.most_recent.typed_value; |
| 419 | | 417 | |
| 420 | // TODO: remove this redundant `getLLVMType`, it is also called in `genTypedValue`. | 418 | // TODO: remove this redundant `getLLVMType`, it is also called in `genTypedValue`. |
| 421 | const llvm_type = try self.getLLVMType(typed_value.ty, src); | 419 | const llvm_type = try self.getLLVMType(typed_value.ty); |
| 422 | const val = try self.genTypedValue(src, typed_value, null); | 420 | const val = try self.genTypedValue(typed_value, null); |
| 423 | const global = self.llvmModule().addGlobal(llvm_type, decl.name); | 421 | const global = self.llvmModule().addGlobal(llvm_type, decl.name); |
| 424 | llvm.setInitializer(global, val); | 422 | llvm.setInitializer(global, val); |
| 425 | | 423 | |
| ... | @@ -429,7 +427,7 @@ pub const DeclGen = struct { | ... | @@ -429,7 +427,7 @@ pub const DeclGen = struct { |
| 429 | return global; | 427 | return global; |
| 430 | } | 428 | } |
| 431 | | 429 | |
| 432 | fn getLLVMType(self: *DeclGen, t: Type, src: LazySrcLoc) error{ OutOfMemory, CodegenFail }!*const llvm.Type { | 430 | fn getLLVMType(self: *DeclGen, t: Type) error{ OutOfMemory, CodegenFail }!*const llvm.Type { |
| 433 | switch (t.zigTypeTag()) { | 431 | switch (t.zigTypeTag()) { |
| 434 | .Void => return self.context().voidType(), | 432 | .Void => return self.context().voidType(), |
| 435 | .NoReturn => return self.context().voidType(), | 433 | .NoReturn => return self.context().voidType(), |
| ... | @@ -440,14 +438,14 @@ pub const DeclGen = struct { | ... | @@ -440,14 +438,14 @@ pub const DeclGen = struct { |
| 440 | .Bool => return self.context().intType(1), | 438 | .Bool => return self.context().intType(1), |
| 441 | .Pointer => { | 439 | .Pointer => { |
| 442 | if (t.isSlice()) { | 440 | if (t.isSlice()) { |
| 443 | return self.fail(src, "TODO: LLVM backend: implement slices", .{}); | 441 | return self.todo("implement slices", .{}); |
| 444 | } else { | 442 | } else { |
| 445 | const elem_type = try self.getLLVMType(t.elemType(), src); | 443 | const elem_type = try self.getLLVMType(t.elemType()); |
| 446 | return elem_type.pointerType(0); | 444 | return elem_type.pointerType(0); |
| 447 | } | 445 | } |
| 448 | }, | 446 | }, |
| 449 | .Array => { | 447 | .Array => { |
| 450 | const elem_type = try self.getLLVMType(t.elemType(), src); | 448 | const elem_type = try self.getLLVMType(t.elemType()); |
| 451 | return elem_type.arrayType(@intCast(c_uint, t.abiSize(self.module.getTarget()))); | 449 | return elem_type.arrayType(@intCast(c_uint, t.abiSize(self.module.getTarget()))); |
| 452 | }, | 450 | }, |
| 453 | .Optional => { | 451 | .Optional => { |
| ... | @@ -456,21 +454,21 @@ pub const DeclGen = struct { | ... | @@ -456,21 +454,21 @@ pub const DeclGen = struct { |
| 456 | const child_type = t.optionalChild(&buf); | 454 | const child_type = t.optionalChild(&buf); |
| 457 | | 455 | |
| 458 | var optional_types: [2]*const llvm.Type = .{ | 456 | var optional_types: [2]*const llvm.Type = .{ |
| 459 | try self.getLLVMType(child_type, src), | 457 | try self.getLLVMType(child_type), |
| 460 | self.context().intType(1), | 458 | self.context().intType(1), |
| 461 | }; | 459 | }; |
| 462 | return self.context().structType(&optional_types, 2, .False); | 460 | return self.context().structType(&optional_types, 2, .False); |
| 463 | } else { | 461 | } else { |
| 464 | return self.fail(src, "TODO implement optional pointers as actual pointers", .{}); | 462 | return self.todo("implement optional pointers as actual pointers", .{}); |
| 465 | } | 463 | } |
| 466 | }, | 464 | }, |
| 467 | else => return self.fail(src, "TODO implement getLLVMType for type '{}'", .{t}), | 465 | else => return self.todo("implement getLLVMType for type '{}'", .{t}), |
| 468 | } | 466 | } |
| 469 | } | 467 | } |
| 470 | | 468 | |
| 471 | // TODO: figure out a way to remove the FuncGen argument | 469 | // TODO: figure out a way to remove the FuncGen argument |
| 472 | fn genTypedValue(self: *DeclGen, src: LazySrcLoc, tv: TypedValue, fg: ?*FuncGen) error{ OutOfMemory, CodegenFail }!*const llvm.Value { | 470 | fn genTypedValue(self: *DeclGen, tv: TypedValue, fg: ?*FuncGen) error{ OutOfMemory, CodegenFail }!*const llvm.Value { |
| 473 | const llvm_type = try self.getLLVMType(tv.ty, src); | 471 | const llvm_type = try self.getLLVMType(tv.ty); |
| 474 | | 472 | |
| 475 | if (tv.val.isUndef()) | 473 | if (tv.val.isUndef()) |
| 476 | return llvm_type.getUndef(); | 474 | return llvm_type.getUndef(); |
| ... | @@ -484,7 +482,7 @@ pub const DeclGen = struct { | ... | @@ -484,7 +482,7 @@ pub const DeclGen = struct { |
| 484 | if (bigint.eqZero()) return llvm_type.constNull(); | 482 | if (bigint.eqZero()) return llvm_type.constNull(); |
| 485 | | 483 | |
| 486 | if (bigint.limbs.len != 1) { | 484 | if (bigint.limbs.len != 1) { |
| 487 | return self.fail(src, "TODO implement bigger bigint", .{}); | 485 | return self.todo("implement bigger bigint", .{}); |
| 488 | } | 486 | } |
| 489 | const llvm_int = llvm_type.constInt(bigint.limbs[0], .False); | 487 | const llvm_int = llvm_type.constInt(bigint.limbs[0], .False); |
| 490 | if (!bigint.positive) { | 488 | if (!bigint.positive) { |
| ... | @@ -495,9 +493,9 @@ pub const DeclGen = struct { | ... | @@ -495,9 +493,9 @@ pub const DeclGen = struct { |
| 495 | .Pointer => switch (tv.val.tag()) { | 493 | .Pointer => switch (tv.val.tag()) { |
| 496 | .decl_ref => { | 494 | .decl_ref => { |
| 497 | const decl = tv.val.castTag(.decl_ref).?.data; | 495 | const decl = tv.val.castTag(.decl_ref).?.data; |
| 498 | const val = try self.resolveGlobalDecl(decl, src); | 496 | const val = try self.resolveGlobalDecl(decl); |
| 499 | | 497 | |
| 500 | const usize_type = try self.getLLVMType(Type.initTag(.usize), src); | 498 | const usize_type = try self.getLLVMType(Type.initTag(.usize)); |
| 501 | | 499 | |
| 502 | // TODO: second index should be the index into the memory! | 500 | // TODO: second index should be the index into the memory! |
| 503 | var indices: [2]*const llvm.Value = .{ | 501 | var indices: [2]*const llvm.Value = .{ |
| ... | @@ -511,29 +509,29 @@ pub const DeclGen = struct { | ... | @@ -511,29 +509,29 @@ pub const DeclGen = struct { |
| 511 | .ref_val => { | 509 | .ref_val => { |
| 512 | const elem_value = tv.val.castTag(.ref_val).?.data; | 510 | const elem_value = tv.val.castTag(.ref_val).?.data; |
| 513 | const elem_type = tv.ty.castPointer().?.data; | 511 | const elem_type = tv.ty.castPointer().?.data; |
| 514 | const alloca = fg.?.buildAlloca(try self.getLLVMType(elem_type, src)); | 512 | const alloca = fg.?.buildAlloca(try self.getLLVMType(elem_type)); |
| 515 | _ = fg.?.builder.buildStore(try self.genTypedValue(src, .{ .ty = elem_type, .val = elem_value }, fg), alloca); | 513 | _ = fg.?.builder.buildStore(try self.genTypedValue(.{ .ty = elem_type, .val = elem_value }, fg), alloca); |
| 516 | return alloca; | 514 | return alloca; |
| 517 | }, | 515 | }, |
| 518 | else => return self.fail(src, "TODO implement const of pointer type '{}'", .{tv.ty}), | 516 | else => return self.todo("implement const of pointer type '{}'", .{tv.ty}), |
| 519 | }, | 517 | }, |
| 520 | .Array => { | 518 | .Array => { |
| 521 | if (tv.val.castTag(.bytes)) |payload| { | 519 | if (tv.val.castTag(.bytes)) |payload| { |
| 522 | const zero_sentinel = if (tv.ty.sentinel()) |sentinel| blk: { | 520 | const zero_sentinel = if (tv.ty.sentinel()) |sentinel| blk: { |
| 523 | if (sentinel.tag() == .zero) break :blk true; | 521 | if (sentinel.tag() == .zero) break :blk true; |
| 524 | return self.fail(src, "TODO handle other sentinel values", .{}); | 522 | return self.todo("handle other sentinel values", .{}); |
| 525 | } else false; | 523 | } else false; |
| 526 | | 524 | |
| 527 | return self.context().constString(payload.data.ptr, @intCast(c_uint, payload.data.len), llvm.Bool.fromBool(!zero_sentinel)); | 525 | return self.context().constString(payload.data.ptr, @intCast(c_uint, payload.data.len), llvm.Bool.fromBool(!zero_sentinel)); |
| 528 | } else { | 526 | } else { |
| 529 | return self.fail(src, "TODO handle more array values", .{}); | 527 | return self.todo("handle more array values", .{}); |
| 530 | } | 528 | } |
| 531 | }, | 529 | }, |
| 532 | .Optional => { | 530 | .Optional => { |
| 533 | if (!tv.ty.isPtrLikeOptional()) { | 531 | if (!tv.ty.isPtrLikeOptional()) { |
| 534 | var buf: Type.Payload.ElemType = undefined; | 532 | var buf: Type.Payload.ElemType = undefined; |
| 535 | const child_type = tv.ty.optionalChild(&buf); | 533 | const child_type = tv.ty.optionalChild(&buf); |
| 536 | const llvm_child_type = try self.getLLVMType(child_type, src); | 534 | const llvm_child_type = try self.getLLVMType(child_type); |
| 537 | | 535 | |
| 538 | if (tv.val.tag() == .null_value) { | 536 | if (tv.val.tag() == .null_value) { |
| 539 | var optional_values: [2]*const llvm.Value = .{ | 537 | var optional_values: [2]*const llvm.Value = .{ |
| ... | @@ -543,16 +541,16 @@ pub const DeclGen = struct { | ... | @@ -543,16 +541,16 @@ pub const DeclGen = struct { |
| 543 | return self.context().constStruct(&optional_values, 2, .False); | 541 | return self.context().constStruct(&optional_values, 2, .False); |
| 544 | } else { | 542 | } else { |
| 545 | var optional_values: [2]*const llvm.Value = .{ | 543 | var optional_values: [2]*const llvm.Value = .{ |
| 546 | try self.genTypedValue(src, .{ .ty = child_type, .val = tv.val }, fg), | 544 | try self.genTypedValue(.{ .ty = child_type, .val = tv.val }, fg), |
| 547 | self.context().intType(1).constAllOnes(), | 545 | self.context().intType(1).constAllOnes(), |
| 548 | }; | 546 | }; |
| 549 | return self.context().constStruct(&optional_values, 2, .False); | 547 | return self.context().constStruct(&optional_values, 2, .False); |
| 550 | } | 548 | } |
| 551 | } else { | 549 | } else { |
| 552 | return self.fail(src, "TODO implement const of optional pointer", .{}); | 550 | return self.todo("implement const of optional pointer", .{}); |
| 553 | } | 551 | } |
| 554 | }, | 552 | }, |
| 555 | else => return self.fail(src, "TODO implement const of type '{}'", .{tv.ty}), | 553 | else => return self.todo("implement const of type '{}'", .{tv.ty}), |
| 556 | } | 554 | } |
| 557 | } | 555 | } |
| 558 | | 556 | |
| ... | @@ -609,9 +607,9 @@ pub const FuncGen = struct { | ... | @@ -609,9 +607,9 @@ pub const FuncGen = struct { |
| 609 | self.blocks.deinit(self.gpa()); | 607 | self.blocks.deinit(self.gpa()); |
| 610 | } | 608 | } |
| 611 | | 609 | |
| 612 | fn fail(self: *FuncGen, src: LazySrcLoc, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { | 610 | fn todo(self: *FuncGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { |
| 613 | @setCold(true); | 611 | @setCold(true); |
| 614 | return self.dg.fail(src, format, args); | 612 | return self.dg.todo(format, args); |
| 615 | } | 613 | } |
| 616 | | 614 | |
| 617 | fn llvmModule(self: *FuncGen) *const llvm.Module { | 615 | fn llvmModule(self: *FuncGen) *const llvm.Module { |
| ... | @@ -628,11 +626,11 @@ pub const FuncGen = struct { | ... | @@ -628,11 +626,11 @@ pub const FuncGen = struct { |
| 628 | | 626 | |
| 629 | fn resolveInst(self: *FuncGen, inst: *ir.Inst) !*const llvm.Value { | 627 | fn resolveInst(self: *FuncGen, inst: *ir.Inst) !*const llvm.Value { |
| 630 | if (inst.value()) |val| { | 628 | if (inst.value()) |val| { |
| 631 | return self.dg.genTypedValue(inst.src, .{ .ty = inst.ty, .val = val }, self); | 629 | return self.dg.genTypedValue(.{ .ty = inst.ty, .val = val }, self); |
| 632 | } | 630 | } |
| 633 | if (self.func_inst_table.get(inst)) |value| return value; | 631 | if (self.func_inst_table.get(inst)) |value| return value; |
| 634 | | 632 | |
| 635 | return self.fail(inst.src, "TODO implement global llvm values (or the value is not in the func_inst_table table)", .{}); | 633 | return self.todo("implement global llvm values (or the value is not in the func_inst_table table)", .{}); |
| 636 | } | 634 | } |
| 637 | | 635 | |
| 638 | fn genBody(self: *FuncGen, body: ir.Body) error{ OutOfMemory, CodegenFail }!void { | 636 | fn genBody(self: *FuncGen, body: ir.Body) error{ OutOfMemory, CodegenFail }!void { |
| ... | @@ -673,7 +671,7 @@ pub const FuncGen = struct { | ... | @@ -673,7 +671,7 @@ pub const FuncGen = struct { |
| 673 | // TODO: implement debug info | 671 | // TODO: implement debug info |
| 674 | break :blk null; | 672 | break :blk null; |
| 675 | }, | 673 | }, |
| 676 | else => |tag| return self.fail(inst.src, "TODO implement LLVM codegen for Zir instruction: {}", .{tag}), | 674 | else => |tag| return self.todo("implement TZIR instruction: {}", .{tag}), |
| 677 | }; | 675 | }; |
| 678 | if (opt_value) |val| try self.func_inst_table.putNoClobber(self.gpa(), inst, val); | 676 | if (opt_value) |val| try self.func_inst_table.putNoClobber(self.gpa(), inst, val); |
| 679 | } | 677 | } |
| ... | @@ -689,7 +687,7 @@ pub const FuncGen = struct { | ... | @@ -689,7 +687,7 @@ pub const FuncGen = struct { |
| 689 | unreachable; | 687 | unreachable; |
| 690 | | 688 | |
| 691 | const zig_fn_type = fn_decl.typed_value.most_recent.typed_value.ty; | 689 | const zig_fn_type = fn_decl.typed_value.most_recent.typed_value.ty; |
| 692 | const llvm_fn = try self.dg.resolveLLVMFunction(fn_decl, inst.base.src); | 690 | const llvm_fn = try self.dg.resolveLLVMFunction(fn_decl); |
| 693 | | 691 | |
| 694 | const num_args = inst.args.len; | 692 | const num_args = inst.args.len; |
| 695 | | 693 | |
| ... | @@ -719,7 +717,7 @@ pub const FuncGen = struct { | ... | @@ -719,7 +717,7 @@ pub const FuncGen = struct { |
| 719 | | 717 | |
| 720 | return call; | 718 | return call; |
| 721 | } else { | 719 | } else { |
| 722 | return self.fail(inst.base.src, "TODO implement calling runtime known function pointer LLVM backend", .{}); | 720 | return self.todo("implement calling runtime known function pointer", .{}); |
| 723 | } | 721 | } |
| 724 | } | 722 | } |
| 725 | | 723 | |
| ... | @@ -739,7 +737,7 @@ pub const FuncGen = struct { | ... | @@ -739,7 +737,7 @@ pub const FuncGen = struct { |
| 739 | | 737 | |
| 740 | if (!inst.base.ty.isInt()) | 738 | if (!inst.base.ty.isInt()) |
| 741 | if (inst.base.ty.tag() != .bool) | 739 | if (inst.base.ty.tag() != .bool) |
| 742 | return self.fail(inst.base.src, "TODO implement 'genCmp' for type {}", .{inst.base.ty}); | 740 | return self.todo("implement 'genCmp' for type {}", .{inst.base.ty}); |
| 743 | | 741 | |
| 744 | const is_signed = inst.base.ty.isSignedInt(); | 742 | const is_signed = inst.base.ty.isSignedInt(); |
| 745 | const operation = switch (op) { | 743 | const operation = switch (op) { |
| ... | @@ -779,7 +777,7 @@ pub const FuncGen = struct { | ... | @@ -779,7 +777,7 @@ pub const FuncGen = struct { |
| 779 | // If the block does not return a value, we dont have to create a phi node. | 777 | // If the block does not return a value, we dont have to create a phi node. |
| 780 | if (!inst.base.ty.hasCodeGenBits()) return null; | 778 | if (!inst.base.ty.hasCodeGenBits()) return null; |
| 781 | | 779 | |
| 782 | const phi_node = self.builder.buildPhi(try self.dg.getLLVMType(inst.base.ty, inst.base.src), ""); | 780 | const phi_node = self.builder.buildPhi(try self.dg.getLLVMType(inst.base.ty), ""); |
| 783 | phi_node.addIncoming( | 781 | phi_node.addIncoming( |
| 784 | break_vals.items.ptr, | 782 | break_vals.items.ptr, |
| 785 | break_bbs.items.ptr, | 783 | break_bbs.items.ptr, |
| ... | @@ -897,7 +895,7 @@ pub const FuncGen = struct { | ... | @@ -897,7 +895,7 @@ pub const FuncGen = struct { |
| 897 | const rhs = try self.resolveInst(inst.rhs); | 895 | const rhs = try self.resolveInst(inst.rhs); |
| 898 | | 896 | |
| 899 | if (!inst.base.ty.isInt()) | 897 | if (!inst.base.ty.isInt()) |
| 900 | return self.fail(inst.base.src, "TODO implement 'genAdd' for type {}", .{inst.base.ty}); | 898 | return self.todo("implement 'genAdd' for type {}", .{inst.base.ty}); |
| 901 | | 899 | |
| 902 | return if (inst.base.ty.isSignedInt()) | 900 | return if (inst.base.ty.isSignedInt()) |
| 903 | self.builder.buildNSWAdd(lhs, rhs, "") | 901 | self.builder.buildNSWAdd(lhs, rhs, "") |
| ... | @@ -910,7 +908,7 @@ pub const FuncGen = struct { | ... | @@ -910,7 +908,7 @@ pub const FuncGen = struct { |
| 910 | const rhs = try self.resolveInst(inst.rhs); | 908 | const rhs = try self.resolveInst(inst.rhs); |
| 911 | | 909 | |
| 912 | if (!inst.base.ty.isInt()) | 910 | if (!inst.base.ty.isInt()) |
| 913 | return self.fail(inst.base.src, "TODO implement 'genSub' for type {}", .{inst.base.ty}); | 911 | return self.todo("implement 'genSub' for type {}", .{inst.base.ty}); |
| 914 | | 912 | |
| 915 | return if (inst.base.ty.isSignedInt()) | 913 | return if (inst.base.ty.isSignedInt()) |
| 916 | self.builder.buildNSWSub(lhs, rhs, "") | 914 | self.builder.buildNSWSub(lhs, rhs, "") |
| ... | @@ -924,12 +922,12 @@ pub const FuncGen = struct { | ... | @@ -924,12 +922,12 @@ pub const FuncGen = struct { |
| 924 | const signed = inst.base.ty.isSignedInt(); | 922 | const signed = inst.base.ty.isSignedInt(); |
| 925 | // TODO: Should we use intcast here or just a simple bitcast? | 923 | // TODO: Should we use intcast here or just a simple bitcast? |
| 926 | // LLVM does truncation vs bitcast (+signed extension) in the intcast depending on the sizes | 924 | // LLVM does truncation vs bitcast (+signed extension) in the intcast depending on the sizes |
| 927 | return self.builder.buildIntCast2(val, try self.dg.getLLVMType(inst.base.ty, inst.base.src), llvm.Bool.fromBool(signed), ""); | 925 | return self.builder.buildIntCast2(val, try self.dg.getLLVMType(inst.base.ty), llvm.Bool.fromBool(signed), ""); |
| 928 | } | 926 | } |
| 929 | | 927 | |
| 930 | fn genBitCast(self: *FuncGen, inst: *Inst.UnOp) !?*const llvm.Value { | 928 | fn genBitCast(self: *FuncGen, inst: *Inst.UnOp) !?*const llvm.Value { |
| 931 | const val = try self.resolveInst(inst.operand); | 929 | const val = try self.resolveInst(inst.operand); |
| 932 | const dest_type = try self.dg.getLLVMType(inst.base.ty, inst.base.src); | 930 | const dest_type = try self.dg.getLLVMType(inst.base.ty); |
| 933 | | 931 | |
| 934 | return self.builder.buildBitCast(val, dest_type, ""); | 932 | return self.builder.buildBitCast(val, dest_type, ""); |
| 935 | } | 933 | } |
| ... | @@ -938,7 +936,7 @@ pub const FuncGen = struct { | ... | @@ -938,7 +936,7 @@ pub const FuncGen = struct { |
| 938 | const arg_val = self.args[self.arg_index]; | 936 | const arg_val = self.args[self.arg_index]; |
| 939 | self.arg_index += 1; | 937 | self.arg_index += 1; |
| 940 | | 938 | |
| 941 | const ptr_val = self.buildAlloca(try self.dg.getLLVMType(inst.base.ty, inst.base.src)); | 939 | const ptr_val = self.buildAlloca(try self.dg.getLLVMType(inst.base.ty)); |
| 942 | _ = self.builder.buildStore(arg_val, ptr_val); | 940 | _ = self.builder.buildStore(arg_val, ptr_val); |
| 943 | return self.builder.buildLoad(ptr_val, ""); | 941 | return self.builder.buildLoad(ptr_val, ""); |
| 944 | } | 942 | } |
| ... | @@ -950,7 +948,7 @@ pub const FuncGen = struct { | ... | @@ -950,7 +948,7 @@ pub const FuncGen = struct { |
| 950 | | 948 | |
| 951 | // TODO: figure out a way to get the name of the var decl. | 949 | // TODO: figure out a way to get the name of the var decl. |
| 952 | // TODO: set alignment and volatile | 950 | // TODO: set alignment and volatile |
| 953 | return self.buildAlloca(try self.dg.getLLVMType(pointee_type, inst.base.src)); | 951 | return self.buildAlloca(try self.dg.getLLVMType(pointee_type)); |
| 954 | } | 952 | } |
| 955 | | 953 | |
| 956 | /// Use this instead of builder.buildAlloca, because this function makes sure to | 954 | /// Use this instead of builder.buildAlloca, because this function makes sure to |