Commit e2fe1907ec

Andrew Kelley <andrew@ziglang.org>
2023-04-13 06:03:36
add c_char type
closes #875
1 parent 856a9c2
lib/std/zig/primitives.zig
@@ -11,6 +11,7 @@ pub const names = std.ComptimeStringMap(void, .{
     .{"c_long"},
     .{"c_longdouble"},
     .{"c_longlong"},
+    .{"c_char"},
     .{"c_short"},
     .{"c_uint"},
     .{"c_ulong"},
lib/std/start.zig
@@ -512,7 +512,7 @@ fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 {
     return initEventLoopAndCallMain();
 }
 
-fn main(c_argc: c_int, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) callconv(.C) c_int {
+fn main(c_argc: c_int, c_argv: [*][*:0]c_char, c_envp: [*:null]?[*:0]c_char) callconv(.C) c_int {
     var env_count: usize = 0;
     while (c_envp[env_count] != null) : (env_count += 1) {}
     const envp = @ptrCast([*][*:0]u8, c_envp)[0..env_count];
@@ -527,7 +527,7 @@ fn main(c_argc: c_int, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) callconv(.C
     return @call(.always_inline, callMainWithArgs, .{ @intCast(usize, c_argc), @ptrCast([*][*:0]u8, c_argv), envp });
 }
 
-fn mainWithoutEnv(c_argc: c_int, c_argv: [*][*:0]u8) callconv(.C) c_int {
+fn mainWithoutEnv(c_argc: c_int, c_argv: [*][*:0]c_char) callconv(.C) c_int {
     std.os.argv = @ptrCast([*][*:0]u8, c_argv)[0..@intCast(usize, c_argc)];
     return @call(.always_inline, callMain, .{});
 }
lib/std/target.zig
@@ -1905,6 +1905,7 @@ pub const Target = struct {
     }
 
     pub const CType = enum {
+        char,
         short,
         ushort,
         int,
@@ -1920,6 +1921,7 @@ pub const Target = struct {
 
     pub fn c_type_byte_size(t: Target, c_type: CType) u16 {
         return switch (c_type) {
+            .char,
             .short,
             .ushort,
             .int,
@@ -1948,21 +1950,25 @@ pub const Target = struct {
         switch (target.os.tag) {
             .freestanding, .other => switch (target.cpu.arch) {
                 .msp430 => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort, .int, .uint => return 16,
                     .float, .long, .ulong => return 32,
                     .longlong, .ulonglong, .double, .longdouble => return 64,
                 },
                 .avr => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort, .int, .uint => return 16,
                     .long, .ulong, .float, .double, .longdouble => return 32,
                     .longlong, .ulonglong => return 64,
                 },
                 .tce, .tcele => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort => return 16,
                     .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
                     .float, .double, .longdouble => return 32,
                 },
                 .mips64, .mips64el => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort => return 16,
                     .int, .uint, .float => return 32,
                     .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
@@ -1970,6 +1976,7 @@ pub const Target = struct {
                     .longdouble => return 128,
                 },
                 .x86_64 => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort => return 16,
                     .int, .uint, .float => return 32,
                     .long, .ulong => switch (target.abi) {
@@ -1980,6 +1987,7 @@ pub const Target = struct {
                     .longdouble => return 80,
                 },
                 else => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort => return 16,
                     .int, .uint, .float => return 32,
                     .long, .ulong => return target.cpu.arch.ptrBitWidth(),
@@ -2036,21 +2044,25 @@ pub const Target = struct {
             .minix,
             => switch (target.cpu.arch) {
                 .msp430 => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort, .int, .uint => return 16,
                     .long, .ulong, .float => return 32,
                     .longlong, .ulonglong, .double, .longdouble => return 64,
                 },
                 .avr => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort, .int, .uint => return 16,
                     .long, .ulong, .float, .double, .longdouble => return 32,
                     .longlong, .ulonglong => return 64,
                 },
                 .tce, .tcele => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort => return 16,
                     .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
                     .float, .double, .longdouble => return 32,
                 },
                 .mips64, .mips64el => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort => return 16,
                     .int, .uint, .float => return 32,
                     .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
@@ -2058,6 +2070,7 @@ pub const Target = struct {
                     .longdouble => if (target.os.tag == .freebsd) return 64 else return 128,
                 },
                 .x86_64 => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort => return 16,
                     .int, .uint, .float => return 32,
                     .long, .ulong => switch (target.abi) {
@@ -2068,6 +2081,7 @@ pub const Target = struct {
                     .longdouble => return 80,
                 },
                 else => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort => return 16,
                     .int, .uint, .float => return 32,
                     .long, .ulong => return target.cpu.arch.ptrBitWidth(),
@@ -2128,6 +2142,7 @@ pub const Target = struct {
 
             .windows, .uefi => switch (target.cpu.arch) {
                 .x86 => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort => return 16,
                     .int, .uint, .float => return 32,
                     .long, .ulong => return 32,
@@ -2138,6 +2153,7 @@ pub const Target = struct {
                     },
                 },
                 .x86_64 => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort => return 16,
                     .int, .uint, .float => return 32,
                     .long, .ulong => switch (target.abi) {
@@ -2151,6 +2167,7 @@ pub const Target = struct {
                     },
                 },
                 else => switch (c_type) {
+                    .char => return 8,
                     .short, .ushort => return 16,
                     .int, .uint, .float => return 32,
                     .long, .ulong => return 32,
@@ -2160,6 +2177,7 @@ pub const Target = struct {
             },
 
             .macos, .ios, .tvos, .watchos => switch (c_type) {
+                .char => return 8,
                 .short, .ushort => return 16,
                 .int, .uint, .float => return 32,
                 .long, .ulong => switch (target.cpu.arch) {
@@ -2182,6 +2200,7 @@ pub const Target = struct {
             },
 
             .nvcl, .cuda => switch (c_type) {
+                .char => return 8,
                 .short, .ushort => return 16,
                 .int, .uint, .float => return 32,
                 .long, .ulong => switch (target.cpu.arch) {
@@ -2194,6 +2213,7 @@ pub const Target = struct {
             },
 
             .amdhsa, .amdpal => switch (c_type) {
+                .char => return 8,
                 .short, .ushort => return 16,
                 .int, .uint, .float => return 32,
                 .long, .ulong, .longlong, .ulonglong, .double => return 64,
src/codegen/c/type.zig
@@ -1358,6 +1358,7 @@ pub const CType = extern union {
             else if (ty.isAbiInt()) switch (ty.tag()) {
                 .usize => self.init(.uintptr_t),
                 .isize => self.init(.intptr_t),
+                .c_char => self.init(.char),
                 .c_short => self.init(.short),
                 .c_ushort => self.init(.@"unsigned short"),
                 .c_int => self.init(.int),
src/AstGen.zig
@@ -9054,6 +9054,7 @@ const primitive_instrs = std.ComptimeStringMap(Zir.Inst.Ref, .{
     .{ "c_long", .c_long_type },
     .{ "c_longdouble", .c_longdouble_type },
     .{ "c_longlong", .c_longlong_type },
+    .{ "c_char", .c_char_type },
     .{ "c_short", .c_short_type },
     .{ "c_uint", .c_uint_type },
     .{ "c_ulong", .c_ulong_type },
@@ -9802,6 +9803,7 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In
                     .c_long_type,
                     .c_longdouble_type,
                     .c_longlong_type,
+                    .c_char_type,
                     .c_short_type,
                     .c_uint_type,
                     .c_ulong_type,
@@ -10047,6 +10049,7 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {
                     .c_long_type,
                     .c_longdouble_type,
                     .c_longlong_type,
+                    .c_char_type,
                     .c_short_type,
                     .c_uint_type,
                     .c_ulong_type,
@@ -10187,6 +10190,7 @@ fn rvalue(
                 as_ty | @enumToInt(Zir.Inst.Ref.i64_type),
                 as_ty | @enumToInt(Zir.Inst.Ref.usize_type),
                 as_ty | @enumToInt(Zir.Inst.Ref.isize_type),
+                as_ty | @enumToInt(Zir.Inst.Ref.c_char_type),
                 as_ty | @enumToInt(Zir.Inst.Ref.c_short_type),
                 as_ty | @enumToInt(Zir.Inst.Ref.c_ushort_type),
                 as_ty | @enumToInt(Zir.Inst.Ref.c_int_type),
src/Sema.zig
@@ -30622,6 +30622,7 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
         .i128,
         .usize,
         .isize,
+        .c_char,
         .c_short,
         .c_ushort,
         .c_int,
@@ -32010,6 +32011,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
         .i128,
         .usize,
         .isize,
+        .c_char,
         .c_short,
         .c_ushort,
         .c_int,
@@ -32640,6 +32642,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
         .i128,
         .usize,
         .isize,
+        .c_char,
         .c_short,
         .c_ushort,
         .c_int,
src/type.zig
@@ -47,6 +47,7 @@ pub const Type = extern union {
             .i128,
             .usize,
             .isize,
+            .c_char,
             .c_short,
             .c_ushort,
             .c_int,
@@ -546,6 +547,7 @@ pub const Type = extern union {
             // Detect that e.g. u64 != usize, even if the bits match on a particular target.
             .usize,
             .isize,
+            .c_char,
             .c_short,
             .c_ushort,
             .c_int,
@@ -946,6 +948,7 @@ pub const Type = extern union {
 
             .usize,
             .isize,
+            .c_char,
             .c_short,
             .c_ushort,
             .c_int,
@@ -1292,6 +1295,7 @@ pub const Type = extern union {
             .i128,
             .usize,
             .isize,
+            .c_char,
             .c_short,
             .c_ushort,
             .c_int,
@@ -1584,6 +1588,7 @@ pub const Type = extern union {
                 .i128,
                 .usize,
                 .isize,
+                .c_char,
                 .c_short,
                 .c_ushort,
                 .c_int,
@@ -1974,6 +1979,7 @@ pub const Type = extern union {
             .i128,
             .usize,
             .isize,
+            .c_char,
             .c_short,
             .c_ushort,
             .c_int,
@@ -2290,6 +2296,7 @@ pub const Type = extern union {
             .i64 => return Value.initTag(.i64_type),
             .usize => return Value.initTag(.usize_type),
             .isize => return Value.initTag(.isize_type),
+            .c_char => return Value.initTag(.c_char_type),
             .c_short => return Value.initTag(.c_short_type),
             .c_ushort => return Value.initTag(.c_ushort_type),
             .c_int => return Value.initTag(.c_int_type),
@@ -2376,6 +2383,7 @@ pub const Type = extern union {
             .i128,
             .usize,
             .isize,
+            .c_char,
             .c_short,
             .c_ushort,
             .c_int,
@@ -2603,6 +2611,7 @@ pub const Type = extern union {
             .i128,
             .usize,
             .isize,
+            .c_char,
             .c_short,
             .c_ushort,
             .c_int,
@@ -2938,6 +2947,7 @@ pub const Type = extern union {
             .anyframe_T,
             => return AbiAlignmentAdvanced{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) },
 
+            .c_char => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.char) },
             .c_short => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.short) },
             .c_ushort => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.ushort) },
             .c_int => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.int) },
@@ -3435,6 +3445,7 @@ pub const Type = extern union {
                 else => return AbiSizeAdvanced{ .scalar = @divExact(target.cpu.arch.ptrBitWidth(), 8) },
             },
 
+            .c_char => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.char) },
             .c_short => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.short) },
             .c_ushort => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.ushort) },
             .c_int => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.int) },
@@ -3742,6 +3753,7 @@ pub const Type = extern union {
             .manyptr_const_u8_sentinel_0,
             => return target.cpu.arch.ptrBitWidth(),
 
+            .c_char => return target.c_type_bit_size(.char),
             .c_short => return target.c_type_bit_size(.short),
             .c_ushort => return target.c_type_bit_size(.ushort),
             .c_int => return target.c_type_bit_size(.int),
@@ -4553,6 +4565,7 @@ pub const Type = extern union {
             .int_signed,
             .i8,
             .isize,
+            .c_char,
             .c_short,
             .c_int,
             .c_long,
@@ -4625,6 +4638,7 @@ pub const Type = extern union {
             .i128 => return .{ .signedness = .signed, .bits = 128 },
             .usize => return .{ .signedness = .unsigned, .bits = target.cpu.arch.ptrBitWidth() },
             .isize => return .{ .signedness = .signed, .bits = target.cpu.arch.ptrBitWidth() },
+            .c_char => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.char) },
             .c_short => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.short) },
             .c_ushort => return .{ .signedness = .unsigned, .bits = target.c_type_bit_size(.ushort) },
             .c_int => return .{ .signedness = .signed, .bits = target.c_type_bit_size(.int) },
@@ -4664,6 +4678,7 @@ pub const Type = extern union {
         return switch (self.tag()) {
             .usize,
             .isize,
+            .c_char,
             .c_short,
             .c_ushort,
             .c_int,
@@ -4921,6 +4936,7 @@ pub const Type = extern union {
             .i128,
             .usize,
             .isize,
+            .c_char,
             .c_short,
             .c_ushort,
             .c_int,
@@ -4964,6 +4980,7 @@ pub const Type = extern union {
             .i128,
             .usize,
             .isize,
+            .c_char,
             .c_short,
             .c_ushort,
             .c_int,
@@ -5155,6 +5172,7 @@ pub const Type = extern union {
             .i128,
             .usize,
             .isize,
+            .c_char,
             .c_short,
             .c_ushort,
             .c_int,
@@ -5993,6 +6011,7 @@ pub const Type = extern union {
         i128,
         usize,
         isize,
+        c_char,
         c_short,
         c_ushort,
         c_int,
@@ -6118,6 +6137,7 @@ pub const Type = extern union {
                 .i128,
                 .usize,
                 .isize,
+                .c_char,
                 .c_short,
                 .c_ushort,
                 .c_int,
src/TypedValue.zig
@@ -92,6 +92,7 @@ pub fn print(
         .i128_type => return writer.writeAll("i128"),
         .isize_type => return writer.writeAll("isize"),
         .usize_type => return writer.writeAll("usize"),
+        .c_char_type => return writer.writeAll("c_char"),
         .c_short_type => return writer.writeAll("c_short"),
         .c_ushort_type => return writer.writeAll("c_ushort"),
         .c_int_type => return writer.writeAll("c_int"),
src/value.zig
@@ -40,6 +40,7 @@ pub const Value = extern union {
         i128_type,
         usize_type,
         isize_type,
+        c_char_type,
         c_short_type,
         c_ushort_type,
         c_int_type,
@@ -210,6 +211,7 @@ pub const Value = extern union {
                 .i128_type,
                 .usize_type,
                 .isize_type,
+                .c_char_type,
                 .c_short_type,
                 .c_ushort_type,
                 .c_int_type,
@@ -413,6 +415,7 @@ pub const Value = extern union {
             .i128_type,
             .usize_type,
             .isize_type,
+            .c_char_type,
             .c_short_type,
             .c_ushort_type,
             .c_int_type,
@@ -679,6 +682,7 @@ pub const Value = extern union {
             .i128_type => return out_stream.writeAll("i128"),
             .isize_type => return out_stream.writeAll("isize"),
             .usize_type => return out_stream.writeAll("usize"),
+            .c_char_type => return out_stream.writeAll("c_char"),
             .c_short_type => return out_stream.writeAll("c_short"),
             .c_ushort_type => return out_stream.writeAll("c_ushort"),
             .c_int_type => return out_stream.writeAll("c_int"),
@@ -919,6 +923,7 @@ pub const Value = extern union {
             .i128_type => Type.initTag(.i128),
             .usize_type => Type.initTag(.usize),
             .isize_type => Type.initTag(.isize),
+            .c_char_type => Type.initTag(.c_char),
             .c_short_type => Type.initTag(.c_short),
             .c_ushort_type => Type.initTag(.c_ushort),
             .c_int_type => Type.initTag(.c_int),
src/Zir.zig
@@ -2062,6 +2062,7 @@ pub const Inst = struct {
         i128_type,
         usize_type,
         isize_type,
+        c_char_type,
         c_short_type,
         c_ushort_type,
         c_int_type,
@@ -2201,6 +2202,10 @@ pub const Inst = struct {
                 .ty = Type.initTag(.type),
                 .val = Value.initTag(.isize_type),
             },
+            .c_char_type = .{
+                .ty = Type.initTag(.type),
+                .val = Value.initTag(.c_char_type),
+            },
             .c_short_type = .{
                 .ty = Type.initTag(.type),
                 .val = Value.initTag(.c_short_type),
stage1/zig1.wasm
Binary file