| author | |
| committer | |
| log | ba9b9cb38dbd66c7a600606c5599c80b115e0f85 |
| tree | 0709a9bef6a253f2ec082085a9c95cf33069fcf7 |
| parent | 2eef83e85f1f701fb67d410d3ffc1a1b344b4c13 |
5 files changed, 51 insertions(+), 10 deletions(-)
BRANCH_TODO+1| ... | ... | @@ -1,3 +1,4 @@ |
| 1 | * decouple AstGen from Module, Compilation | |
| 1 | 2 | * modify dbg_stmt ZIR instructions to have line/column rather than node indexes |
| 2 | 3 | * AstGen threadlocal |
| 3 | 4 | * extern "foo" for vars and for functions |
src/AstGen.zig+9-3| ... | ... | @@ -1048,10 +1048,12 @@ pub fn fnProtoExpr( |
| 1048 | 1048 | assert(param_type_i == param_count); |
| 1049 | 1049 | } |
| 1050 | 1050 | |
| 1051 | if (fn_proto.ast.align_expr != 0) { | |
| 1052 | return astgen.failNode(fn_proto.ast.align_expr, "TODO: AstGen: implement function prototypes with alignment expressions", .{}); | |
| 1051 | const align_inst: Zir.Inst.Ref = if (fn_proto.ast.align_expr == 0) .none else inst: { | |
| 1052 | break :inst try expr(gz, scope, align_rl, fn_proto.ast.align_expr); | |
| 1053 | }; | |
| 1054 | if (fn_proto.ast.section_expr != 0) { | |
| 1055 | return astgen.failNode(fn_proto.ast.section_expr, "linksection not allowed on function prototypes", .{}); | |
| 1053 | 1056 | } |
| 1054 | assert(fn_proto.ast.section_expr == 0); // caught by the parser | |
| 1055 | 1057 | |
| 1056 | 1058 | const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; |
| 1057 | 1059 | const is_inferred_error = token_tags[maybe_bang] == .bang; |
| ... | ... | @@ -1081,6 +1083,7 @@ pub fn fnProtoExpr( |
| 1081 | 1083 | .param_types = param_types, |
| 1082 | 1084 | .body = &[0]Zir.Inst.Index{}, |
| 1083 | 1085 | .cc = cc, |
| 1086 | .align_inst = align_inst, | |
| 1084 | 1087 | .lib_name = 0, |
| 1085 | 1088 | .is_var_args = is_var_args, |
| 1086 | 1089 | .is_inferred_error = false, |
| ... | ... | @@ -2794,6 +2797,7 @@ fn fnDecl( |
| 2794 | 2797 | .param_types = param_types, |
| 2795 | 2798 | .body = &[0]Zir.Inst.Index{}, |
| 2796 | 2799 | .cc = cc, |
| 2800 | .align_inst = .none, // passed in the per-decl data | |
| 2797 | 2801 | .lib_name = lib_name, |
| 2798 | 2802 | .is_var_args = is_var_args, |
| 2799 | 2803 | .is_inferred_error = false, |
| ... | ... | @@ -2866,6 +2870,7 @@ fn fnDecl( |
| 2866 | 2870 | .param_types = param_types, |
| 2867 | 2871 | .body = fn_gz.instructions.items, |
| 2868 | 2872 | .cc = cc, |
| 2873 | .align_inst = .none, // passed in the per-decl data | |
| 2869 | 2874 | .lib_name = lib_name, |
| 2870 | 2875 | .is_var_args = is_var_args, |
| 2871 | 2876 | .is_inferred_error = is_inferred_error, |
| ... | ... | @@ -3167,6 +3172,7 @@ fn testDecl( |
| 3167 | 3172 | .param_types = &[0]Zir.Inst.Ref{}, |
| 3168 | 3173 | .body = fn_block.instructions.items, |
| 3169 | 3174 | .cc = .none, |
| 3175 | .align_inst = .none, | |
| 3170 | 3176 | .lib_name = 0, |
| 3171 | 3177 | .is_var_args = false, |
| 3172 | 3178 | .is_inferred_error = true, |
src/Module.zig+11-3| ... | ... | @@ -1372,6 +1372,7 @@ pub const Scope = struct { |
| 1372 | 1372 | body: []const Zir.Inst.Index, |
| 1373 | 1373 | ret_ty: Zir.Inst.Ref, |
| 1374 | 1374 | cc: Zir.Inst.Ref, |
| 1375 | align_inst: Zir.Inst.Ref, | |
| 1375 | 1376 | lib_name: u32, |
| 1376 | 1377 | is_var_args: bool, |
| 1377 | 1378 | is_inferred_error: bool, |
| ... | ... | @@ -1385,12 +1386,15 @@ pub const Scope = struct { |
| 1385 | 1386 | try gz.instructions.ensureUnusedCapacity(gpa, 1); |
| 1386 | 1387 | try astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| 1387 | 1388 | |
| 1388 | if (args.cc != .none or args.lib_name != 0 or args.is_var_args or args.is_test) { | |
| 1389 | if (args.cc != .none or args.lib_name != 0 or | |
| 1390 | args.is_var_args or args.is_test or args.align_inst != .none) | |
| 1391 | { | |
| 1389 | 1392 | try astgen.extra.ensureUnusedCapacity( |
| 1390 | 1393 | gpa, |
| 1391 | 1394 | @typeInfo(Zir.Inst.ExtendedFunc).Struct.fields.len + |
| 1392 | 1395 | args.param_types.len + args.body.len + |
| 1393 | 1396 | @boolToInt(args.lib_name != 0) + |
| 1397 | @boolToInt(args.align_inst != .none) + | |
| 1394 | 1398 | @boolToInt(args.cc != .none), |
| 1395 | 1399 | ); |
| 1396 | 1400 | const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedFunc{ |
| ... | ... | @@ -1399,11 +1403,14 @@ pub const Scope = struct { |
| 1399 | 1403 | .param_types_len = @intCast(u32, args.param_types.len), |
| 1400 | 1404 | .body_len = @intCast(u32, args.body.len), |
| 1401 | 1405 | }); |
| 1406 | if (args.lib_name != 0) { | |
| 1407 | astgen.extra.appendAssumeCapacity(args.lib_name); | |
| 1408 | } | |
| 1402 | 1409 | if (args.cc != .none) { |
| 1403 | 1410 | astgen.extra.appendAssumeCapacity(@enumToInt(args.cc)); |
| 1404 | 1411 | } |
| 1405 | if (args.lib_name != 0) { | |
| 1406 | astgen.extra.appendAssumeCapacity(args.lib_name); | |
| 1412 | if (args.align_inst != .none) { | |
| 1413 | astgen.extra.appendAssumeCapacity(@enumToInt(args.align_inst)); | |
| 1407 | 1414 | } |
| 1408 | 1415 | astgen.appendRefsAssumeCapacity(args.param_types); |
| 1409 | 1416 | astgen.extra.appendSliceAssumeCapacity(args.body); |
| ... | ... | @@ -1418,6 +1425,7 @@ pub const Scope = struct { |
| 1418 | 1425 | .is_inferred_error = args.is_inferred_error, |
| 1419 | 1426 | .has_lib_name = args.lib_name != 0, |
| 1420 | 1427 | .has_cc = args.cc != .none, |
| 1428 | .has_align = args.align_inst != .none, | |
| 1421 | 1429 | .is_test = args.is_test, |
| 1422 | 1430 | }), |
| 1423 | 1431 | .operand = payload_index, |
src/Sema.zig+16-1| ... | ... | @@ -2737,6 +2737,7 @@ fn zirFunc( |
| 2737 | 2737 | body, |
| 2738 | 2738 | extra.data.return_type, |
| 2739 | 2739 | .Unspecified, |
| 2740 | Value.initTag(.null_value), | |
| 2740 | 2741 | false, |
| 2741 | 2742 | inferred_error_set, |
| 2742 | 2743 | ); |
| ... | ... | @@ -2750,6 +2751,7 @@ fn funcCommon( |
| 2750 | 2751 | body: []const Zir.Inst.Index, |
| 2751 | 2752 | zir_return_type: Zir.Inst.Ref, |
| 2752 | 2753 | cc: std.builtin.CallingConvention, |
| 2754 | align_val: Value, | |
| 2753 | 2755 | var_args: bool, |
| 2754 | 2756 | inferred_error_set: bool, |
| 2755 | 2757 | ) InnerError!*Inst { |
| ... | ... | @@ -2762,7 +2764,7 @@ fn funcCommon( |
| 2762 | 2764 | } |
| 2763 | 2765 | |
| 2764 | 2766 | // Hot path for some common function types. |
| 2765 | if (zir_param_types.len == 0 and !var_args) { | |
| 2767 | if (zir_param_types.len == 0 and !var_args and align_val.tag() == .null_value) { | |
| 2766 | 2768 | if (return_type.zigTypeTag() == .NoReturn and cc == .Unspecified) { |
| 2767 | 2769 | return sema.mod.constType(sema.arena, src, Type.initTag(.fn_noreturn_no_args)); |
| 2768 | 2770 | } |
| ... | ... | @@ -2789,6 +2791,10 @@ fn funcCommon( |
| 2789 | 2791 | param_types[i] = try sema.resolveType(block, src, param_type); |
| 2790 | 2792 | } |
| 2791 | 2793 | |
| 2794 | if (align_val.tag() != .null_value) { | |
| 2795 | return sema.mod.fail(&block.base, src, "TODO implement support for function prototypes to have alignment specified", .{}); | |
| 2796 | } | |
| 2797 | ||
| 2792 | 2798 | const fn_ty = try Type.Tag.function.create(sema.arena, .{ |
| 2793 | 2799 | .param_types = param_types, |
| 2794 | 2800 | .return_type = return_type, |
| ... | ... | @@ -5432,6 +5438,7 @@ fn zirFuncExtended( |
| 5432 | 5438 | const extra = sema.code.extraData(Zir.Inst.ExtendedFunc, extended.operand); |
| 5433 | 5439 | const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; |
| 5434 | 5440 | const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = extra.data.src_node }; |
| 5441 | const align_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at align | |
| 5435 | 5442 | const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small); |
| 5436 | 5443 | |
| 5437 | 5444 | var extra_index: usize = extra.end; |
| ... | ... | @@ -5455,6 +5462,13 @@ fn zirFuncExtended( |
| 5455 | 5462 | break :blk cc; |
| 5456 | 5463 | } else .Unspecified; |
| 5457 | 5464 | |
| 5465 | const align_val: Value = if (small.has_align) blk: { | |
| 5466 | const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); | |
| 5467 | extra_index += 1; | |
| 5468 | const align_tv = try sema.resolveInstConst(block, align_src, align_ref); | |
| 5469 | break :blk align_tv.val; | |
| 5470 | } else Value.initTag(.null_value); | |
| 5471 | ||
| 5458 | 5472 | const param_types = sema.code.refSlice(extra_index, extra.data.param_types_len); |
| 5459 | 5473 | extra_index += param_types.len; |
| 5460 | 5474 | |
| ... | ... | @@ -5467,6 +5481,7 @@ fn zirFuncExtended( |
| 5467 | 5481 | body, |
| 5468 | 5482 | extra.data.return_type, |
| 5469 | 5483 | cc, |
| 5484 | align_val, | |
| 5470 | 5485 | small.is_var_args, |
| 5471 | 5486 | small.is_inferred_error, |
| 5472 | 5487 | ); |
src/Zir.zig+14-3| ... | ... | @@ -2189,8 +2189,9 @@ pub const Inst = struct { |
| 2189 | 2189 | /// Trailing: |
| 2190 | 2190 | /// 0. lib_name: u32, // null terminated string index, if has_lib_name is set |
| 2191 | 2191 | /// 1. cc: Ref, // if has_cc is set |
| 2192 | /// 2. param_type: Ref // for each param_types_len | |
| 2193 | /// 3. body: Index // for each body_len | |
| 2192 | /// 2. align: Ref, // if has_align is set | |
| 2193 | /// 3. param_type: Ref // for each param_types_len | |
| 2194 | /// 4. body: Index // for each body_len | |
| 2194 | 2195 | pub const ExtendedFunc = struct { |
| 2195 | 2196 | src_node: i32, |
| 2196 | 2197 | return_type: Ref, |
| ... | ... | @@ -2202,8 +2203,9 @@ pub const Inst = struct { |
| 2202 | 2203 | is_inferred_error: bool, |
| 2203 | 2204 | has_lib_name: bool, |
| 2204 | 2205 | has_cc: bool, |
| 2206 | has_align: bool, | |
| 2205 | 2207 | is_test: bool, |
| 2206 | _: u11 = undefined, | |
| 2208 | _: u10 = undefined, | |
| 2207 | 2209 | }; |
| 2208 | 2210 | }; |
| 2209 | 2211 | |
| ... | ... | @@ -3966,6 +3968,7 @@ const Writer = struct { |
| 3966 | 3968 | inferred_error_set, |
| 3967 | 3969 | false, |
| 3968 | 3970 | .none, |
| 3971 | .none, | |
| 3969 | 3972 | body, |
| 3970 | 3973 | src, |
| 3971 | 3974 | ); |
| ... | ... | @@ -3988,6 +3991,11 @@ const Writer = struct { |
| 3988 | 3991 | extra_index += 1; |
| 3989 | 3992 | break :blk cc; |
| 3990 | 3993 | }; |
| 3994 | const align_inst: Inst.Ref = if (!small.has_align) .none else blk: { | |
| 3995 | const align_inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]); | |
| 3996 | extra_index += 1; | |
| 3997 | break :blk align_inst; | |
| 3998 | }; | |
| 3991 | 3999 | |
| 3992 | 4000 | const param_types = self.code.refSlice(extra_index, extra.data.param_types_len); |
| 3993 | 4001 | extra_index += param_types.len; |
| ... | ... | @@ -4001,6 +4009,7 @@ const Writer = struct { |
| 4001 | 4009 | small.is_inferred_error, |
| 4002 | 4010 | small.is_var_args, |
| 4003 | 4011 | cc, |
| 4012 | align_inst, | |
| 4004 | 4013 | body, |
| 4005 | 4014 | src, |
| 4006 | 4015 | ); |
| ... | ... | @@ -4053,6 +4062,7 @@ const Writer = struct { |
| 4053 | 4062 | inferred_error_set: bool, |
| 4054 | 4063 | var_args: bool, |
| 4055 | 4064 | cc: Inst.Ref, |
| 4065 | align_inst: Inst.Ref, | |
| 4056 | 4066 | body: []const Inst.Index, |
| 4057 | 4067 | src: LazySrcLoc, |
| 4058 | 4068 | ) !void { |
| ... | ... | @@ -4064,6 +4074,7 @@ const Writer = struct { |
| 4064 | 4074 | try stream.writeAll("], "); |
| 4065 | 4075 | try self.writeInstRef(stream, ret_ty); |
| 4066 | 4076 | try self.writeOptionalInstRef(stream, ", cc=", cc); |
| 4077 | try self.writeOptionalInstRef(stream, ", align=", align_inst); | |
| 4067 | 4078 | try self.writeFlag(stream, ", vargs", var_args); |
| 4068 | 4079 | try self.writeFlag(stream, ", inferror", inferred_error_set); |
| 4069 | 4080 |