add C pointer type to @typeInfo

See #1059
This commit is contained in:
Andrew Kelley 2019-02-11 16:07:40 -05:00
parent 342bca7f46
commit 90b8cd4a45
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
7 changed files with 41 additions and 6 deletions

View File

@ -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),

View File

@ -7309,6 +7309,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
" One,\n"
" Many,\n"
" Slice,\n"
" C,\n"
" };\n"
" };\n"
"\n"

View File

@ -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();
}

View File

@ -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) {

View File

@ -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,

View File

@ -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 {
}
}
},
}
}

View File

@ -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();