| ... | ... | @@ -351,6 +351,7 @@ pub const Object = struct { |
| 351 | 351 | liveness: Liveness, |
| 352 | 352 | ) !void { |
| 353 | 353 | var dg: DeclGen = .{ |
| 354 | .context = self.context, |
| 354 | 355 | .object = self, |
| 355 | 356 | .module = module, |
| 356 | 357 | .decl = func.owner_decl, |
| ... | ... | @@ -375,15 +376,16 @@ pub const Object = struct { |
| 375 | 376 | bb.deleteBasicBlock(); |
| 376 | 377 | } |
| 377 | 378 | |
| 378 | | const builder = dg.context().createBuilder(); |
| 379 | const builder = dg.context.createBuilder(); |
| 379 | 380 | |
| 380 | | const entry_block = dg.context().appendBasicBlock(llvm_func, "Entry"); |
| 381 | const entry_block = dg.context.appendBasicBlock(llvm_func, "Entry"); |
| 381 | 382 | builder.positionBuilderAtEnd(entry_block); |
| 382 | 383 | |
| 383 | 384 | var fg: FuncGen = .{ |
| 384 | 385 | .gpa = dg.gpa, |
| 385 | 386 | .air = air, |
| 386 | 387 | .liveness = liveness, |
| 388 | .context = dg.context, |
| 387 | 389 | .dg = &dg, |
| 388 | 390 | .builder = builder, |
| 389 | 391 | .args = args, |
| ... | ... | @@ -409,6 +411,7 @@ pub const Object = struct { |
| 409 | 411 | |
| 410 | 412 | pub fn updateDecl(self: *Object, module: *Module, decl: *Module.Decl) !void { |
| 411 | 413 | var dg: DeclGen = .{ |
| 414 | .context = self.context, |
| 412 | 415 | .object = self, |
| 413 | 416 | .module = module, |
| 414 | 417 | .decl = decl, |
| ... | ... | @@ -428,6 +431,7 @@ pub const Object = struct { |
| 428 | 431 | }; |
| 429 | 432 | |
| 430 | 433 | pub const DeclGen = struct { |
| 434 | context: *const llvm.Context, |
| 431 | 435 | object: *Object, |
| 432 | 436 | module: *Module, |
| 433 | 437 | decl: *Module.Decl, |
| ... | ... | @@ -447,10 +451,6 @@ pub const DeclGen = struct { |
| 447 | 451 | return self.object.llvm_module; |
| 448 | 452 | } |
| 449 | 453 | |
| 450 | | fn context(self: *DeclGen) *const llvm.Context { |
| 451 | | return self.object.context; |
| 452 | | } |
| 453 | | |
| 454 | 454 | fn genDecl(self: *DeclGen) !void { |
| 455 | 455 | const decl = self.decl; |
| 456 | 456 | assert(decl.has_tv); |
| ... | ... | @@ -525,13 +525,13 @@ pub const DeclGen = struct { |
| 525 | 525 | fn llvmType(self: *DeclGen, t: Type) error{ OutOfMemory, CodegenFail }!*const llvm.Type { |
| 526 | 526 | log.debug("llvmType for {}", .{t}); |
| 527 | 527 | switch (t.zigTypeTag()) { |
| 528 | | .Void => return self.context().voidType(), |
| 529 | | .NoReturn => return self.context().voidType(), |
| 528 | .Void => return self.context.voidType(), |
| 529 | .NoReturn => return self.context.voidType(), |
| 530 | 530 | .Int => { |
| 531 | 531 | const info = t.intInfo(self.module.getTarget()); |
| 532 | | return self.context().intType(info.bits); |
| 532 | return self.context.intType(info.bits); |
| 533 | 533 | }, |
| 534 | | .Bool => return self.context().intType(1), |
| 534 | .Bool => return self.context.intType(1), |
| 535 | 535 | .Pointer => { |
| 536 | 536 | if (t.isSlice()) { |
| 537 | 537 | return self.todo("implement slices", .{}); |
| ... | ... | @@ -551,13 +551,16 @@ pub const DeclGen = struct { |
| 551 | 551 | |
| 552 | 552 | var optional_types: [2]*const llvm.Type = .{ |
| 553 | 553 | try self.llvmType(child_type), |
| 554 | | self.context().intType(1), |
| 554 | self.context.intType(1), |
| 555 | 555 | }; |
| 556 | | return self.context().structType(&optional_types, 2, .False); |
| 556 | return self.context.structType(&optional_types, 2, .False); |
| 557 | 557 | } else { |
| 558 | 558 | return self.todo("implement optional pointers as actual pointers", .{}); |
| 559 | 559 | } |
| 560 | 560 | }, |
| 561 | .ErrorUnion => { |
| 562 | return self.todo("implement llvmType for error unions", .{}); |
| 563 | }, |
| 561 | 564 | .ComptimeInt => unreachable, |
| 562 | 565 | .ComptimeFloat => unreachable, |
| 563 | 566 | .Type => unreachable, |
| ... | ... | @@ -569,7 +572,6 @@ pub const DeclGen = struct { |
| 569 | 572 | |
| 570 | 573 | .Float, |
| 571 | 574 | .Struct, |
| 572 | | .ErrorUnion, |
| 573 | 575 | .ErrorSet, |
| 574 | 576 | .Enum, |
| 575 | 577 | .Union, |
| ... | ... | @@ -638,7 +640,7 @@ pub const DeclGen = struct { |
| 638 | 640 | return self.todo("handle other sentinel values", .{}); |
| 639 | 641 | } else false; |
| 640 | 642 | |
| 641 | | return self.context().constString(payload.data.ptr, @intCast(c_uint, payload.data.len), llvm.Bool.fromBool(!zero_sentinel)); |
| 643 | return self.context.constString(payload.data.ptr, @intCast(c_uint, payload.data.len), llvm.Bool.fromBool(!zero_sentinel)); |
| 642 | 644 | } else { |
| 643 | 645 | return self.todo("handle more array values", .{}); |
| 644 | 646 | } |
| ... | ... | @@ -652,15 +654,15 @@ pub const DeclGen = struct { |
| 652 | 654 | if (tv.val.tag() == .null_value) { |
| 653 | 655 | var optional_values: [2]*const llvm.Value = .{ |
| 654 | 656 | llvm_child_type.constNull(), |
| 655 | | self.context().intType(1).constNull(), |
| 657 | self.context.intType(1).constNull(), |
| 656 | 658 | }; |
| 657 | | return self.context().constStruct(&optional_values, 2, .False); |
| 659 | return self.context.constStruct(&optional_values, 2, .False); |
| 658 | 660 | } else { |
| 659 | 661 | var optional_values: [2]*const llvm.Value = .{ |
| 660 | 662 | try self.genTypedValue(.{ .ty = child_type, .val = tv.val }, fg), |
| 661 | | self.context().intType(1).constAllOnes(), |
| 663 | self.context.intType(1).constAllOnes(), |
| 662 | 664 | }; |
| 663 | | return self.context().constStruct(&optional_values, 2, .False); |
| 665 | return self.context.constStruct(&optional_values, 2, .False); |
| 664 | 666 | } |
| 665 | 667 | } else { |
| 666 | 668 | return self.todo("implement const of optional pointer", .{}); |
| ... | ... | @@ -674,7 +676,7 @@ pub const DeclGen = struct { |
| 674 | 676 | fn addAttr(self: *DeclGen, val: *const llvm.Value, index: llvm.AttributeIndex, name: []const u8) void { |
| 675 | 677 | const kind_id = llvm.getEnumAttributeKindForName(name.ptr, name.len); |
| 676 | 678 | assert(kind_id != 0); |
| 677 | | const llvm_attr = self.context().createEnumAttribute(kind_id, 0); |
| 679 | const llvm_attr = self.context.createEnumAttribute(kind_id, 0); |
| 678 | 680 | val.addAttributeAtIndex(index, llvm_attr); |
| 679 | 681 | } |
| 680 | 682 | |
| ... | ... | @@ -689,6 +691,7 @@ pub const FuncGen = struct { |
| 689 | 691 | dg: *DeclGen, |
| 690 | 692 | air: Air, |
| 691 | 693 | liveness: Liveness, |
| 694 | context: *const llvm.Context, |
| 692 | 695 | |
| 693 | 696 | builder: *const llvm.Builder, |
| 694 | 697 | |
| ... | ... | @@ -734,10 +737,6 @@ pub const FuncGen = struct { |
| 734 | 737 | return self.dg.object.llvm_module; |
| 735 | 738 | } |
| 736 | 739 | |
| 737 | | fn context(self: *FuncGen) *const llvm.Context { |
| 738 | | return self.dg.object.context; |
| 739 | | } |
| 740 | | |
| 741 | 740 | fn resolveInst(self: *FuncGen, inst: Air.Inst.Ref) !*const llvm.Value { |
| 742 | 741 | if (self.air.value(inst)) |val| { |
| 743 | 742 | return self.dg.genTypedValue(.{ .ty = self.air.typeOf(inst), .val = val }, self); |
| ... | ... | @@ -884,7 +883,7 @@ pub const FuncGen = struct { |
| 884 | 883 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 885 | 884 | const extra = self.air.extraData(Air.Block, ty_pl.payload); |
| 886 | 885 | const body = self.air.extra[extra.end..][0..extra.data.body_len]; |
| 887 | | const parent_bb = self.context().createBasicBlock("Block"); |
| 886 | const parent_bb = self.context.createBasicBlock("Block"); |
| 888 | 887 | |
| 889 | 888 | // 5 breaks to a block seems like a reasonable default. |
| 890 | 889 | var break_bbs = try BreakBasicBlocks.initCapacity(self.gpa, 5); |
| ... | ... | @@ -943,8 +942,8 @@ pub const FuncGen = struct { |
| 943 | 942 | const then_body = self.air.extra[extra.end..][0..extra.data.then_body_len]; |
| 944 | 943 | const else_body = self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; |
| 945 | 944 | |
| 946 | | const then_block = self.context().appendBasicBlock(self.llvm_func, "Then"); |
| 947 | | const else_block = self.context().appendBasicBlock(self.llvm_func, "Else"); |
| 945 | const then_block = self.context.appendBasicBlock(self.llvm_func, "Then"); |
| 946 | const else_block = self.context.appendBasicBlock(self.llvm_func, "Else"); |
| 948 | 947 | { |
| 949 | 948 | const prev_block = self.builder.getInsertBlock(); |
| 950 | 949 | defer self.builder.positionBuilderAtEnd(prev_block); |
| ... | ... | @@ -963,7 +962,7 @@ pub const FuncGen = struct { |
| 963 | 962 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 964 | 963 | const loop = self.air.extraData(Air.Block, ty_pl.payload); |
| 965 | 964 | const body = self.air.extra[loop.end..][0..loop.data.body_len]; |
| 966 | | const loop_block = self.context().appendBasicBlock(self.llvm_func, "Loop"); |
| 965 | const loop_block = self.context.appendBasicBlock(self.llvm_func, "Loop"); |
| 967 | 966 | _ = self.builder.buildBr(loop_block); |
| 968 | 967 | |
| 969 | 968 | self.builder.positionBuilderAtEnd(loop_block); |
| ... | ... | @@ -1119,7 +1118,7 @@ pub const FuncGen = struct { |
| 1119 | 1118 | const operand = try self.resolveInst(un_op); |
| 1120 | 1119 | |
| 1121 | 1120 | if (operand_is_ptr) { |
| 1122 | | const index_type = self.context().intType(32); |
| 1121 | const index_type = self.context.intType(32); |
| 1123 | 1122 | |
| 1124 | 1123 | var indices: [2]*const llvm.Value = .{ |
| 1125 | 1124 | index_type.constNull(), |
| ... | ... | @@ -1151,7 +1150,7 @@ pub const FuncGen = struct { |
| 1151 | 1150 | const operand = try self.resolveInst(ty_op.operand); |
| 1152 | 1151 | |
| 1153 | 1152 | if (operand_is_ptr) { |
| 1154 | | const index_type = self.context().intType(32); |
| 1153 | const index_type = self.context.intType(32); |
| 1155 | 1154 | |
| 1156 | 1155 | var indices: [2]*const llvm.Value = .{ |
| 1157 | 1156 | index_type.constNull(), |