@@ -3134,6 +3134,7 @@ pub const Type = struct {
31343134 const b_type = b .pointer ;
31353135 if (a_type .size != b_type .size ) return false ;
31363136 if (a_type .sentinel != b_type .sentinel ) return false ;
3137+ if (a_type .is_const != b_type .is_const ) return false ;
31373138 if (! a_type .elem_ty .eql (b_type .elem_ty .* )) return false ;
31383139 },
31393140 .array = > | a_type | {
@@ -4057,6 +4058,62 @@ pub const Type = struct {
40574058 };
40584059 }
40594060
4061+ const PointerInfo = struct {
4062+ elem_ty : Type ,
4063+ sentinel : InternPool.Index ,
4064+ flags : InternPool.Key.Pointer.Flags ,
4065+ };
4066+
4067+ fn pointerInfo (ty : Type , analyser : * Analyser ) ? PointerInfo {
4068+ if (! ty .is_type_val ) return null ;
4069+ return blk : switch (ty .data ) {
4070+ .pointer = > | info | .{
4071+ .elem_ty = info .elem_ty .* ,
4072+ .sentinel = info .sentinel ,
4073+ .flags = .{
4074+ .size = info .size ,
4075+ .is_const = info .is_const ,
4076+ },
4077+ },
4078+ .ip_index = > | payload | switch (analyser .ip .indexToKey (payload .index orelse return null )) {
4079+ .pointer_type = > | info | .{
4080+ .elem_ty = Type .fromIP (analyser , .type_type , info .elem_type ),
4081+ .sentinel = info .sentinel ,
4082+ .flags = info .flags ,
4083+ },
4084+ else = > null ,
4085+ },
4086+ .optional = > | child | switch (child .data ) {
4087+ .pointer = > continue :blk child .data ,
4088+ .ip_index = > | payload | switch (analyser .ip .indexToKey (payload .index orelse return null )) {
4089+ .pointer_type = > continue :blk child .data ,
4090+ else = > null ,
4091+ },
4092+ else = > null ,
4093+ },
4094+ else = > null ,
4095+ };
4096+ }
4097+
4098+ fn isPointerAtRuntime (ty : Type , analyser : * Analyser ) bool {
4099+ switch (ty .data ) {
4100+ .optional = > | child | {
4101+ const p = child .pointerInfo (analyser ) orelse return false ;
4102+ return switch (p .flags .size ) {
4103+ .slice , .c = > false ,
4104+ .many , .one = > ! p .flags .is_allowzero ,
4105+ };
4106+ },
4107+ else = > {
4108+ const info = ty .pointerInfo (analyser ) orelse return false ;
4109+ return switch (info .flags .size ) {
4110+ .slice = > false ,
4111+ .one , .many , .c = > true ,
4112+ };
4113+ },
4114+ }
4115+ }
4116+
40604117 pub fn stringifyTypeOf (ty : Type , analyser : * Analyser , options : FormatOptions ) error {OutOfMemory }! []const u8 {
40614118 const typeof = try ty .typeOf (analyser );
40624119 var aw : std.io.Writer.Allocating = .init (analyser .arena );
@@ -6648,7 +6705,64 @@ fn resolvePeerTypesInner(analyser: *Analyser, peer_tys: []?Type) !?Type {
66486705
66496706 .vector = > return null , // TODO
66506707
6651- .c_ptr = > return null , // TODO
6708+ .c_ptr = > {
6709+ var opt_ptr_info : ? Type.PointerInfo = null ;
6710+ for (peer_tys ) | opt_ty | {
6711+ const ty = opt_ty orelse continue ;
6712+ switch (ty .zigTypeTag (analyser ).? ) {
6713+ .comptime_int = > continue ,
6714+ .int = > {
6715+ const ptr_bits = builtin .target .ptrBitWidth ();
6716+ const bits = analyser .ip .intInfo (ty .data .ip_index .index .? , builtin .target ).bits ;
6717+ if (bits >= ptr_bits ) continue ;
6718+ },
6719+ .null = > continue ,
6720+ else = > {},
6721+ }
6722+
6723+ if (! ty .isPointerAtRuntime (analyser )) {
6724+ return null ;
6725+ }
6726+
6727+ const peer_info = ty .pointerInfo (analyser ).? ;
6728+
6729+ var ptr_info = opt_ptr_info orelse {
6730+ opt_ptr_info = peer_info ;
6731+ continue ;
6732+ };
6733+
6734+ if (! ptr_info .elem_ty .eql (peer_info .elem_ty )) {
6735+ // TODO: coerce C pointer element types
6736+ return null ;
6737+ }
6738+
6739+ if (ptr_info .flags .alignment != ptr_info .flags .alignment ) {
6740+ // TODO: find minimum C pointer alignment
6741+ return null ;
6742+ }
6743+
6744+ if (ptr_info .flags .address_space != peer_info .flags .address_space ) {
6745+ return null ;
6746+ }
6747+
6748+ ptr_info .flags .is_const = ptr_info .flags .is_const or peer_info .flags .is_const ;
6749+ ptr_info .flags .is_volatile = ptr_info .flags .is_volatile or peer_info .flags .is_volatile ;
6750+
6751+ opt_ptr_info = ptr_info ;
6752+ }
6753+ const info = opt_ptr_info .? ;
6754+ return .{
6755+ .data = .{
6756+ .pointer = .{
6757+ .elem_ty = try analyser .allocType (info .elem_ty ),
6758+ .sentinel = .none ,
6759+ .size = .c ,
6760+ .is_const = info .flags .is_const ,
6761+ },
6762+ },
6763+ .is_type_val = true ,
6764+ };
6765+ },
66526766
66536767 .ptr = > return null , // TODO
66546768
0 commit comments