| ... | ... | @@ -498,21 +498,21 @@ pub const Object = struct { |
| 498 | 498 | ) !void { |
| 499 | 499 | // If the module does not already have the function, we ignore this function call |
| 500 | 500 | // because we call `updateDeclExports` at the end of `updateFunc` and `updateDecl`. |
| 501 | | const llvm_fn = self.decl_map.get(decl) orelse return; |
| 502 | | const is_extern = decl.val.tag() == .extern_fn; |
| 501 | const llvm_global = self.decl_map.get(decl) orelse return; |
| 502 | const is_extern = decl.isExtern(); |
| 503 | 503 | if (is_extern) { |
| 504 | | llvm_fn.setValueName(decl.name); |
| 505 | | llvm_fn.setUnnamedAddr(.False); |
| 506 | | llvm_fn.setLinkage(.External); |
| 504 | llvm_global.setValueName(decl.name); |
| 505 | llvm_global.setUnnamedAddr(.False); |
| 506 | llvm_global.setLinkage(.External); |
| 507 | 507 | } else if (exports.len != 0) { |
| 508 | 508 | const exp_name = exports[0].options.name; |
| 509 | | llvm_fn.setValueName2(exp_name.ptr, exp_name.len); |
| 510 | | llvm_fn.setUnnamedAddr(.False); |
| 509 | llvm_global.setValueName2(exp_name.ptr, exp_name.len); |
| 510 | llvm_global.setUnnamedAddr(.False); |
| 511 | 511 | switch (exports[0].options.linkage) { |
| 512 | 512 | .Internal => unreachable, |
| 513 | | .Strong => llvm_fn.setLinkage(.External), |
| 514 | | .Weak => llvm_fn.setLinkage(.WeakODR), |
| 515 | | .LinkOnce => llvm_fn.setLinkage(.LinkOnceODR), |
| 513 | .Strong => llvm_global.setLinkage(.External), |
| 514 | .Weak => llvm_global.setLinkage(.WeakODR), |
| 515 | .LinkOnce => llvm_global.setLinkage(.LinkOnceODR), |
| 516 | 516 | } |
| 517 | 517 | // If a Decl is exported more than one time (which is rare), |
| 518 | 518 | // we add aliases for all but the first export. |
| ... | ... | @@ -525,9 +525,9 @@ pub const Object = struct { |
| 525 | 525 | defer module.gpa.free(exp_name_z); |
| 526 | 526 | |
| 527 | 527 | if (self.llvm_module.getNamedGlobalAlias(exp_name_z.ptr, exp_name_z.len)) |alias| { |
| 528 | | alias.setAliasee(llvm_fn); |
| 528 | alias.setAliasee(llvm_global); |
| 529 | 529 | } else { |
| 530 | | const alias = self.llvm_module.addAlias(llvm_fn.typeOf(), llvm_fn, exp_name_z); |
| 530 | const alias = self.llvm_module.addAlias(llvm_global.typeOf(), llvm_global, exp_name_z); |
| 531 | 531 | switch (exp.options.linkage) { |
| 532 | 532 | .Internal => alias.setLinkage(.Internal), |
| 533 | 533 | .Strong => alias.setLinkage(.External), |
| ... | ... | @@ -545,9 +545,9 @@ pub const Object = struct { |
| 545 | 545 | } else { |
| 546 | 546 | const fqn = try decl.getFullyQualifiedName(module.gpa); |
| 547 | 547 | defer module.gpa.free(fqn); |
| 548 | | llvm_fn.setValueName2(fqn.ptr, fqn.len); |
| 549 | | llvm_fn.setLinkage(.Internal); |
| 550 | | llvm_fn.setUnnamedAddr(.True); |
| 548 | llvm_global.setValueName2(fqn.ptr, fqn.len); |
| 549 | llvm_global.setLinkage(.Internal); |
| 550 | llvm_global.setUnnamedAddr(.True); |
| 551 | 551 | } |
| 552 | 552 | } |
| 553 | 553 | |
| ... | ... | @@ -598,9 +598,10 @@ pub const DeclGen = struct { |
| 598 | 598 | global.setGlobalConstant(.True); |
| 599 | 599 | break :init_val decl.val; |
| 600 | 600 | }; |
| 601 | | |
| 602 | | const llvm_init = try self.genTypedValue(.{ .ty = decl.ty, .val = init_val }); |
| 603 | | global.setInitializer(llvm_init); |
| 601 | if (init_val.tag() != .unreachable_value) { |
| 602 | const llvm_init = try self.genTypedValue(.{ .ty = decl.ty, .val = init_val }); |
| 603 | global.setInitializer(llvm_init); |
| 604 | } |
| 604 | 605 | } |
| 605 | 606 | } |
| 606 | 607 | |
| ... | ... | @@ -704,6 +705,13 @@ pub const DeclGen = struct { |
| 704 | 705 | const llvm_addrspace = dg.llvmAddressSpace(decl.@"addrspace"); |
| 705 | 706 | const llvm_global = dg.object.llvm_module.addGlobalInAddressSpace(llvm_type, fqn, llvm_addrspace); |
| 706 | 707 | gop.value_ptr.* = llvm_global; |
| 708 | |
| 709 | const is_extern = decl.val.tag() == .unreachable_value; |
| 710 | if (!is_extern) { |
| 711 | llvm_global.setLinkage(.Internal); |
| 712 | llvm_global.setUnnamedAddr(.True); |
| 713 | } |
| 714 | |
| 707 | 715 | return llvm_global; |
| 708 | 716 | } |
| 709 | 717 | |
| ... | ... | @@ -2431,10 +2439,33 @@ pub const FuncGen = struct { |
| 2431 | 2439 | } |
| 2432 | 2440 | |
| 2433 | 2441 | fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| 2434 | | if (self.liveness.isUnused(inst)) |
| 2435 | | return null; |
| 2442 | if (self.liveness.isUnused(inst)) return null; |
| 2443 | |
| 2444 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2445 | const payload_ty = self.air.typeOf(ty_op.operand); |
| 2446 | const operand = try self.resolveInst(ty_op.operand); |
| 2447 | if (!payload_ty.hasCodeGenBits()) { |
| 2448 | return operand; |
| 2449 | } |
| 2450 | const inst_ty = self.air.typeOfIndex(inst); |
| 2451 | const ok_err_code = self.context.intType(16).constNull(); |
| 2452 | const err_un_llvm_ty = try self.dg.llvmType(inst_ty); |
| 2453 | if (isByRef(inst_ty)) { |
| 2454 | const result_ptr = self.buildAlloca(err_un_llvm_ty); |
| 2455 | const err_ptr = self.builder.buildStructGEP(result_ptr, 0, ""); |
| 2456 | _ = self.builder.buildStore(ok_err_code, err_ptr); |
| 2457 | const payload_ptr = self.builder.buildStructGEP(result_ptr, 1, ""); |
| 2458 | var ptr_ty_payload: Type.Payload.ElemType = .{ |
| 2459 | .base = .{ .tag = .single_mut_pointer }, |
| 2460 | .data = payload_ty, |
| 2461 | }; |
| 2462 | const payload_ptr_ty = Type.initPayload(&ptr_ty_payload.base); |
| 2463 | self.store(payload_ptr, payload_ptr_ty, operand, .NotAtomic); |
| 2464 | return result_ptr; |
| 2465 | } |
| 2436 | 2466 | |
| 2437 | | return self.todo("implement llvm codegen for 'airWrapErrUnionPayload'", .{}); |
| 2467 | const partial = self.builder.buildInsertValue(err_un_llvm_ty.getUndef(), ok_err_code, 0, ""); |
| 2468 | return self.builder.buildInsertValue(partial, operand, 1, ""); |
| 2438 | 2469 | } |
| 2439 | 2470 | |
| 2440 | 2471 | fn airWrapErrUnionErr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |