| ... | ... | @@ -320,7 +320,7 @@ pub const Function = struct { |
| 320 | 320 | try writer.writeAll("static "); |
| 321 | 321 | try f.object.dg.renderTypeAndName(writer, ty, decl_c_value, .Const, alignment, .Complete); |
| 322 | 322 | try writer.writeAll(" = "); |
| 323 | | try f.object.dg.renderValue(writer, ty, val, .Initializer); |
| 323 | try f.object.dg.renderValue(writer, ty, val, .StaticInitializer); |
| 324 | 324 | try writer.writeAll(";\n "); |
| 325 | 325 | break :result decl_c_value; |
| 326 | 326 | } else CValue{ .constant = inst }; |
| ... | ... | @@ -514,6 +514,7 @@ pub const DeclGen = struct { |
| 514 | 514 | ty: Type, |
| 515 | 515 | val: Value, |
| 516 | 516 | decl_index: Decl.Index, |
| 517 | location: ValueRenderLocation, |
| 517 | 518 | ) error{ OutOfMemory, AnalysisFail }!void { |
| 518 | 519 | const decl = dg.module.declPtr(decl_index); |
| 519 | 520 | assert(decl.has_tv); |
| ... | ... | @@ -527,12 +528,16 @@ pub const DeclGen = struct { |
| 527 | 528 | inline for (.{ .function, .extern_fn }) |tag| |
| 528 | 529 | if (decl.val.castTag(tag)) |func| |
| 529 | 530 | if (func.data.owner_decl != decl_index) |
| 530 | | return dg.renderDeclValue(writer, ty, val, func.data.owner_decl); |
| 531 | return dg.renderDeclValue(writer, ty, val, func.data.owner_decl, location); |
| 531 | 532 | |
| 532 | 533 | if (ty.isSlice()) { |
| 533 | | try writer.writeByte('('); |
| 534 | | try dg.renderTypecast(writer, ty); |
| 535 | | try writer.writeAll("){ .ptr = "); |
| 534 | if (location == .StaticInitializer) { |
| 535 | try writer.writeByte('{'); |
| 536 | } else { |
| 537 | try writer.writeByte('('); |
| 538 | try dg.renderTypecast(writer, ty); |
| 539 | try writer.writeAll("){ .ptr = "); |
| 540 | } |
| 536 | 541 | |
| 537 | 542 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 538 | 543 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Initializer); |
| ... | ... | @@ -542,7 +547,12 @@ pub const DeclGen = struct { |
| 542 | 547 | .data = val.sliceLen(dg.module), |
| 543 | 548 | }; |
| 544 | 549 | const len_val = Value.initPayload(&len_pl.base); |
| 545 | | return writer.print(", .len = {} }}", .{try dg.fmtIntLiteral(Type.usize, len_val)}); |
| 550 | |
| 551 | if (location == .StaticInitializer) { |
| 552 | return writer.print(", {} }}", .{try dg.fmtIntLiteral(Type.usize, len_val)}); |
| 553 | } else { |
| 554 | return writer.print(", .len = {} }}", .{try dg.fmtIntLiteral(Type.usize, len_val)}); |
| 555 | } |
| 546 | 556 | } |
| 547 | 557 | |
| 548 | 558 | // We shouldn't cast C function pointers as this is UB (when you call |
| ... | ... | @@ -564,7 +574,7 @@ pub const DeclGen = struct { |
| 564 | 574 | // that its contents are defined with respect to. |
| 565 | 575 | // |
| 566 | 576 | // Used for .elem_ptr, .field_ptr, .opt_payload_ptr, .eu_payload_ptr |
| 567 | | fn renderParentPtr(dg: *DeclGen, writer: anytype, ptr_val: Value, ptr_ty: Type) error{ OutOfMemory, AnalysisFail }!void { |
| 577 | fn renderParentPtr(dg: *DeclGen, writer: anytype, ptr_val: Value, ptr_ty: Type, location: ValueRenderLocation) error{ OutOfMemory, AnalysisFail }!void { |
| 568 | 578 | if (!ptr_ty.isSlice()) { |
| 569 | 579 | try writer.writeByte('('); |
| 570 | 580 | try dg.renderTypecast(writer, ptr_ty); |
| ... | ... | @@ -579,7 +589,7 @@ pub const DeclGen = struct { |
| 579 | 589 | .variable => ptr_val.castTag(.variable).?.data.owner_decl, |
| 580 | 590 | else => unreachable, |
| 581 | 591 | }; |
| 582 | | try dg.renderDeclValue(writer, ptr_ty, ptr_val, decl_index); |
| 592 | try dg.renderDeclValue(writer, ptr_ty, ptr_val, decl_index, location); |
| 583 | 593 | }, |
| 584 | 594 | .field_ptr => { |
| 585 | 595 | const ptr_info = ptr_ty.ptrInfo(); |
| ... | ... | @@ -617,7 +627,7 @@ pub const DeclGen = struct { |
| 617 | 627 | try writer.writeAll("&(("); |
| 618 | 628 | try dg.renderTypecast(writer, u8_ptr_ty); |
| 619 | 629 | try writer.writeByte(')'); |
| 620 | | try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty); |
| 630 | try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty, location); |
| 621 | 631 | return writer.print(")[{}]", .{try dg.fmtIntLiteral(Type.usize, byte_offset_val)}); |
| 622 | 632 | } else { |
| 623 | 633 | var host_pl = Type.Payload.Bits{ |
| ... | ... | @@ -629,7 +639,7 @@ pub const DeclGen = struct { |
| 629 | 639 | try writer.writeByte('('); |
| 630 | 640 | try dg.renderTypecast(writer, ptr_ty); |
| 631 | 641 | try writer.writeByte(')'); |
| 632 | | return dg.renderParentPtr(writer, field_ptr.container_ptr, host_ty); |
| 642 | return dg.renderParentPtr(writer, field_ptr.container_ptr, host_ty, location); |
| 633 | 643 | }, |
| 634 | 644 | }, |
| 635 | 645 | .Union => switch (container_ty.containerLayout()) { |
| ... | ... | @@ -638,7 +648,7 @@ pub const DeclGen = struct { |
| 638 | 648 | .ty = container_ty.unionFields().values()[index].ty, |
| 639 | 649 | }, |
| 640 | 650 | .Packed => { |
| 641 | | return dg.renderParentPtr(writer, field_ptr.container_ptr, ptr_ty); |
| 651 | return dg.renderParentPtr(writer, field_ptr.container_ptr, ptr_ty, location); |
| 642 | 652 | }, |
| 643 | 653 | }, |
| 644 | 654 | .Pointer => field_info: { |
| ... | ... | @@ -657,7 +667,7 @@ pub const DeclGen = struct { |
| 657 | 667 | try dg.renderType(std.io.null_writer, field_ptr.container_ty, .Complete); |
| 658 | 668 | |
| 659 | 669 | try writer.writeAll("&("); |
| 660 | | try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty); |
| 670 | try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty, location); |
| 661 | 671 | try writer.writeAll(")->"); |
| 662 | 672 | switch (field_ptr.container_ty.tag()) { |
| 663 | 673 | .union_tagged, .union_safety_tagged => try writer.writeAll("payload."), |
| ... | ... | @@ -665,7 +675,7 @@ pub const DeclGen = struct { |
| 665 | 675 | } |
| 666 | 676 | try writer.print("{ }", .{fmtIdent(field_info.name)}); |
| 667 | 677 | } else { |
| 668 | | try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty); |
| 678 | try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty, location); |
| 669 | 679 | } |
| 670 | 680 | }, |
| 671 | 681 | .elem_ptr => { |
| ... | ... | @@ -677,7 +687,7 @@ pub const DeclGen = struct { |
| 677 | 687 | const elem_ptr_ty = Type.initPayload(&elem_ptr_ty_pl.base); |
| 678 | 688 | |
| 679 | 689 | try writer.writeAll("&("); |
| 680 | | try dg.renderParentPtr(writer, elem_ptr.array_ptr, elem_ptr_ty); |
| 690 | try dg.renderParentPtr(writer, elem_ptr.array_ptr, elem_ptr_ty, location); |
| 681 | 691 | try writer.print(")[{d}]", .{elem_ptr.index}); |
| 682 | 692 | }, |
| 683 | 693 | .opt_payload_ptr, .eu_payload_ptr => { |
| ... | ... | @@ -692,7 +702,7 @@ pub const DeclGen = struct { |
| 692 | 702 | try dg.renderType(std.io.null_writer, payload_ptr.container_ty, .Complete); |
| 693 | 703 | |
| 694 | 704 | try writer.writeAll("&("); |
| 695 | | try dg.renderParentPtr(writer, payload_ptr.container_ptr, container_ptr_ty); |
| 705 | try dg.renderParentPtr(writer, payload_ptr.container_ptr, container_ptr_ty, location); |
| 696 | 706 | try writer.writeAll(")->payload"); |
| 697 | 707 | }, |
| 698 | 708 | else => unreachable, |
| ... | ... | @@ -910,7 +920,7 @@ pub const DeclGen = struct { |
| 910 | 920 | .eu_payload_ptr, |
| 911 | 921 | .decl_ref_mut, |
| 912 | 922 | .decl_ref, |
| 913 | | => try dg.renderParentPtr(writer, val, ty), |
| 923 | => try dg.renderParentPtr(writer, val, ty, location), |
| 914 | 924 | else => try writer.print("{}", .{try dg.fmtIntLiteralLoc(ty, val, location)}), |
| 915 | 925 | }, |
| 916 | 926 | .Float => { |
| ... | ... | @@ -1024,7 +1034,7 @@ pub const DeclGen = struct { |
| 1024 | 1034 | }, |
| 1025 | 1035 | .variable => { |
| 1026 | 1036 | const decl = val.castTag(.variable).?.data.owner_decl; |
| 1027 | | return dg.renderDeclValue(writer, ty, val, decl); |
| 1037 | return dg.renderDeclValue(writer, ty, val, decl, location); |
| 1028 | 1038 | }, |
| 1029 | 1039 | .slice => { |
| 1030 | 1040 | if (!location.isInitializer()) { |
| ... | ... | @@ -1061,7 +1071,7 @@ pub const DeclGen = struct { |
| 1061 | 1071 | .eu_payload_ptr, |
| 1062 | 1072 | .decl_ref_mut, |
| 1063 | 1073 | .decl_ref, |
| 1064 | | => try dg.renderParentPtr(writer, val, ty), |
| 1074 | => try dg.renderParentPtr(writer, val, ty, location), |
| 1065 | 1075 | else => unreachable, |
| 1066 | 1076 | }, |
| 1067 | 1077 | .Array, .Vector => { |
| ... | ... | @@ -1255,11 +1265,11 @@ pub const DeclGen = struct { |
| 1255 | 1265 | .Fn => switch (val.tag()) { |
| 1256 | 1266 | .function => { |
| 1257 | 1267 | const decl = val.castTag(.function).?.data.owner_decl; |
| 1258 | | return dg.renderDeclValue(writer, ty, val, decl); |
| 1268 | return dg.renderDeclValue(writer, ty, val, decl, location); |
| 1259 | 1269 | }, |
| 1260 | 1270 | .extern_fn => { |
| 1261 | 1271 | const decl = val.castTag(.extern_fn).?.data.owner_decl; |
| 1262 | | return dg.renderDeclValue(writer, ty, val, decl); |
| 1272 | return dg.renderDeclValue(writer, ty, val, decl, location); |
| 1263 | 1273 | }, |
| 1264 | 1274 | else => unreachable, |
| 1265 | 1275 | }, |
| ... | ... | @@ -2512,6 +2522,9 @@ pub const DeclGen = struct { |
| 2512 | 2522 | try dg.writeCValue(writer, member); |
| 2513 | 2523 | } |
| 2514 | 2524 | |
| 2525 | const IdentHasher = std.crypto.auth.siphash.SipHash128(1, 3); |
| 2526 | const ident_hasher_init: IdentHasher = IdentHasher.init(&[_]u8{0} ** IdentHasher.key_length); |
| 2527 | |
| 2515 | 2528 | fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: Decl.Index, export_index: u32) !void { |
| 2516 | 2529 | const decl = dg.module.declPtr(decl_index); |
| 2517 | 2530 | dg.module.markDeclAlive(decl); |
| ... | ... | @@ -2529,7 +2542,18 @@ pub const DeclGen = struct { |
| 2529 | 2542 | const gpa = dg.gpa; |
| 2530 | 2543 | const name = try decl.getFullyQualifiedName(dg.module); |
| 2531 | 2544 | defer gpa.free(name); |
| 2532 | | return writer.print("{}", .{fmtIdent(name)}); |
| 2545 | |
| 2546 | // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case), expand |
| 2547 | // to 3x the length of its input |
| 2548 | if (name.len > 1365) { |
| 2549 | var hash = ident_hasher_init; |
| 2550 | hash.update(name); |
| 2551 | const ident_hash = hash.finalInt(); |
| 2552 | try writer.writeAll("zig_D_"); |
| 2553 | return std.fmt.formatIntValue(ident_hash, "x", .{}, writer); |
| 2554 | } else { |
| 2555 | return writer.print("{}", .{fmtIdent(name)}); |
| 2556 | } |
| 2533 | 2557 | } |
| 2534 | 2558 | } |
| 2535 | 2559 | |
| ... | ... | @@ -4648,7 +4672,15 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4648 | 4672 | try f.writeCValue(writer, cond, .Other); |
| 4649 | 4673 | try writer.writeAll(") "); |
| 4650 | 4674 | try genBody(f, then_body); |
| 4651 | | try writer.writeAll(" else "); |
| 4675 | |
| 4676 | // TODO: If body ends in goto, elide the else block? |
| 4677 | const needs_else = then_body.len <= 0 or f.air.instructions.items(.tag)[then_body[then_body.len - 1]] != .br; |
| 4678 | if (needs_else) { |
| 4679 | try writer.writeAll(" else "); |
| 4680 | } else { |
| 4681 | try writer.writeByte('\n'); |
| 4682 | } |
| 4683 | |
| 4652 | 4684 | f.value_map.deinit(); |
| 4653 | 4685 | f.value_map = cloned_map.move(); |
| 4654 | 4686 | const free_locals = f.getFreeLocals(); |
| ... | ... | @@ -4661,7 +4693,12 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4661 | 4693 | |
| 4662 | 4694 | try noticeBranchFrees(f, pre_locals_len, inst); |
| 4663 | 4695 | |
| 4664 | | try genBody(f, else_body); |
| 4696 | if (needs_else) { |
| 4697 | try genBody(f, else_body); |
| 4698 | } else { |
| 4699 | try genBodyInner(f, else_body); |
| 4700 | } |
| 4701 | |
| 4665 | 4702 | try f.object.indent_writer.insertNewline(); |
| 4666 | 4703 | |
| 4667 | 4704 | return CValue.none; |