Commit a7b8d011a3

Veikka Tuominen <git@vexu.eu>
2022-11-03 12:43:10
Merge pull request #13420 from jacobly0/c-backend
cbe: enough fixes to bootstrap a compiler with a working c backend
1 parent ee8af8c
Changed files (3)
lib
include
src
codegen
test
stage2
lib/include/zig.h
@@ -66,9 +66,9 @@
 #endif
 
 #if defined(__cplusplus)
-#define zig_extern_c extern "C"
+#define zig_extern extern "C"
 #else
-#define zig_extern_c
+#define zig_extern extern
 #endif
 
 #if zig_has_builtin(debugtrap)
@@ -265,8 +265,8 @@ typedef  int64_t zig_i64;
 #define zig_compiler_rt_abbrev_f80  xf
 #define zig_compiler_rt_abbrev_f128 tf
 
-zig_extern_c void *memcpy (void *zig_restrict, void const *zig_restrict, zig_usize);
-zig_extern_c void *memset (void *, int, zig_usize);
+zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, zig_usize);
+zig_extern void *memset (void *, int, zig_usize);
 
 /* ==================== 8/16/32/64-bit Integer Routines ===================== */
 
@@ -279,24 +279,21 @@ zig_extern_c void *memset (void *, int, zig_usize);
     static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##RhsType rhs) { \
         return lhs operator rhs; \
     }
-#define zig_int_operators(w) \
-    zig_int_operator(u##w, u##w,       and,  &) \
-    zig_int_operator(i##w, i##w,       and,  &) \
-    zig_int_operator(u##w, u##w,        or,  |) \
-    zig_int_operator(i##w, i##w,        or,  |) \
-    zig_int_operator(u##w, u##w,       xor,  ^) \
-    zig_int_operator(i##w, i##w,       xor,  ^) \
-    zig_int_operator(u##w, u8,         shl, <<) \
-    zig_int_operator(i##w, u8,         shl, <<) \
-    zig_int_operator(u##w, u8,         shr, >>) \
-    zig_int_operator(u##w, u##w, div_floor,  /) \
-    zig_int_operator(u##w, u##w,       mod,  %)
-zig_int_operators(8)
-zig_int_operators(16)
-zig_int_operators(32)
-zig_int_operators(64)
-
+#define zig_int_basic_operator(Type, operation, operator) \
+    zig_int_operator(Type, Type, operation, operator)
+#define zig_int_shift_operator(Type, operation, operator) \
+    zig_int_operator(Type,   u8, operation, operator)
 #define zig_int_helpers(w) \
+    zig_int_basic_operator(u##w, and,  &) \
+    zig_int_basic_operator(i##w, and,  &) \
+    zig_int_basic_operator(u##w,  or,  |) \
+    zig_int_basic_operator(i##w,  or,  |) \
+    zig_int_basic_operator(u##w, xor,  ^) \
+    zig_int_basic_operator(i##w, xor,  ^) \
+    zig_int_shift_operator(u##w, shl, <<) \
+    zig_int_shift_operator(i##w, shl, <<) \
+    zig_int_shift_operator(u##w, shr, >>) \
+\
     static inline zig_i##w zig_shr_i##w(zig_i##w lhs, zig_u8 rhs) { \
         zig_i##w sign_mask = lhs < zig_as_i##w(0) ? -zig_as_i##w(1) : zig_as_i##w(0); \
         return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \
@@ -319,10 +316,14 @@ zig_int_operators(64)
         return (val & zig_as_u##w(1) << (bits - zig_as_u8(1))) != 0 \
             ? val | zig_minInt(i##w, bits) : val & zig_maxInt(i##w, bits); \
     } \
+\
+    zig_int_basic_operator(u##w, div_floor, /) \
 \
     static inline zig_i##w zig_div_floor_i##w(zig_i##w lhs, zig_i##w rhs) { \
         return lhs / rhs - (((lhs ^ rhs) & (lhs % rhs)) < zig_as_i##w(0)); \
     } \
+\
+    zig_int_basic_operator(u##w, mod, %) \
 \
     static inline zig_i##w zig_mod_i##w(zig_i##w lhs, zig_i##w rhs) { \
         zig_i##w rem = lhs % rhs; \
@@ -345,7 +346,7 @@ static inline zig_bool zig_addo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_
 #endif
 }
 
-zig_extern_c zig_i32  __addosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
+zig_extern zig_i32  __addosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
 static inline zig_bool zig_addo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
 #if zig_has_builtin(add_overflow)
     zig_i32 full_res;
@@ -371,7 +372,7 @@ static inline zig_bool zig_addo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_
 #endif
 }
 
-zig_extern_c zig_i64  __addodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
+zig_extern zig_i64  __addodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
 static inline zig_bool zig_addo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
 #if zig_has_builtin(add_overflow)
     zig_i64 full_res;
@@ -441,7 +442,7 @@ static inline zig_bool zig_subo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_
 #endif
 }
 
-zig_extern_c zig_i32  __subosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
+zig_extern zig_i32  __subosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
 static inline zig_bool zig_subo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
 #if zig_has_builtin(sub_overflow)
     zig_i32 full_res;
@@ -467,7 +468,7 @@ static inline zig_bool zig_subo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_
 #endif
 }
 
-zig_extern_c zig_i64  __subodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
+zig_extern zig_i64  __subodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
 static inline zig_bool zig_subo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
 #if zig_has_builtin(sub_overflow)
     zig_i64 full_res;
@@ -537,7 +538,7 @@ static inline zig_bool zig_mulo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_
 #endif
 }
 
-zig_extern_c zig_i32  __mulosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
+zig_extern zig_i32  __mulosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow);
 static inline zig_bool zig_mulo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) {
 #if zig_has_builtin(mul_overflow)
     zig_i32 full_res;
@@ -563,7 +564,7 @@ static inline zig_bool zig_mulo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_
 #endif
 }
 
-zig_extern_c zig_i64  __mulodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
+zig_extern zig_i64  __mulodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow);
 static inline zig_bool zig_mulo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) {
 #if zig_has_builtin(mul_overflow)
     zig_i64 full_res;
@@ -1210,7 +1211,7 @@ static inline zig_bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs,
 #endif
 }
 
-zig_extern_c zig_i128  __addoti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
+zig_extern zig_i128  __addoti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
 static inline zig_bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
 #if zig_has_builtin(add_overflow)
     zig_i128 full_res;
@@ -1236,7 +1237,7 @@ static inline zig_bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs,
 #endif
 }
 
-zig_extern_c zig_i128  __suboti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
+zig_extern zig_i128  __suboti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
 static inline zig_bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
 #if zig_has_builtin(sub_overflow)
     zig_i128 full_res;
@@ -1262,7 +1263,7 @@ static inline zig_bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs,
 #endif
 }
 
-zig_extern_c zig_i128  __muloti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
+zig_extern zig_i128  __muloti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow);
 static inline zig_bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) {
 #if zig_has_builtin(mul_overflow)
     zig_i128 full_res;
@@ -1552,7 +1553,7 @@ typedef long double zig_c_longdouble;
 #define zig_as_special_c_longdouble(sign, name, arg, repr) sign __builtin_##name##l(arg)
 
 #define zig_convert_builtin(ResType, operation, ArgType, version) \
-    zig_extern_c zig_##ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
+    zig_extern zig_##ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
         zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(zig_##ArgType);
 zig_convert_builtin(f16,  trunc,  f32,  2)
 zig_convert_builtin(f16,  trunc,  f64,  2)
@@ -1585,7 +1586,7 @@ zig_convert_builtin(f128, extend, f80,  2)
     }
 
 #define zig_float_less_builtin_0(Type, operation) \
-    zig_extern_c zig_i8 zig_expand_concat(zig_expand_concat(__##operation, \
+    zig_extern zig_i8 zig_expand_concat(zig_expand_concat(__##operation, \
         zig_compiler_rt_abbrev_##Type), 2)(zig_##Type, zig_##Type); \
     static inline zig_i8 zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
         return (zig_i8)zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_##Type), 2)(lhs, rhs); \
@@ -1603,7 +1604,7 @@ zig_convert_builtin(f128, extend, f80,  2)
     }
 
 #define zig_float_binary_builtin_0(Type, operation, operator) \
-    zig_extern_c zig_##Type zig_expand_concat(zig_expand_concat(__##operation, \
+    zig_extern zig_##Type zig_expand_concat(zig_expand_concat(__##operation, \
         zig_compiler_rt_abbrev_##Type), 3)(zig_##Type, zig_##Type); \
     static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
         return zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_##Type), 3)(lhs, rhs); \
@@ -1638,24 +1639,24 @@ zig_convert_builtin(f128, extend, f80,  2)
     zig_expand_concat(zig_float_binary_builtin_,  zig_has_##Type)(Type, sub, -) \
     zig_expand_concat(zig_float_binary_builtin_,  zig_has_##Type)(Type, mul, *) \
     zig_expand_concat(zig_float_binary_builtin_,  zig_has_##Type)(Type, div, /) \
-    zig_extern_c zig_##Type zig_libc_name_##Type(sqrt)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(sin)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(cos)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(tan)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(exp)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(exp2)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(log)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(log2)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(log10)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(fabs)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(floor)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(ceil)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(round)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(trunc)(zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(fmod)(zig_##Type, zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(fmin)(zig_##Type, zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(fmax)(zig_##Type, zig_##Type); \
-    zig_extern_c zig_##Type zig_libc_name_##Type(fma)(zig_##Type, zig_##Type, zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(sqrt)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(sin)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(cos)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(tan)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(exp)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(exp2)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(log)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(log2)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(log10)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(fabs)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(floor)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(ceil)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(round)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(trunc)(zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(fmod)(zig_##Type, zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(fmin)(zig_##Type, zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(fmax)(zig_##Type, zig_##Type); \
+    zig_extern zig_##Type zig_libc_name_##Type(fma)(zig_##Type, zig_##Type, zig_##Type); \
 \
     static inline zig_##Type zig_div_trunc_##Type(zig_##Type lhs, zig_##Type rhs) { \
         return zig_libc_name_##Type(trunc)(zig_div_##Type(lhs, rhs)); \
src/codegen/c.zig
@@ -704,9 +704,13 @@ pub const DeclGen = struct {
 
                     try writer.writeByte('{');
                     if (ty.unionTagTypeSafety()) |tag_ty| {
-                        try writer.writeAll(" .tag = ");
-                        try dg.renderValue(writer, tag_ty, val, .Initializer);
-                        try writer.writeAll(", .payload = {");
+                        const layout = ty.unionGetLayout(target);
+                        if (layout.tag_size != 0) {
+                            try writer.writeAll(" .tag = ");
+                            try dg.renderValue(writer, tag_ty, val, .Initializer);
+                            try writer.writeByte(',');
+                        }
+                        try writer.writeAll(" .payload = {");
                     }
                     for (ty.unionFields().values()) |field| {
                         if (!field.ty.hasRuntimeBits()) continue;
@@ -1115,7 +1119,6 @@ pub const DeclGen = struct {
             },
             .Union => {
                 const union_obj = val.castTag(.@"union").?.data;
-                const layout = ty.unionGetLayout(target);
 
                 if (location != .Initializer) {
                     try writer.writeByte('(');
@@ -1125,6 +1128,7 @@ pub const DeclGen = struct {
 
                 try writer.writeByte('{');
                 if (ty.unionTagTypeSafety()) |tag_ty| {
+                    const layout = ty.unionGetLayout(target);
                     if (layout.tag_size != 0) {
                         try writer.writeAll(".tag = ");
                         try dg.renderValue(writer, tag_ty, union_obj.tag, .Initializer);
@@ -2215,7 +2219,7 @@ pub fn genFunc(f: *Function) !void {
 
     const is_global = o.dg.module.decl_exports.contains(f.func.owner_decl);
     const fwd_decl_writer = o.dg.fwd_decl.writer();
-    try fwd_decl_writer.writeAll(if (is_global) "zig_extern_c " else "static ");
+    try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
     try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward);
     try fwd_decl_writer.writeAll(";\n");
 
@@ -2252,9 +2256,10 @@ pub fn genDecl(o: *Object) !void {
         .ty = o.dg.decl.ty,
         .val = o.dg.decl.val,
     };
+    if (!tv.ty.isFnOrHasRuntimeBitsIgnoreComptime()) return;
     if (tv.val.tag() == .extern_fn) {
         const fwd_decl_writer = o.dg.fwd_decl.writer();
-        try fwd_decl_writer.writeAll("zig_extern_c ");
+        try fwd_decl_writer.writeAll("zig_extern ");
         try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward);
         try fwd_decl_writer.writeAll(";\n");
     } else if (tv.val.castTag(.variable)) |var_payload| {
@@ -2268,22 +2273,19 @@ pub fn genDecl(o: *Object) !void {
             .decl = o.dg.decl_index,
         };
 
-        if (is_global) try fwd_decl_writer.writeAll("zig_extern_c ");
+        try fwd_decl_writer.writeAll(if (is_global) "zig_extern " else "static ");
         if (variable.is_threadlocal) try fwd_decl_writer.writeAll("zig_threadlocal ");
         try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete);
         try fwd_decl_writer.writeAll(";\n");
 
-        if (variable.is_extern or variable.init.isUndefDeep()) {
-            return;
-        }
+        if (variable.is_extern) return;
 
         const w = o.writer();
+        if (!is_global) try w.writeAll("static ");
         if (variable.is_threadlocal) try w.writeAll("zig_threadlocal ");
         try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete);
         try w.writeAll(" = ");
-        if (variable.init.tag() != .unreachable_value) {
-            try o.dg.renderValue(w, tv.ty, variable.init, .Initializer);
-        }
+        try o.dg.renderValue(w, tv.ty, variable.init, .Initializer);
         try w.writeByte(';');
         try o.indent_writer.insertNewline();
     } else {
@@ -2319,7 +2321,7 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void {
         .Fn => {
             const is_global = dg.declIsGlobal(tv);
             if (is_global) {
-                try writer.writeAll("zig_extern_c ");
+                try writer.writeAll("zig_extern ");
                 try dg.renderFunctionSignature(writer, .Complete);
                 try dg.fwd_decl.appendSlice(";\n");
             }
@@ -2432,7 +2434,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
             .bool_or,  .bit_or  => try airBinOp(f, inst, "|",  "or",  .None),
             .xor                => try airBinOp(f, inst, "^",  "xor", .None),
             .shr, .shr_exact    => try airBinBuiltinCall(f, inst, "shr", .None),
-            .shl,               => try airBinBuiltinCall(f, inst, "shl", .None),
+            .shl,               => try airBinBuiltinCall(f, inst, "shlw", .Bits),
             .shl_exact          => try airBinOp(f, inst, "<<", "shl", .None),
             .not                => try airNot  (f, inst),
 
@@ -3701,7 +3703,6 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
         const local = try f.allocLocal(inst_ty, .Const);
         try writer.writeAll(" = (");
         try f.renderTypecast(writer, inst_ty);
-
         try writer.writeByte(')');
         try f.writeCValue(writer, operand, .Other);
         try writer.writeAll(";\n");
@@ -3719,6 +3720,17 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue {
     try f.renderTypecast(writer, inst_ty);
     try writer.writeAll("));\n");
 
+    // Ensure padding bits have the expected value.
+    if (inst_ty.isAbiInt()) {
+        try f.writeCValue(writer, local, .Other);
+        try writer.writeAll(" = zig_wrap_");
+        try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty);
+        try writer.writeByte('(');
+        try f.writeCValue(writer, local, .Other);
+        try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits);
+        try writer.writeAll(");\n");
+    }
+
     return local;
 }
 
@@ -5307,7 +5319,6 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
     const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data;
     const union_ty = f.air.typeOfIndex(inst);
     const target = f.object.dg.module.getTarget();
-    const layout = union_ty.unionGetLayout(target);
     const union_obj = union_ty.cast(Type.Payload.Union).?.data;
     const field_name = union_obj.fields.keys()[extra.field_index];
     const payload = try f.resolveInst(extra.init);
@@ -5316,6 +5327,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
     const local = try f.allocLocal(union_ty, .Const);
     try writer.writeAll(" = {");
     if (union_ty.unionTagTypeSafety()) |tag_ty| {
+        const layout = union_ty.unionGetLayout(target);
         if (layout.tag_size != 0) {
             const field_index = tag_ty.enumFieldIndex(field_name).?;
 
test/stage2/cbe.zig
@@ -951,7 +951,7 @@ pub fn addCases(ctx: *TestContext) !void {
     ctx.h("simple header", linux_x64,
         \\export fn start() void{}
     ,
-        \\zig_extern_c zig_void start(zig_void);
+        \\zig_extern zig_void start(zig_void);
         \\
     );
     ctx.h("header with single param function", linux_x64,
@@ -959,7 +959,7 @@ pub fn addCases(ctx: *TestContext) !void {
         \\    _ = a;
         \\}
     ,
-        \\zig_extern_c zig_void start(zig_u8 const a0);
+        \\zig_extern zig_void start(zig_u8 const a0);
         \\
     );
     ctx.h("header with multiple param function", linux_x64,
@@ -967,25 +967,25 @@ pub fn addCases(ctx: *TestContext) !void {
         \\  _ = a; _ = b; _ = c;
         \\}
     ,
-        \\zig_extern_c zig_void start(zig_u8 const a0, zig_u8 const a1, zig_u8 const a2);
+        \\zig_extern zig_void start(zig_u8 const a0, zig_u8 const a1, zig_u8 const a2);
         \\
     );
     ctx.h("header with u32 param function", linux_x64,
         \\export fn start(a: u32) void{ _ = a; }
     ,
-        \\zig_extern_c zig_void start(zig_u32 const a0);
+        \\zig_extern zig_void start(zig_u32 const a0);
         \\
     );
     ctx.h("header with usize param function", linux_x64,
         \\export fn start(a: usize) void{ _ = a; }
     ,
-        \\zig_extern_c zig_void start(zig_usize const a0);
+        \\zig_extern zig_void start(zig_usize const a0);
         \\
     );
     ctx.h("header with bool param function", linux_x64,
         \\export fn start(a: bool) void{_ = a;}
     ,
-        \\zig_extern_c zig_void start(zig_bool const a0);
+        \\zig_extern zig_void start(zig_bool const a0);
         \\
     );
     ctx.h("header with noreturn function", linux_x64,
@@ -993,7 +993,7 @@ pub fn addCases(ctx: *TestContext) !void {
         \\    unreachable;
         \\}
     ,
-        \\zig_extern_c zig_noreturn start(zig_void);
+        \\zig_extern zig_noreturn start(zig_void);
         \\
     );
     ctx.h("header with multiple functions", linux_x64,
@@ -1001,15 +1001,15 @@ pub fn addCases(ctx: *TestContext) !void {
         \\export fn b() void{}
         \\export fn c() void{}
     ,
-        \\zig_extern_c zig_void a(zig_void);
-        \\zig_extern_c zig_void b(zig_void);
-        \\zig_extern_c zig_void c(zig_void);
+        \\zig_extern zig_void a(zig_void);
+        \\zig_extern zig_void b(zig_void);
+        \\zig_extern zig_void c(zig_void);
         \\
     );
     ctx.h("header with multiple includes", linux_x64,
         \\export fn start(a: u32, b: usize) void{ _ = a; _ = b; }
     ,
-        \\zig_extern_c zig_void start(zig_u32 const a0, zig_usize const a1);
+        \\zig_extern zig_void start(zig_u32 const a0, zig_usize const a1);
         \\
     );
 }