astgen: finish updating expressions to new mem layout

Now all that is left is compile errors and whatever regressions this
branch introduced.
This commit is contained in:
Andrew Kelley 2021-02-17 20:59:21 -07:00
parent 4b226286e8
commit c66481f9bc
6 changed files with 456 additions and 326 deletions

View File

@ -1528,8 +1528,9 @@ pub const Tree = struct {
pub fn switchCaseOne(tree: Tree, node: Node.Index) full.SwitchCase {
const data = &tree.nodes.items(.data)[node];
const values: *[1]Node.Index = &data.lhs;
return tree.fullSwitchCase(.{
.values = if (data.lhs == 0) &.{} else @ptrCast([*]Node.Index, &data.lhs)[0..1],
.values = if (data.lhs == 0) values[0..0] else values[0..1],
.arrow_token = tree.nodes.items(.main_token)[node],
.target_expr = data.rhs,
});
@ -2532,8 +2533,8 @@ pub const Node = struct {
@"defer",
/// lhs catch rhs
/// lhs catch |err| rhs
/// main_token is the catch
/// payload is determined by looking at the prev tokens before rhs.
/// main_token is the `catch` keyword.
/// payload is determined by looking at the next token after the `catch` keyword.
@"catch",
/// `lhs.a`. main_token is the dot. rhs is the identifier token index.
field_access,

View File

@ -416,9 +416,9 @@ fn renderExpression(ais: *Ais, tree: ast.Tree, node: ast.Node.Index, space: Spac
return renderToken(ais, tree, rbracket, space); // ]
},
.slice_open => try renderSlice(ais, tree, tree.sliceOpen(node), space),
.slice => try renderSlice(ais, tree, tree.slice(node), space),
.slice_sentinel => try renderSlice(ais, tree, tree.sliceSentinel(node), space),
.slice_open => return renderSlice(ais, tree, tree.sliceOpen(node), space),
.slice => return renderSlice(ais, tree, tree.slice(node), space),
.slice_sentinel => return renderSlice(ais, tree, tree.sliceSentinel(node), space),
.deref => {
try renderExpression(ais, tree, datas[node].lhs, .none);

View File

@ -1163,16 +1163,16 @@ fn astgenAndSemaFn(
}
assert(param_type_i == param_count);
}
if (fn_proto.lib_name) |lib_name| blk: {
if (fn_proto.lib_name) |lib_name_token| blk: {
// TODO call std.zig.parseStringLiteral
const lib_name_str = mem.trim(u8, tree.tokenSlice(lib_name), "\"");
const lib_name_str = mem.trim(u8, tree.tokenSlice(lib_name_token), "\"");
log.debug("extern fn symbol expected in lib '{s}'", .{lib_name_str});
const target = mod.comp.getTarget();
if (target_util.is_libc_lib_name(target, lib_name_str)) {
if (!mod.comp.bin_file.options.link_libc) {
return mod.failTok(
&fn_type_scope.base,
lib_name,
lib_name_token,
"dependency on libc must be explicitly specified in the build command",
.{},
);
@ -1183,7 +1183,7 @@ fn astgenAndSemaFn(
if (!mod.comp.bin_file.options.link_libcpp) {
return mod.failTok(
&fn_type_scope.base,
lib_name,
lib_name_token,
"dependency on libc++ must be explicitly specified in the build command",
.{},
);
@ -1193,17 +1193,17 @@ fn astgenAndSemaFn(
if (!target.isWasm() and !mod.comp.bin_file.options.pic) {
return mod.failTok(
&fn_type_scope.base,
lib_name,
lib_name_token,
"dependency on dynamic library '{s}' requires enabling Position Independent Code. Fixed by `-l{s}` or `-fPIC`.",
.{ lib_name, lib_name },
.{ lib_name_str, lib_name_str },
);
}
mod.comp.stage1AddLinkLib(lib_name_str) catch |err| {
return mod.failTok(
&fn_type_scope.base,
lib_name,
lib_name_token,
"unable to add link lib '{s}': {s}",
.{ lib_name, @errorName(err) },
.{ lib_name_str, @errorName(err) },
);
};
}

File diff suppressed because it is too large Load Diff

View File

@ -343,6 +343,8 @@ pub const Inst = struct {
void_value,
/// A switch expression.
switchbr,
/// Same as `switchbr` but the target is a pointer to the value being switched on.
switchbr_ref,
/// A range in a switch case, `lhs...rhs`.
/// Only checks that `lhs >= rhs` if they are ints, everything else is
/// validated by the .switch instruction.
@ -453,6 +455,8 @@ pub const Inst = struct {
.block_comptime_flat,
=> Block,
.switchbr, .switchbr_ref => SwitchBr,
.arg => Arg,
.array_type_sentinel => ArrayTypeSentinel,
.@"break" => Break,
@ -488,7 +492,6 @@ pub const Inst = struct {
.enum_type => EnumType,
.union_type => UnionType,
.struct_type => StructType,
.switchbr => SwitchBr,
};
}
@ -617,7 +620,6 @@ pub const Inst = struct {
.struct_type,
.void_value,
.switch_range,
.switchbr,
=> false,
.@"break",
@ -632,6 +634,8 @@ pub const Inst = struct {
.container_field_named,
.container_field_typed,
.container_field,
.switchbr,
.switchbr_ref,
=> true,
};
}
@ -730,6 +734,8 @@ pub const Inst = struct {
kw_args: struct {},
};
// TODO break this into multiple call instructions to avoid paying the cost
// of the calling convention field most of the time.
pub const Call = struct {
pub const base_tag = Tag.call;
base: Inst,
@ -737,10 +743,9 @@ pub const Inst = struct {
positionals: struct {
func: *Inst,
args: []*Inst,
},
kw_args: struct {
modifier: std.builtin.CallOptions.Modifier = .auto,
},
kw_args: struct {},
};
pub const DeclRef = struct {
@ -1185,7 +1190,6 @@ pub const Inst = struct {
};
pub const SwitchBr = struct {
pub const base_tag = Tag.switchbr;
base: Inst,
positionals: struct {
@ -1194,14 +1198,12 @@ pub const Inst = struct {
items: []*Inst,
cases: []Case,
else_body: Body,
},
kw_args: struct {
/// Pointer to first range if such exists.
range: ?*Inst = null,
special_prong: SpecialProng = .none,
},
kw_args: struct {},
// Not anonymous due to stage1 limitations
pub const SpecialProng = enum {
none,
@"else",

View File

@ -154,7 +154,8 @@ pub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!
.bool_and => return zirBoolOp(mod, scope, old_inst.castTag(.bool_and).?),
.bool_or => return zirBoolOp(mod, scope, old_inst.castTag(.bool_or).?),
.void_value => return mod.constVoid(scope, old_inst.src),
.switchbr => return zirSwitchBr(mod, scope, old_inst.castTag(.switchbr).?),
.switchbr => return zirSwitchBr(mod, scope, old_inst.castTag(.switchbr).?, false),
.switchbr_ref => return zirSwitchBr(mod, scope, old_inst.castTag(.switchbr).?, true),
.switch_range => return zirSwitchRange(mod, scope, old_inst.castTag(.switch_range).?),
.container_field_named,
@ -1554,10 +1555,15 @@ fn zirSwitchRange(mod: *Module, scope: *Scope, inst: *zir.Inst.BinOp) InnerError
return mod.constVoid(scope, inst.base.src);
}
fn zirSwitchBr(mod: *Module, scope: *Scope, inst: *zir.Inst.SwitchBr) InnerError!*Inst {
fn zirSwitchBr(mod: *Module, scope: *Scope, inst: *zir.Inst.SwitchBr, ref: bool) InnerError!*Inst {
const tracy = trace(@src());
defer tracy.end();
const target = try resolveInst(mod, scope, inst.positionals.target);
const target_ptr = try resolveInst(mod, scope, inst.positionals.target);
const target = if (ref)
try mod.analyzeDeref(scope, inst.base.src, target_ptr, inst.positionals.target.src)
else
target_ptr;
try validateSwitch(mod, scope, target, inst);
if (try mod.resolveDefinedValue(scope, target)) |target_val| {