@@ -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+ if (ty .pointerInfo (analyser )) | info | {
4100+ return switch (info .flags .size ) {
4101+ .slice = > false ,
4102+ .one , .many , .c = > true ,
4103+ };
4104+ }
4105+ switch (ty .data ) {
4106+ .optional = > | child | {
4107+ const p = child .pointerInfo (analyser ) orelse return false ;
4108+ return switch (p .flags .size ) {
4109+ .slice , .c = > false ,
4110+ .many , .one = > ! p .flags .is_allowzero ,
4111+ };
4112+ },
4113+ else = > return false ,
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 );
@@ -6660,7 +6717,64 @@ fn resolvePeerTypesInner(analyser: *Analyser, peer_tys: []?Type) !?Type {
66606717
66616718 .vector = > return null , // TODO
66626719
6663- .c_ptr = > return null , // TODO
6720+ .c_ptr = > {
6721+ var opt_ptr_info : ? Type.PointerInfo = null ;
6722+ for (peer_tys ) | opt_ty | {
6723+ const ty = opt_ty orelse continue ;
6724+ switch (ty .zigTypeTag (analyser ).? ) {
6725+ .comptime_int = > continue ,
6726+ .int = > {
6727+ const ptr_bits = builtin .target .ptrBitWidth ();
6728+ const bits = analyser .ip .intInfo (ty .data .ip_index .index .? , builtin .target ).bits ;
6729+ if (bits >= ptr_bits ) continue ;
6730+ },
6731+ .null = > continue ,
6732+ else = > {},
6733+ }
6734+
6735+ if (! ty .isPointerAtRuntime (analyser )) {
6736+ return null ;
6737+ }
6738+
6739+ const peer_info = ty .pointerInfo (analyser ).? ;
6740+
6741+ var ptr_info = opt_ptr_info orelse {
6742+ opt_ptr_info = peer_info ;
6743+ continue ;
6744+ };
6745+
6746+ if (! ptr_info .elem_ty .eql (peer_info .elem_ty )) {
6747+ // TODO: coerce C pointer types
6748+ return null ;
6749+ }
6750+
6751+ if (ptr_info .flags .alignment != ptr_info .flags .alignment ) {
6752+ // TODO: find minimum C pointer alignment
6753+ return null ;
6754+ }
6755+
6756+ if (ptr_info .flags .address_space != peer_info .flags .address_space ) {
6757+ return null ;
6758+ }
6759+
6760+ ptr_info .flags .is_const = ptr_info .flags .is_const or peer_info .flags .is_const ;
6761+ ptr_info .flags .is_volatile = ptr_info .flags .is_volatile or peer_info .flags .is_volatile ;
6762+
6763+ opt_ptr_info = ptr_info ;
6764+ }
6765+ const info = opt_ptr_info .? ;
6766+ return .{
6767+ .data = .{
6768+ .pointer = .{
6769+ .elem_ty = try analyser .allocType (info .elem_ty ),
6770+ .sentinel = .none ,
6771+ .size = .c ,
6772+ .is_const = info .flags .is_const ,
6773+ },
6774+ },
6775+ .is_type_val = true ,
6776+ };
6777+ },
66646778
66656779 .ptr = > return null , // TODO
66666780
0 commit comments