| ... | ... | @@ -389,7 +389,7 @@ pub const DeclGen = struct { |
| 389 | 389 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Other); |
| 390 | 390 | try writer.writeAll(", "); |
| 391 | 391 | try writer.print("{d}", .{val.sliceLen(dg.module)}); |
| 392 | | try writer.writeAll("}"); |
| 392 | try writer.writeByte('}'); |
| 393 | 393 | return; |
| 394 | 394 | } |
| 395 | 395 | |
| ... | ... | @@ -563,6 +563,7 @@ pub const DeclGen = struct { |
| 563 | 563 | switch (ty.zigTypeTag()) { |
| 564 | 564 | // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang) |
| 565 | 565 | // with 'error: expected expression' (including when built with 'zig cc') |
| 566 | .Bool => return writer.writeAll("false"), |
| 566 | 567 | .Int => { |
| 567 | 568 | const c_bits = toCIntBits(ty.intInfo(dg.module.getTarget()).bits) orelse |
| 568 | 569 | return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); |
| ... | ... | @@ -583,14 +584,19 @@ pub const DeclGen = struct { |
| 583 | 584 | } |
| 584 | 585 | }, |
| 585 | 586 | .Pointer => switch (dg.module.getTarget().cpu.arch.ptrBitWidth()) { |
| 586 | | 32 => return writer.writeAll("(void *)0xaaaaaaaa"), |
| 587 | | 64 => return writer.writeAll("(void *)0xaaaaaaaaaaaaaaaa"), |
| 587 | 32 => return writer.writeAll("(void *)0xaaaaaaaau"), |
| 588 | 64 => return writer.writeAll("(void *)0xaaaaaaaaaaaaaaaau"), |
| 588 | 589 | else => unreachable, |
| 589 | 590 | }, |
| 590 | 591 | .Struct, .ErrorUnion => { |
| 591 | 592 | try writer.writeByte('('); |
| 592 | 593 | try dg.renderTypecast(writer, ty); |
| 593 | | return writer.writeAll("){0xaa}"); |
| 594 | return writer.writeAll("){0xaau}"); |
| 595 | }, |
| 596 | .Array => { |
| 597 | try writer.writeByte('{'); |
| 598 | try dg.renderValue(writer, ty.childType(), val, location); |
| 599 | return writer.writeByte('}'); |
| 594 | 600 | }, |
| 595 | 601 | else => { |
| 596 | 602 | // This should lower to 0xaa bytes in safe modes, and for unsafe modes should |
| ... | ... | @@ -652,7 +658,7 @@ pub const DeclGen = struct { |
| 652 | 658 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, location); |
| 653 | 659 | try writer.writeAll(", "); |
| 654 | 660 | try dg.renderValue(writer, Type.usize, slice.len, location); |
| 655 | | try writer.writeAll("}"); |
| 661 | try writer.writeByte('}'); |
| 656 | 662 | }, |
| 657 | 663 | .function => { |
| 658 | 664 | const func = val.castTag(.function).?.data; |
| ... | ... | @@ -684,6 +690,8 @@ pub const DeclGen = struct { |
| 684 | 690 | const ai = ty.arrayInfo(); |
| 685 | 691 | if (ai.sentinel) |s| { |
| 686 | 692 | try dg.renderValue(writer, ai.elem_type, s, location); |
| 693 | } else { |
| 694 | try writer.writeByte('0'); |
| 687 | 695 | } |
| 688 | 696 | try writer.writeByte('}'); |
| 689 | 697 | }, |
| ... | ... | @@ -703,12 +711,12 @@ pub const DeclGen = struct { |
| 703 | 711 | const ai = ty.arrayInfo(); |
| 704 | 712 | var index: usize = 0; |
| 705 | 713 | while (index < ai.len) : (index += 1) { |
| 706 | | if (index != 0) try writer.writeAll(","); |
| 714 | if (index != 0) try writer.writeByte(','); |
| 707 | 715 | const elem_val = try val.elemValue(dg.module, arena_allocator, index); |
| 708 | 716 | try dg.renderValue(writer, ai.elem_type, elem_val, .Other); |
| 709 | 717 | } |
| 710 | 718 | if (ai.sentinel) |s| { |
| 711 | | if (index != 0) try writer.writeAll(","); |
| 719 | if (index != 0) try writer.writeByte(','); |
| 712 | 720 | try dg.renderValue(writer, ai.elem_type, s, .Other); |
| 713 | 721 | } |
| 714 | 722 | try writer.writeByte('}'); |
| ... | ... | @@ -751,7 +759,7 @@ pub const DeclGen = struct { |
| 751 | 759 | else => { |
| 752 | 760 | // In this case we are rendering an error union which has a |
| 753 | 761 | // 0 bits payload. |
| 754 | | return writer.writeAll("0"); |
| 762 | return writer.writeByte('0'); |
| 755 | 763 | }, |
| 756 | 764 | } |
| 757 | 765 | }, |
| ... | ... | @@ -827,27 +835,29 @@ pub const DeclGen = struct { |
| 827 | 835 | .Struct => { |
| 828 | 836 | const field_vals = val.castTag(.aggregate).?.data; |
| 829 | 837 | |
| 830 | | try writer.writeAll("("); |
| 838 | try writer.writeByte('('); |
| 831 | 839 | try dg.renderTypecast(writer, ty); |
| 832 | 840 | try writer.writeAll("){"); |
| 833 | 841 | |
| 834 | | var i: usize = 0; |
| 842 | var empty = true; |
| 835 | 843 | for (field_vals) |field_val, field_index| { |
| 836 | 844 | const field_ty = ty.structFieldType(field_index); |
| 837 | 845 | if (!field_ty.hasRuntimeBits()) continue; |
| 838 | 846 | |
| 839 | | if (i != 0) try writer.writeAll(","); |
| 847 | if (!empty) try writer.writeByte(','); |
| 840 | 848 | try dg.renderValue(writer, field_ty, field_val, location); |
| 841 | | i += 1; |
| 849 | |
| 850 | empty = false; |
| 842 | 851 | } |
| 852 | if (empty) try writer.writeByte('0'); |
| 843 | 853 | |
| 844 | | try writer.writeAll("}"); |
| 854 | try writer.writeByte('}'); |
| 845 | 855 | }, |
| 846 | 856 | .Union => { |
| 847 | 857 | const union_obj = val.castTag(.@"union").?.data; |
| 848 | 858 | const layout = ty.unionGetLayout(target); |
| 849 | 859 | |
| 850 | | try writer.writeAll("("); |
| 860 | try writer.writeByte('('); |
| 851 | 861 | try dg.renderTypecast(writer, ty); |
| 852 | 862 | try writer.writeAll("){"); |
| 853 | 863 | |
| ... | ... | @@ -866,11 +876,11 @@ pub const DeclGen = struct { |
| 866 | 876 | if (field_ty.hasRuntimeBits()) { |
| 867 | 877 | try writer.print(".{ } = ", .{fmtIdent(field_name)}); |
| 868 | 878 | try dg.renderValue(writer, field_ty, union_obj.val, location); |
| 869 | | } |
| 879 | } else try writer.writeByte('0'); |
| 870 | 880 | if (ty.unionTagTypeSafety()) |_| { |
| 871 | | try writer.writeAll("}"); |
| 881 | try writer.writeByte('}'); |
| 872 | 882 | } |
| 873 | | try writer.writeAll("}"); |
| 883 | try writer.writeByte('}'); |
| 874 | 884 | }, |
| 875 | 885 | |
| 876 | 886 | .ComptimeInt => unreachable, |
| ... | ... | @@ -913,9 +923,9 @@ pub const DeclGen = struct { |
| 913 | 923 | } else { |
| 914 | 924 | try w.writeAll("void"); |
| 915 | 925 | } |
| 916 | | try w.writeAll(" "); |
| 926 | try w.writeByte(' '); |
| 917 | 927 | try dg.renderDeclName(w, dg.decl_index); |
| 918 | | try w.writeAll("("); |
| 928 | try w.writeByte('('); |
| 919 | 929 | |
| 920 | 930 | var params_written: usize = 0; |
| 921 | 931 | for (fn_info.param_types) |param_type, index| { |
| ... | ... | @@ -1038,6 +1048,7 @@ pub const DeclGen = struct { |
| 1038 | 1048 | try buffer.appendSlice("typedef struct {\n"); |
| 1039 | 1049 | { |
| 1040 | 1050 | var it = struct_obj.fields.iterator(); |
| 1051 | var empty = true; |
| 1041 | 1052 | while (it.next()) |entry| { |
| 1042 | 1053 | const field_ty = entry.value_ptr.ty; |
| 1043 | 1054 | if (!field_ty.hasRuntimeBits()) continue; |
| ... | ... | @@ -1047,7 +1058,10 @@ pub const DeclGen = struct { |
| 1047 | 1058 | try buffer.append(' '); |
| 1048 | 1059 | try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment); |
| 1049 | 1060 | try buffer.appendSlice(";\n"); |
| 1061 | |
| 1062 | empty = false; |
| 1050 | 1063 | } |
| 1064 | if (empty) try buffer.appendSlice(" char empty_struct;\n"); |
| 1051 | 1065 | } |
| 1052 | 1066 | try buffer.appendSlice("} "); |
| 1053 | 1067 | |
| ... | ... | @@ -1076,7 +1090,9 @@ pub const DeclGen = struct { |
| 1076 | 1090 | |
| 1077 | 1091 | try buffer.appendSlice("typedef struct {\n"); |
| 1078 | 1092 | { |
| 1093 | var empty = true; |
| 1079 | 1094 | for (tuple.types) |field_ty, i| { |
| 1095 | if (!field_ty.hasRuntimeBits()) continue; |
| 1080 | 1096 | const val = tuple.values[i]; |
| 1081 | 1097 | if (val.tag() != .unreachable_value) continue; |
| 1082 | 1098 | |
| ... | ... | @@ -1087,7 +1103,10 @@ pub const DeclGen = struct { |
| 1087 | 1103 | try buffer.append(' '); |
| 1088 | 1104 | try dg.renderTypeAndName(writer, field_ty, .{ .bytes = name.items }, .Mut, 0); |
| 1089 | 1105 | try buffer.appendSlice(";\n"); |
| 1106 | |
| 1107 | empty = false; |
| 1090 | 1108 | } |
| 1109 | if (empty) try buffer.appendSlice(" char empty_tuple;\n"); |
| 1091 | 1110 | } |
| 1092 | 1111 | try buffer.appendSlice("} "); |
| 1093 | 1112 | |
| ... | ... | @@ -1129,17 +1148,23 @@ pub const DeclGen = struct { |
| 1129 | 1148 | } |
| 1130 | 1149 | |
| 1131 | 1150 | try buffer.appendSlice("union {\n"); |
| 1151 | const fields = t.unionFields(); |
| 1132 | 1152 | { |
| 1133 | | var it = t.unionFields().iterator(); |
| 1153 | var it = fields.iterator(); |
| 1154 | var empty = true; |
| 1134 | 1155 | while (it.next()) |entry| { |
| 1135 | 1156 | const field_ty = entry.value_ptr.ty; |
| 1136 | 1157 | if (!field_ty.hasRuntimeBits()) continue; |
| 1158 | |
| 1137 | 1159 | const alignment = entry.value_ptr.abi_align; |
| 1138 | 1160 | const name: CValue = .{ .identifier = entry.key_ptr.* }; |
| 1139 | 1161 | try buffer.append(' '); |
| 1140 | 1162 | try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment); |
| 1141 | 1163 | try buffer.appendSlice(";\n"); |
| 1164 | |
| 1165 | empty = false; |
| 1142 | 1166 | } |
| 1167 | if (empty) try buffer.appendSlice(" char empty_union;\n"); |
| 1143 | 1168 | } |
| 1144 | 1169 | try buffer.appendSlice("} "); |
| 1145 | 1170 | |
| ... | ... | @@ -1725,7 +1750,7 @@ pub fn genDecl(o: *Object) !void { |
| 1725 | 1750 | if (variable.init.tag() != .unreachable_value) { |
| 1726 | 1751 | try o.dg.renderValue(w, tv.ty, variable.init, .Other); |
| 1727 | 1752 | } |
| 1728 | | try w.writeAll(";"); |
| 1753 | try w.writeByte(';'); |
| 1729 | 1754 | try o.indent_writer.insertNewline(); |
| 1730 | 1755 | } else { |
| 1731 | 1756 | const writer = o.writer(); |
| ... | ... | @@ -2035,7 +2060,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 2035 | 2060 | } |
| 2036 | 2061 | |
| 2037 | 2062 | f.object.indent_writer.popIndent(); |
| 2038 | | try writer.writeAll("}"); |
| 2063 | try writer.writeByte('}'); |
| 2039 | 2064 | } |
| 2040 | 2065 | |
| 2041 | 2066 | fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue { |
| ... | ... | @@ -2154,7 +2179,7 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2154 | 2179 | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); |
| 2155 | 2180 | try writer.writeAll(" = "); |
| 2156 | 2181 | try f.writeCValue(writer, array); |
| 2157 | | try writer.writeAll("["); |
| 2182 | try writer.writeByte('['); |
| 2158 | 2183 | try f.writeCValue(writer, index); |
| 2159 | 2184 | try writer.writeAll("];\n"); |
| 2160 | 2185 | return local; |
| ... | ... | @@ -2214,7 +2239,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2214 | 2239 | if (is_array) { |
| 2215 | 2240 | // Insert a memcpy to initialize this array. The source operand is always a pointer |
| 2216 | 2241 | // and thus we only need to know size/type information from the local type/dest. |
| 2217 | | try writer.writeAll(";"); |
| 2242 | try writer.writeByte(';'); |
| 2218 | 2243 | try f.object.indent_writer.insertNewline(); |
| 2219 | 2244 | try writer.writeAll("memcpy("); |
| 2220 | 2245 | try f.writeCValue(writer, local); |
| ... | ... | @@ -2278,7 +2303,7 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2278 | 2303 | const local = try f.allocLocal(inst_ty, .Const); |
| 2279 | 2304 | try writer.writeAll(" = ("); |
| 2280 | 2305 | try f.renderTypecast(writer, inst_ty); |
| 2281 | | try writer.writeAll(")"); |
| 2306 | try writer.writeByte(')'); |
| 2282 | 2307 | try f.writeCValue(writer, operand); |
| 2283 | 2308 | try writer.writeAll(";\n"); |
| 2284 | 2309 | return local; |
| ... | ... | @@ -2381,7 +2406,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2381 | 2406 | const new_local = try f.allocLocal(rhs_type, .Const); |
| 2382 | 2407 | try writer.writeAll(" = "); |
| 2383 | 2408 | try f.writeCValue(writer, src_val); |
| 2384 | | try writer.writeAll(";"); |
| 2409 | try writer.writeByte(';'); |
| 2385 | 2410 | try f.object.indent_writer.insertNewline(); |
| 2386 | 2411 | |
| 2387 | 2412 | break :blk new_local; |
| ... | ... | @@ -2605,7 +2630,7 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8) !CV |
| 2605 | 2630 | const max = intMax(scalar_ty, target, &max_buf); |
| 2606 | 2631 | |
| 2607 | 2632 | const ret = try f.allocLocal(inst_ty, .Mut); |
| 2608 | | try w.writeAll(";"); |
| 2633 | try w.writeByte(';'); |
| 2609 | 2634 | try f.object.indent_writer.insertNewline(); |
| 2610 | 2635 | try f.writeCValue(w, ret); |
| 2611 | 2636 | |
| ... | ... | @@ -2654,10 +2679,7 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2654 | 2679 | const local = try f.allocLocal(inst_ty, .Const); |
| 2655 | 2680 | |
| 2656 | 2681 | try writer.writeAll(" = "); |
| 2657 | | if (inst_ty.zigTypeTag() == .Bool) |
| 2658 | | try writer.writeAll("!") |
| 2659 | | else |
| 2660 | | try writer.writeAll("~"); |
| 2682 | try writer.writeByte(if (inst_ty.tag() == .bool) '!' else '~'); |
| 2661 | 2683 | try f.writeCValue(writer, op); |
| 2662 | 2684 | try writer.writeAll(";\n"); |
| 2663 | 2685 | |
| ... | ... | @@ -2868,7 +2890,7 @@ fn airCall( |
| 2868 | 2890 | try f.writeCValue(writer, callee); |
| 2869 | 2891 | } |
| 2870 | 2892 | |
| 2871 | | try writer.writeAll("("); |
| 2893 | try writer.writeByte('('); |
| 2872 | 2894 | var args_written: usize = 0; |
| 2873 | 2895 | for (args) |arg| { |
| 2874 | 2896 | const ty = f.air.typeOf(arg); |
| ... | ... | @@ -2992,7 +3014,7 @@ fn lowerTry( |
| 2992 | 3014 | try writer.writeAll("if("); |
| 2993 | 3015 | } |
| 2994 | 3016 | try f.writeCValue(writer, err_union); |
| 2995 | | try writer.writeAll(")"); |
| 3017 | try writer.writeByte(')'); |
| 2996 | 3018 | break :err; |
| 2997 | 3019 | } |
| 2998 | 3020 | if (operand_is_ptr or isByRef(err_union_ty)) { |
| ... | ... | @@ -3066,7 +3088,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3066 | 3088 | try writer.writeAll(" = ("); |
| 3067 | 3089 | try f.renderTypecast(writer, inst_ty); |
| 3068 | 3090 | |
| 3069 | | try writer.writeAll(")"); |
| 3091 | try writer.writeByte(')'); |
| 3070 | 3092 | try f.writeCValue(writer, operand); |
| 3071 | 3093 | try writer.writeAll(";\n"); |
| 3072 | 3094 | return local; |
| ... | ... | @@ -3797,7 +3819,7 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3797 | 3819 | |
| 3798 | 3820 | try writer.writeAll(" = ("); |
| 3799 | 3821 | try f.renderTypecast(writer, inst_ty); |
| 3800 | | try writer.writeAll(")"); |
| 3822 | try writer.writeByte(')'); |
| 3801 | 3823 | try f.writeCValue(writer, operand); |
| 3802 | 3824 | try writer.writeAll(";\n"); |
| 3803 | 3825 | return local; |
| ... | ... | @@ -4212,7 +4234,7 @@ fn airNeg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4212 | 4234 | const inst_ty = f.air.typeOfIndex(inst); |
| 4213 | 4235 | const operand = try f.resolveInst(un_op); |
| 4214 | 4236 | const local = try f.allocLocal(inst_ty, .Const); |
| 4215 | | try writer.writeAll("-"); |
| 4237 | try writer.writeByte('-'); |
| 4216 | 4238 | try f.writeCValue(writer, operand); |
| 4217 | 4239 | try writer.writeAll(";\n"); |
| 4218 | 4240 | return local; |