diff --git a/src-self-hosted/zir.zig b/src-self-hosted/zir.zig index 6b98f1d493..38751e22a3 100644 --- a/src-self-hosted/zir.zig +++ b/src-self-hosted/zir.zig @@ -183,6 +183,10 @@ pub const Inst = struct { shl, /// Integer shift-right. Arithmetic or logical depending on the signedness of the integer type. shr, + /// Create a const pointer type based on the element type. `*const T` + single_const_ptr_type, + /// Create a mutable pointer type based on the element type. `*T` + single_mut_ptr_type, /// Write a value to a pointer. For loading, see `deref`. store, /// String Literal. Makes an anonymous Decl and then takes a pointer to it. @@ -228,6 +232,8 @@ pub const Inst = struct { .ref, .bitcast_lvalue, .typeof, + .single_const_ptr_type, + .single_mut_ptr_type, => UnOp, .add, @@ -348,6 +354,8 @@ pub const Inst = struct { .ret_type, .shl, .shr, + .single_const_ptr_type, + .single_mut_ptr_type, .store, .str, .sub, @@ -2095,6 +2103,25 @@ const EmitZIR = struct { }; return self.emitUnnamedDecl(&inttype_inst.base); }, + .Pointer => { + if (ty.isSinglePointer()) { + const inst = try self.arena.allocator.create(Inst.UnOp); + const tag: Inst.Tag = if (ty.isConstPtr()) .single_const_ptr_type else .single_mut_ptr_type; + inst.* = .{ + .base = .{ + .src = src, + .tag = tag, + }, + .positionals = .{ + .operand = (try self.emitType(src, ty.elemType())).inst, + }, + .kw_args = .{}, + }; + return self.emitUnnamedDecl(&inst.base); + } else { + std.debug.panic("TODO implement emitType for {}", .{ty}); + } + }, else => std.debug.panic("TODO implement emitType for {}", .{ty}), }, } diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index 45b49536e5..7db2811384 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -50,6 +50,8 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError! .ref => return analyzeInstRef(mod, scope, old_inst.castTag(.ref).?), .ret_ptr => return analyzeInstRetPtr(mod, scope, old_inst.castTag(.ret_ptr).?), .ret_type => return analyzeInstRetType(mod, scope, old_inst.castTag(.ret_type).?), + .single_const_ptr_type => return analyzeInstSingleConstPtrType(mod, scope, old_inst.castTag(.single_const_ptr_type).?), + .single_mut_ptr_type => return analyzeInstSingleMutPtrType(mod, scope, old_inst.castTag(.single_mut_ptr_type).?), .store => return analyzeInstStore(mod, scope, old_inst.castTag(.store).?), .str => return analyzeInstStr(mod, scope, old_inst.castTag(.str).?), .int => { @@ -1137,3 +1139,15 @@ fn analyzeDeclVal(mod: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) InnerErr return decl; } + +fn analyzeInstSingleConstPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { + const elem_type = try resolveType(mod, scope, inst.positionals.operand); + const ty = try mod.singleConstPtrType(scope, inst.base.src, elem_type); + return mod.constType(scope, inst.base.src, ty); +} + +fn analyzeInstSingleMutPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp) InnerError!*Inst { + const elem_type = try resolveType(mod, scope, inst.positionals.operand); + const ty = try mod.singleMutPtrType(scope, inst.base.src, elem_type); + return mod.constType(scope, inst.base.src, ty); +}