Commit c52513e25b
Changed files (3)
src-self-hosted
src-self-hosted/astgen.zig
@@ -113,6 +113,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
.Period => return rlWrap(mod, scope, rl, try field(mod, scope, node.castTag(.Period).?)),
.Deref => return rlWrap(mod, scope, rl, try deref(mod, scope, node.castTag(.Deref).?)),
.BoolNot => return rlWrap(mod, scope, rl, try boolNot(mod, scope, node.castTag(.BoolNot).?)),
+ .AddressOf => return rlWrap(mod, scope, rl, try addressOf(mod, scope, node.castTag(.AddressOf).?)),
.FloatLiteral => return rlWrap(mod, scope, rl, try floatLiteral(mod, scope, node.castTag(.FloatLiteral).?)),
.UndefinedLiteral => return rlWrap(mod, scope, rl, try undefLiteral(mod, scope, node.castTag(.UndefinedLiteral).?)),
.BoolLiteral => return rlWrap(mod, scope, rl, try boolLiteral(mod, scope, node.castTag(.BoolLiteral).?)),
@@ -122,6 +123,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
.Block => return rlWrapVoid(mod, scope, rl, node, try blockExpr(mod, scope, node.castTag(.Block).?)),
.LabeledBlock => return labeledBlockExpr(mod, scope, rl, node.castTag(.LabeledBlock).?),
.Break => return rlWrap(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)),
+ .PtrType => return rlWrap(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)),
.Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}),
.Catch => return mod.failNode(scope, node, "TODO implement astgen.expr for .Catch", .{}),
@@ -131,7 +133,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
.MergeErrorSets => return mod.failNode(scope, node, "TODO implement astgen.expr for .MergeErrorSets", .{}),
.Range => return mod.failNode(scope, node, "TODO implement astgen.expr for .Range", .{}),
.OrElse => return mod.failNode(scope, node, "TODO implement astgen.expr for .OrElse", .{}),
- .AddressOf => return mod.failNode(scope, node, "TODO implement astgen.expr for .AddressOf", .{}),
.Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}),
.BitNot => return mod.failNode(scope, node, "TODO implement astgen.expr for .BitNot", .{}),
.Negation => return mod.failNode(scope, node, "TODO implement astgen.expr for .Negation", .{}),
@@ -140,7 +141,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr
.Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
.ArrayType => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayType", .{}),
.ArrayTypeSentinel => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayTypeSentinel", .{}),
- .PtrType => return mod.failNode(scope, node, "TODO implement astgen.expr for .PtrType", .{}),
.SliceType => return mod.failNode(scope, node, "TODO implement astgen.expr for .SliceType", .{}),
.Slice => return mod.failNode(scope, node, "TODO implement astgen.expr for .Slice", .{}),
.ArrayAccess => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayAccess", .{}),
@@ -452,6 +452,12 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerErr
return addZIRUnOp(mod, scope, src, .boolnot, operand);
}
+fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {
+ const tree = scope.tree();
+ const src = tree.token_locs[node.op_token].start;
+ return expr(mod, scope, .lvalue, node.rhs);
+}
+
fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst {
const tree = scope.tree();
const src = tree.token_locs[node.op_token].start;
@@ -463,6 +469,47 @@ fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) Inn
return addZIRUnOp(mod, scope, src, .optional_type, operand);
}
+fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir.Inst {
+ const tree = scope.tree();
+ const src = tree.token_locs[node.op_token].start;
+ const meta_type = try addZIRInstConst(mod, scope, src, .{
+ .ty = Type.initTag(.type),
+ .val = Value.initTag(.type_type),
+ });
+
+ const simple = node.ptr_info.allowzero_token == null and
+ node.ptr_info.align_info == null and
+ node.ptr_info.volatile_token == null and
+ node.ptr_info.sentinel == null;
+
+ if (simple) {
+ const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);
+ return addZIRUnOp(mod, scope, src, if (node.ptr_info.const_token == null)
+ .single_mut_ptr_type
+ else
+ .single_const_ptr_type, child_type);
+ }
+
+ const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs);
+
+ var kw_args: std.meta.fieldInfo(zir.Inst.PtrType, "kw_args").field_type = .{};
+ kw_args.@"allowzero" = node.ptr_info.allowzero_token != null;
+ if (node.ptr_info.align_info) |some| {
+ kw_args.@"align" = try expr(mod, scope, .none, some.node);
+ if (some.bit_range) |bit_range| {
+ kw_args.align_bit_start = try expr(mod, scope, .none, bit_range.start);
+ kw_args.align_bit_end = try expr(mod, scope, .none, bit_range.end);
+ }
+ }
+ kw_args.@"const" = node.ptr_info.const_token != null;
+ kw_args.@"volatile" = node.ptr_info.volatile_token != null;
+ if (node.ptr_info.sentinel) |some| {
+ kw_args.sentinel = try expr(mod, scope, .{ .ty = child_type }, some);
+ }
+
+ return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);
+}
+
fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst {
const tree = scope.tree();
const src = tree.token_locs[node.rtoken].start;
src-self-hosted/zir.zig
@@ -192,6 +192,8 @@ pub const Inst = struct {
single_const_ptr_type,
/// Create a mutable pointer type based on the element type. `*T`
single_mut_ptr_type,
+ /// Create a pointer type with attributes
+ 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.
@@ -305,6 +307,7 @@ pub const Inst = struct {
.fntype => FnType,
.elemptr => ElemPtr,
.condbr => CondBr,
+ .ptr_type => PtrType,
};
}
@@ -382,6 +385,7 @@ pub const Inst = struct {
.optional_type,
.unwrap_optional_safe,
.unwrap_optional_unsafe,
+ .ptr_type,
=> false,
.@"break",
@@ -811,6 +815,24 @@ pub const Inst = struct {
},
kw_args: struct {},
};
+
+ pub const PtrType = struct {
+ pub const base_tag = Tag.ptr_type;
+ base: Inst,
+
+ positionals: struct {
+ child_type: *Inst,
+ },
+ kw_args: struct {
+ @"allowzero": bool = false,
+ @"align": ?*Inst = null,
+ align_bit_start: ?*Inst = null,
+ align_bit_end: ?*Inst = null,
+ @"const": bool = true,
+ @"volatile": bool = false,
+ sentinel: ?*Inst = null,
+ },
+ };
};
pub const ErrorMsg = struct {
src-self-hosted/zir_sema.zig
@@ -53,6 +53,7 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
.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).?),
+ .ptr_type => return analyzeInstPtrType(mod, scope, old_inst.castTag(.ptr_type).?),
.store => return analyzeInstStore(mod, scope, old_inst.castTag(.store).?),
.str => return analyzeInstStr(mod, scope, old_inst.castTag(.str).?),
.int => {
@@ -1287,3 +1288,7 @@ fn analyzeInstSingleMutPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.UnOp
const ty = try mod.singleMutPtrType(scope, inst.base.src, elem_type);
return mod.constType(scope, inst.base.src, ty);
}
+
+fn analyzeInstPtrType(mod: *Module, scope: *Scope, inst: *zir.Inst.PtrType) InnerError!*Inst {
+ return mod.fail(scope, inst.base.src, "TODO implement ptr_type", .{});
+}