authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-03-22 16:03:00+01:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2021-03-22 16:03:00+01:00
logf3770dcc307e4207de8e38c44bcf1bf98dc8448c
tree4c9874426cbe5dd3a61a790b96b79e909f7413b1
parent8111453cc12f7908110850cf64efedb9c69ede98
signature Commit is signed but in an unrecognized format.

astgen: implement pointer types


3 files changed, 80 insertions(+), 43 deletions(-)

src/Sema.zig+2-2
...@@ -2957,13 +2957,13 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -2957,13 +2957,13 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
2957 break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u32);2957 break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u32);
2958 } else 0;2958 } else 0;
29592959
2960 const bit_start = if (inst_data.flags.has_bit_start) blk: {2960 const bit_start = if (inst_data.flags.has_bit_range) blk: {
2961 const ref = sema.code.extra[extra_i];2961 const ref = sema.code.extra[extra_i];
2962 extra_i += 1;2962 extra_i += 1;
2963 break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u16);2963 break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u16);
2964 } else 0;2964 } else 0;
29652965
2966 const bit_end = if (inst_data.flags.has_bit_end) blk: {2966 const bit_end = if (inst_data.flags.has_bit_range) blk: {
2967 const ref = sema.code.extra[extra_i];2967 const ref = sema.code.extra[extra_i];
2968 extra_i += 1;2968 extra_i += 1;
2969 break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u16);2969 break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u16);
src/astgen.zig+74-36
...@@ -603,10 +603,10 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In...@@ -603,10 +603,10 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
603 ),603 ),
604 },604 },
605605
606 .ptr_type_aligned => return ptrType(mod, scope, rl, tree.ptrTypeAligned(node)),606 .ptr_type_aligned => return ptrType(mod, scope, rl, node, tree.ptrTypeAligned(node)),
607 .ptr_type_sentinel => return ptrType(mod, scope, rl, tree.ptrTypeSentinel(node)),607 .ptr_type_sentinel => return ptrType(mod, scope, rl, node, tree.ptrTypeSentinel(node)),
608 .ptr_type => return ptrType(mod, scope, rl, tree.ptrType(node)),608 .ptr_type => return ptrType(mod, scope, rl, node, tree.ptrType(node)),
609 .ptr_type_bit_range => return ptrType(mod, scope, rl, tree.ptrTypeBitRange(node)),609 .ptr_type_bit_range => return ptrType(mod, scope, rl, node, tree.ptrTypeBitRange(node)),
610610
611 .container_decl,611 .container_decl,
612 .container_decl_trailing,612 .container_decl_trailing,
...@@ -1346,47 +1346,85 @@ fn ptrType(...@@ -1346,47 +1346,85 @@ fn ptrType(
1346 mod: *Module,1346 mod: *Module,
1347 scope: *Scope,1347 scope: *Scope,
1348 rl: ResultLoc,1348 rl: ResultLoc,
1349 node: ast.Node.Index,
1349 ptr_info: ast.full.PtrType,1350 ptr_info: ast.full.PtrType,
1350) InnerError!zir.Inst.Ref {1351) InnerError!zir.Inst.Ref {
1351 if (true) @panic("TODO update for zir-memory-layout");
1352 const tree = scope.tree();1352 const tree = scope.tree();
1353 const gz = scope.getGenZir();
13531354
1354 const simple = ptr_info.allowzero_token == null and1355 const elem_type = try typeExpr(mod, scope, ptr_info.ast.child_type);
1355 ptr_info.ast.align_node == 0 and1356
1356 ptr_info.volatile_token == null and1357 const simple = ptr_info.ast.align_node == 0 and
1357 ptr_info.ast.sentinel == 0;1358 ptr_info.ast.sentinel == 0 and
1359 ptr_info.ast.bit_range_start == 0;
13581360
1359 if (simple) {1361 if (simple) {
1360 const child_type = try typeExpr(mod, scope, ptr_info.ast.child_type);1362 const result = try gz.add(.{ .tag = .ptr_type_simple, .data = .{
1361 const mutable = ptr_info.const_token == null;1363 .ptr_type_simple = .{
1362 const T = zir.Inst.Tag;1364 .is_allowzero = ptr_info.allowzero_token != null,
1363 const result = try addZIRUnOp(mod, scope, src, switch (ptr_info.size) {1365 .is_mutable = ptr_info.const_token == null,
1364 .One => if (mutable) T.single_mut_ptr_type else T.single_const_ptr_type,1366 .is_volatile = ptr_info.volatile_token != null,
1365 .Many => if (mutable) T.many_mut_ptr_type else T.many_const_ptr_type,1367 .size = ptr_info.size,
1366 .C => if (mutable) T.c_mut_ptr_type else T.c_const_ptr_type,1368 .elem_type = elem_type,
1367 .Slice => if (mutable) T.mut_slice_type else T.const_slice_type,1369 },
1368 }, child_type);1370 } });
1369 return rvalue(mod, scope, rl, result);1371 return rvalue(mod, scope, rl, result, node);
1370 }
1371
1372 var kw_args: std.meta.fieldInfo(zir.Inst.PtrType, .kw_args).field_type = .{};
1373 kw_args.size = ptr_info.size;
1374 kw_args.@"allowzero" = ptr_info.allowzero_token != null;
1375 if (ptr_info.ast.align_node != 0) {
1376 kw_args.@"align" = try expr(mod, scope, .none, ptr_info.ast.align_node);
1377 if (ptr_info.ast.bit_range_start != 0) {
1378 kw_args.align_bit_start = try expr(mod, scope, .none, ptr_info.ast.bit_range_start);
1379 kw_args.align_bit_end = try expr(mod, scope, .none, ptr_info.ast.bit_range_end);
1380 }
1381 }1372 }
1382 kw_args.mutable = ptr_info.const_token == null;1373
1383 kw_args.@"volatile" = ptr_info.volatile_token != null;1374 var sentinel_ref: zir.Inst.Ref = 0;
1384 const child_type = try typeExpr(mod, scope, ptr_info.ast.child_type);1375 var align_ref: zir.Inst.Ref = 0;
1376 var bit_start_ref: zir.Inst.Ref = 0;
1377 var bit_end_ref: zir.Inst.Ref = 0;
1378 var trailing_count: u32 = 0;
1379
1385 if (ptr_info.ast.sentinel != 0) {1380 if (ptr_info.ast.sentinel != 0) {
1386 kw_args.sentinel = try expr(mod, scope, .{ .ty = child_type }, ptr_info.ast.sentinel);1381 sentinel_ref = try expr(mod, scope, .{ .ty = elem_type }, ptr_info.ast.sentinel);
1382 trailing_count += 1;
1387 }1383 }
1388 const result = try addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);1384 if (ptr_info.ast.align_node != 0) {
1389 return rvalue(mod, scope, rl, result);1385 align_ref = try expr(mod, scope, .none, ptr_info.ast.align_node);
1386 trailing_count += 1;
1387 }
1388 if (ptr_info.ast.bit_range_start != 0) {
1389 assert(ptr_info.ast.bit_range_end != 0);
1390 bit_start_ref = try expr(mod, scope, .none, ptr_info.ast.bit_range_start);
1391 bit_end_ref = try expr(mod, scope, .none, ptr_info.ast.bit_range_end);
1392 trailing_count += 2;
1393 }
1394
1395 const gpa = gz.zir_code.gpa;
1396 try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1);
1397 try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1);
1398 try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len +
1399 @typeInfo(zir.Inst.PtrType).Struct.fields.len + trailing_count);
1400
1401 const payload_index = gz.zir_code.addExtraAssumeCapacity(zir.Inst.PtrType{ .elem_type = elem_type });
1402 if (sentinel_ref != 0) gz.zir_code.extra.appendAssumeCapacity(sentinel_ref);
1403 if (align_ref != 0) gz.zir_code.extra.appendAssumeCapacity(align_ref);
1404 if (bit_start_ref != 0) {
1405 gz.zir_code.extra.appendAssumeCapacity(bit_start_ref);
1406 gz.zir_code.extra.appendAssumeCapacity(bit_end_ref);
1407 }
1408
1409 const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len);
1410 const result = new_index + gz.zir_code.ref_start_index;
1411 gz.zir_code.instructions.appendAssumeCapacity(.{ .tag = .ptr_type, .data = .{
1412 .ptr_type = .{
1413 .flags = .{
1414 .is_allowzero = ptr_info.allowzero_token != null,
1415 .is_mutable = ptr_info.const_token == null,
1416 .is_volatile = ptr_info.volatile_token != null,
1417 .has_sentinel = sentinel_ref != 0,
1418 .has_align = align_ref != 0,
1419 .has_bit_range = bit_start_ref != 0,
1420 },
1421 .size = ptr_info.size,
1422 .payload_index = payload_index,
1423 },
1424 } });
1425 gz.instructions.appendAssumeCapacity(new_index);
1426
1427 return rvalue(mod, scope, rl, result, node);
1390}1428}
13911429
1392fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !zir.Inst.Ref {1430fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !zir.Inst.Ref {
src/zir.zig+4-5
...@@ -1146,9 +1146,8 @@ pub const Inst = struct {...@@ -1146,9 +1146,8 @@ pub const Inst = struct {
1146 is_volatile: bool,1146 is_volatile: bool,
1147 has_sentinel: bool,1147 has_sentinel: bool,
1148 has_align: bool,1148 has_align: bool,
1149 has_bit_start: bool,1149 has_bit_range: bool,
1150 has_bit_end: bool,1150 _: u2 = undefined,
1151 _: u1 = undefined,
1152 },1151 },
1153 size: std.builtin.TypeInfo.Pointer.Size,1152 size: std.builtin.TypeInfo.Pointer.Size,
1154 /// Index into extra. See `PtrType`.1153 /// Index into extra. See `PtrType`.
...@@ -1244,8 +1243,8 @@ pub const Inst = struct {...@@ -1244,8 +1243,8 @@ pub const Inst = struct {
1244 /// trailing Ref fields:1243 /// trailing Ref fields:
1245 /// 0. sentinel: Ref // if `has_sentinel` flag is set1244 /// 0. sentinel: Ref // if `has_sentinel` flag is set
1246 /// 1. align: Ref // if `has_align` flag is set1245 /// 1. align: Ref // if `has_align` flag is set
1247 /// 2. bit_start: Ref // if `has_bit_start` flag is set1246 /// 2. bit_start: Ref // if `has_bit_range` flag is set
1248 /// 3. bit_end: Ref // if `has_bit_end` flag is set1247 /// 3. bit_end: Ref // if `has_bit_range` flag is set
1249 pub const PtrType = struct {1248 pub const PtrType = struct {
1250 elem_type: Ref,1249 elem_type: Ref,
1251 };1250 };