diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig index 8a05594b30..790b51b7be 100644 --- a/src-self-hosted/type.zig +++ b/src-self-hosted/type.zig @@ -794,6 +794,7 @@ pub const Type = struct { Size.One => "*", Size.Many => "[*]", Size.Slice => "[]", + Size.C => "[*c]", }; const mut_str = switch (self.key.mut) { Mut.Const => "const ", @@ -1088,6 +1089,7 @@ fn hashAny(x: var, comptime seed: u64) u32 { builtin.TypeInfo.Pointer.Size.One => return hashAny(@ptrToInt(x), seed), builtin.TypeInfo.Pointer.Size.Many => @compileError("implement hash function"), builtin.TypeInfo.Pointer.Size.Slice => @compileError("implement hash function"), + builtin.TypeInfo.Pointer.Size.C => unreachable, } }, builtin.TypeId.Enum => return hashAny(@enumToInt(x), seed), diff --git a/src/codegen.cpp b/src/codegen.cpp index 605ea59b06..142e8174f5 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7309,6 +7309,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { " One,\n" " Many,\n" " Slice,\n" + " C,\n" " };\n" " };\n" "\n" diff --git a/src/ir.cpp b/src/ir.cpp index bc37ac9b54..36ea50ed52 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17584,6 +17584,18 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco return ErrorNone; } +static uint32_t ptr_len_to_size_enum_index(PtrLen ptr_len) { + switch (ptr_len) { + case PtrLenSingle: + return 0; + case PtrLenUnknown: + return 1; + case PtrLenC: + return 3; + } + zig_unreachable(); +} + static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_entry) { Error err; ZigType *attrs_type; @@ -17593,7 +17605,7 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty size_enum_index = 2; } else if (ptr_type_entry->id == ZigTypeIdPointer) { attrs_type = ptr_type_entry; - size_enum_index = (ptr_type_entry->data.pointer.ptr_len == PtrLenSingle) ? 0 : 1; + size_enum_index = ptr_len_to_size_enum_index(ptr_type_entry->data.pointer.ptr_len); } else { zig_unreachable(); } diff --git a/std/fmt/index.zig b/std/fmt/index.zig index 05b028112f..b09fe21032 100644 --- a/std/fmt/index.zig +++ b/std/fmt/index.zig @@ -236,6 +236,9 @@ pub fn formatType( const casted_value = ([]const u8)(value); return output(context, casted_value); }, + builtin.TypeInfo.Pointer.Size.C => { + return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value)); + }, }, builtin.TypeId.Array => |info| { if (info.child == u8) { diff --git a/std/meta/index.zig b/std/meta/index.zig index 3f8ea762a6..652e2d39ec 100644 --- a/std/meta/index.zig +++ b/std/meta/index.zig @@ -463,13 +463,16 @@ pub fn eql(a: var, b: @typeOf(a)) bool { builtin.TypeId.Pointer => { const info = @typeInfo(T).Pointer; switch (info.size) { - builtin.TypeInfo.Pointer.Size.One, builtin.TypeInfo.Pointer.Size.Many => return a == b, + builtin.TypeInfo.Pointer.Size.One, + builtin.TypeInfo.Pointer.Size.Many, + builtin.TypeInfo.Pointer.Size.C, + => return a == b, builtin.TypeInfo.Pointer.Size.Slice => return a.ptr == b.ptr and a.len == b.len, } }, builtin.TypeId.Optional => { - if(a == null and b == null) return true; - if(a == null or b == null) return false; + if (a == null and b == null) return true; + if (a == null or b == null) return false; return eql(a.?, b.?); }, else => return a == b, diff --git a/std/testing.zig b/std/testing.zig index ade6e8b0dd..f3ce69659d 100644 --- a/std/testing.zig +++ b/std/testing.zig @@ -69,7 +69,7 @@ pub fn expectEqual(expected: var, actual: var) void { } }, - builtin.TypeInfo.Pointer.Size.Slice => { + builtin.TypeInfo.Pointer.Size.Slice => { if (actual.ptr != expected.ptr) { std.debug.panic("expected slice ptr {}, found {}", expected.ptr, actual.ptr); } @@ -122,7 +122,6 @@ pub fn expectEqual(expected: var, actual: var) void { } } }, - } } diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig index ce0ad795b4..dc185cc960 100644 --- a/test/stage1/behavior/type_info.zig +++ b/test/stage1/behavior/type_info.zig @@ -61,6 +61,21 @@ fn testUnknownLenPtr() void { expect(u32_ptr_info.Pointer.child == f64); } +test "type info: C pointer type info" { + testCPtr(); + comptime testCPtr(); +} + +fn testCPtr() void { + const ptr_info = @typeInfo([*c]align(4) const i8); + expect(TypeId(ptr_info) == TypeId.Pointer); + expect(ptr_info.Pointer.size == TypeInfo.Pointer.Size.C); + expect(ptr_info.Pointer.is_const); + expect(!ptr_info.Pointer.is_volatile); + expect(ptr_info.Pointer.alignment == 4); + expect(ptr_info.Pointer.child == i8); +} + test "type info: slice type info" { testSlice(); comptime testSlice();