Commit 90b8cd4a45

Andrew Kelley <andrew@ziglang.org>
2019-02-11 22:07:40
add C pointer type to @typeInfo
See #1059
1 parent 342bca7
Changed files (7)
src
src-self-hosted
std
test
stage1
behavior
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"
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();
     }
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),
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) {
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,
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 {
                 }
             }
         },
-
     }
 }
 
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();