@@ -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 );
@@ -6619,7 +6676,64 @@ fn resolvePeerTypesInner(analyser: *Analyser, peer_tys: []?Type) !?Type {
66196676
66206677 .vector = > return null , // TODO
66216678
6622- .c_ptr = > return null , // TODO
6679+ .c_ptr = > {
6680+ var opt_ptr_info : ? Type.PointerInfo = null ;
6681+ for (peer_tys ) | opt_ty | {
6682+ const ty = opt_ty orelse continue ;
6683+ switch (ty .zigTypeTag (analyser ).? ) {
6684+ .comptime_int = > continue ,
6685+ .int = > {
6686+ const ptr_bits = builtin .target .ptrBitWidth ();
6687+ const bits = analyser .ip .intInfo (ty .data .ip_index .index .? , builtin .target ).bits ;
6688+ if (bits >= ptr_bits ) continue ;
6689+ },
6690+ .null = > continue ,
6691+ else = > {},
6692+ }
6693+
6694+ if (! ty .isPointerAtRuntime (analyser )) {
6695+ return null ;
6696+ }
6697+
6698+ const peer_info = ty .pointerInfo (analyser ).? ;
6699+
6700+ var ptr_info = opt_ptr_info orelse {
6701+ opt_ptr_info = peer_info ;
6702+ continue ;
6703+ };
6704+
6705+ if (! ptr_info .elem_ty .eql (peer_info .elem_ty )) {
6706+ // TODO: coerce C pointer types
6707+ return null ;
6708+ }
6709+
6710+ if (ptr_info .flags .alignment != ptr_info .flags .alignment ) {
6711+ // TODO: find minimum C pointer alignment
6712+ return null ;
6713+ }
6714+
6715+ if (ptr_info .flags .address_space != peer_info .flags .address_space ) {
6716+ return null ;
6717+ }
6718+
6719+ ptr_info .flags .is_const = ptr_info .flags .is_const or peer_info .flags .is_const ;
6720+ ptr_info .flags .is_volatile = ptr_info .flags .is_volatile or peer_info .flags .is_volatile ;
6721+
6722+ opt_ptr_info = ptr_info ;
6723+ }
6724+ const info = opt_ptr_info .? ;
6725+ return .{
6726+ .data = .{
6727+ .pointer = .{
6728+ .elem_ty = try analyser .allocType (info .elem_ty ),
6729+ .sentinel = .none ,
6730+ .size = .c ,
6731+ .is_const = info .flags .is_const ,
6732+ },
6733+ },
6734+ .is_type_val = true ,
6735+ };
6736+ },
66236737
66246738 .ptr = > return null , // TODO
66256739
0 commit comments