Commit 7efc2a0626
Changed files (2)
src/AstGen.zig
@@ -8271,17 +8271,31 @@ fn nodeMayNeedMemoryLocation(tree: *const Ast, start_node: Ast.Node.Index) bool
}
},
- .builtin_call,
- .builtin_call_comma,
- .builtin_call_two,
- .builtin_call_two_comma,
- => {
+ .builtin_call_two, .builtin_call_two_comma => {
+ const builtin_token = main_tokens[node];
+ const builtin_name = tree.tokenSlice(builtin_token);
+ // If the builtin is an invalid name, we don't cause an error here; instead
+ // let it pass, and the error will be "invalid builtin function" later.
+ const builtin_info = BuiltinFn.list.get(builtin_name) orelse return false;
+ switch (builtin_info.needs_mem_loc) {
+ .never => return false,
+ .always => return true,
+ .forward1 => node = node_datas[node].rhs,
+ }
+ },
+
+ .builtin_call, .builtin_call_comma => {
+ const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs];
const builtin_token = main_tokens[node];
const builtin_name = tree.tokenSlice(builtin_token);
// If the builtin is an invalid name, we don't cause an error here; instead
// let it pass, and the error will be "invalid builtin function" later.
const builtin_info = BuiltinFn.list.get(builtin_name) orelse return false;
- return builtin_info.needs_mem_loc;
+ switch (builtin_info.needs_mem_loc) {
+ .never => return false,
+ .always => return true,
+ .forward1 => node = params[1],
+ }
},
}
}
src/BuiltinFn.zig
@@ -110,10 +110,19 @@ pub const Tag = enum {
Vector,
};
+pub const MemLocRequirement = enum {
+ /// The builtin never needs a memory location.
+ never,
+ /// The builtin always needs a memory location.
+ always,
+ /// The builtin forwards the question to argument at index 1.
+ forward1,
+};
+
tag: Tag,
-/// `true` if the builtin call can take advantage of a result location pointer.
-needs_mem_loc: bool = false,
+/// Info about the builtin call's ability to take advantage of a result location pointer.
+needs_mem_loc: MemLocRequirement = .never,
/// `true` if the builtin call can be the left-hand side of an expression (assigned to).
allows_lvalue: bool = false,
/// The number of parameters to this builtin function. `null` means variable number
@@ -148,7 +157,7 @@ pub const list = list: {
"@as",
.{
.tag = .as,
- .needs_mem_loc = true,
+ .needs_mem_loc = .forward1,
.param_count = 2,
},
},
@@ -184,7 +193,7 @@ pub const list = list: {
"@bitCast",
.{
.tag = .bit_cast,
- .needs_mem_loc = true,
+ .needs_mem_loc = .forward1,
.param_count = 2,
},
},
@@ -248,7 +257,7 @@ pub const list = list: {
"@call",
.{
.tag = .call,
- .needs_mem_loc = true,
+ .needs_mem_loc = .always,
.param_count = 3,
},
},
@@ -410,7 +419,7 @@ pub const list = list: {
"@field",
.{
.tag = .field,
- .needs_mem_loc = true,
+ .needs_mem_loc = .always,
.param_count = 2,
.allows_lvalue = true,
},
@@ -699,7 +708,6 @@ pub const list = list: {
"@splat",
.{
.tag = .splat,
- .needs_mem_loc = true,
.param_count = 2,
},
},
@@ -714,7 +722,7 @@ pub const list = list: {
"@src",
.{
.tag = .src,
- .needs_mem_loc = true,
+ .needs_mem_loc = .always,
.param_count = 0,
},
},
@@ -869,7 +877,7 @@ pub const list = list: {
"@unionInit",
.{
.tag = .union_init,
- .needs_mem_loc = true,
+ .needs_mem_loc = .always,
.param_count = 3,
},
},