feature. See also
. The project being documented here (as the example) is the Zig library itself.
AstGen.ptrType
fn ptrType(
gz: *GenZir,
scope: *Scope,
ri: ResultInfo,
node: Ast.Node.Index,
ptr_info: Ast.full.PtrType,
) InnerError!Zir.Inst.Ref
File
Code
fn ptrType(
gz: *GenZir,
scope: *Scope,
ri: ResultInfo,
node: Ast.Node.Index,
ptr_info: Ast.full.PtrType,
) InnerError!Zir.Inst.Ref {
if (ptr_info.size == .c and ptr_info.allowzero_token != null) {
return gz.astgen.failTok(ptr_info.allowzero_token.?, "C pointers always allow address zero", .{});
}
if (ptr_info.duplicate_token) |duplicate| {
return gz.astgen.failTok(duplicate, "Extra pointer qualifier", .{});
}
const source_offset = gz.astgen.source_offset;
const source_line = gz.astgen.source_line;
const source_column = gz.astgen.source_column;
const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type);
var sentinel_ref: Zir.Inst.Ref = .none;
var align_ref: Zir.Inst.Ref = .none;
var addrspace_ref: Zir.Inst.Ref = .none;
var bit_start_ref: Zir.Inst.Ref = .none;
var bit_end_ref: Zir.Inst.Ref = .none;
var trailing_count: u32 = 0;
if (ptr_info.ast.sentinel.unwrap()) |sentinel| {
// element type so we need to reset the source cursor before generating them.
gz.astgen.source_offset = source_offset;
gz.astgen.source_line = source_line;
gz.astgen.source_column = source_column;
sentinel_ref = try comptimeExpr(
gz,
scope,
.{ .rl = .{ .ty = elem_type } },
sentinel,
switch (ptr_info.size) {
.slice => .slice_sentinel,
else => .pointer_sentinel,
},
);
trailing_count += 1;
}
if (ptr_info.ast.addrspace_node.unwrap()) |addrspace_node| {
gz.astgen.source_offset = source_offset;
gz.astgen.source_line = source_line;
gz.astgen.source_column = source_column;
const addrspace_ty = try gz.addStdLangValue(addrspace_node, .address_space);
addrspace_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = addrspace_ty } }, addrspace_node, .@"addrspace");
trailing_count += 1;
}
if (ptr_info.ast.align_node.unwrap()) |align_node| {
gz.astgen.source_offset = source_offset;
gz.astgen.source_line = source_line;
gz.astgen.source_column = source_column;
align_ref = try comptimeExpr(gz, scope, coerced_align_ri, align_node, .@"align");
trailing_count += 1;
}
if (ptr_info.ast.bit_range_start.unwrap()) |bit_range_start| {
const bit_range_end = ptr_info.ast.bit_range_end.unwrap().?;
bit_start_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, bit_range_start, .type);
bit_end_ref = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, bit_range_end, .type);
trailing_count += 2;
}
const gpa = gz.astgen.gpa;
try gz.instructions.ensureUnusedCapacity(gpa, 1);
try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1);
try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.PtrType).@"struct".field_names.len +
trailing_count);
const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.PtrType{
.elem_type = elem_type,
.src_node = gz.nodeIndexToRelative(node),
});
if (sentinel_ref != .none) {
gz.astgen.extra.appendAssumeCapacity(@backingInt(sentinel_ref));
}
if (align_ref != .none) {
gz.astgen.extra.appendAssumeCapacity(@backingInt(align_ref));
}
if (addrspace_ref != .none) {
gz.astgen.extra.appendAssumeCapacity(@backingInt(addrspace_ref));
}
if (bit_start_ref != .none) {
gz.astgen.extra.appendAssumeCapacity(@backingInt(bit_start_ref));
gz.astgen.extra.appendAssumeCapacity(@backingInt(bit_end_ref));
}
const new_index: Zir.Inst.Index = @fromBackingInt(@intCast(gz.astgen.instructions.len));
const result = new_index.toRef();
gz.astgen.instructions.appendAssumeCapacity(.{ .tag = .ptr_type, .data = .{
.ptr_type = .{
.flags = .{
.is_allowzero = ptr_info.allowzero_token != null,
.is_mutable = ptr_info.const_token == null,
.is_volatile = ptr_info.volatile_token != null,
.has_sentinel = sentinel_ref != .none,
.has_align = align_ref != .none,
.has_addrspace = addrspace_ref != .none,
.has_bit_range = bit_start_ref != .none,
},
.size = ptr_info.size,
.payload_index = payload_index,
},
} });
gz.instructions.appendAssumeCapacity(new_index);
return rvalue(gz, ri, result, node);
}