authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-22 16:31:51-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-22 16:31:51-07:00
log7c453b91b85bab6800d24feb57c4f35b8ce48d57
treecf091f9555b03f3a28eba96b1774fb6e62d78e99
parent3d637e6dd257d617867e12ac949d966d2c2ef48a

AstGen: implement `@extern` builtin


6 files changed, 66 insertions(+), 0 deletions(-)

src/AstGen.zig+13
...@@ -6135,6 +6135,9 @@ fn builtinCall(...@@ -6135,6 +6135,9 @@ fn builtinCall(
6135 }6135 }
6136 const ident_token = main_tokens[params[0]];6136 const ident_token = main_tokens[params[0]];
6137 const decl_name = try gz.identAsString(ident_token);6137 const decl_name = try gz.identAsString(ident_token);
6138 // TODO look for local variables in scope matching `decl_name` and emit a compile
6139 // error. Only top-level declarations can be exported. Until this is done, the
6140 // compile error will end up being "use of undeclared identifier" in Sema.
6138 const options = try comptimeExpr(gz, scope, .{ .ty = .export_options_type }, params[1]);6141 const options = try comptimeExpr(gz, scope, .{ .ty = .export_options_type }, params[1]);
6139 _ = try gz.addPlNode(.@"export", node, Zir.Inst.Export{6142 _ = try gz.addPlNode(.@"export", node, Zir.Inst.Export{
6140 .decl_name = decl_name,6143 .decl_name = decl_name,
...@@ -6142,6 +6145,16 @@ fn builtinCall(...@@ -6142,6 +6145,16 @@ fn builtinCall(
6142 });6145 });
6143 return rvalue(gz, scope, rl, .void_value, node);6146 return rvalue(gz, scope, rl, .void_value, node);
6144 },6147 },
6148 .@"extern" => {
6149 const type_inst = try typeExpr(gz, scope, params[0]);
6150 const options = try comptimeExpr(gz, scope, .{ .ty = .extern_options_type }, params[1]);
6151 const result = try gz.addExtendedPayload(.builtin_extern, Zir.Inst.BinNode{
6152 .node = gz.nodeIndexToRelative(node),
6153 .lhs = type_inst,
6154 .rhs = options,
6155 });
6156 return rvalue(gz, scope, rl, result, node);
6157 },
61456158
6146 .breakpoint => return simpleNoOpVoid(gz, scope, rl, node, .breakpoint),6159 .breakpoint => return simpleNoOpVoid(gz, scope, rl, node, .breakpoint),
6147 .fence => return simpleNoOpVoid(gz, scope, rl, node, .fence),6160 .fence => return simpleNoOpVoid(gz, scope, rl, node, .fence),
src/BuiltinFn.zig+8
...@@ -39,6 +39,7 @@ pub const Tag = enum {...@@ -39,6 +39,7 @@ pub const Tag = enum {
39 error_to_int,39 error_to_int,
40 err_set_cast,40 err_set_cast,
41 @"export",41 @"export",
42 @"extern",
42 fence,43 fence,
43 field,44 field,
44 field_parent_ptr,45 field_parent_ptr,
...@@ -387,6 +388,13 @@ pub const list = list: {...@@ -387,6 +388,13 @@ pub const list = list: {
387 .param_count = 2,388 .param_count = 2,
388 },389 },
389 },390 },
391 .{
392 "@extern",
393 .{
394 .tag = .@"extern",
395 .param_count = 2,
396 },
397 },
390 .{398 .{
391 "@fence",399 "@fence",
392 .{400 .{
src/Sema.zig+11
...@@ -517,6 +517,7 @@ fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro...@@ -517,6 +517,7 @@ fn zirExtended(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerErro
517 .frame => return sema.zirFrame( block, extended),517 .frame => return sema.zirFrame( block, extended),
518 .frame_address => return sema.zirFrameAddress( block, extended),518 .frame_address => return sema.zirFrameAddress( block, extended),
519 .alloc => return sema.zirAllocExtended( block, extended),519 .alloc => return sema.zirAllocExtended( block, extended),
520 .builtin_extern => return sema.zirBuiltinExtern( block, extended),
520 .c_undef => return sema.zirCUndef( block, extended),521 .c_undef => return sema.zirCUndef( block, extended),
521 .c_include => return sema.zirCInclude( block, extended),522 .c_include => return sema.zirCInclude( block, extended),
522 .c_define => return sema.zirCDefine( block, extended),523 .c_define => return sema.zirCDefine( block, extended),
...@@ -5488,6 +5489,16 @@ fn zirWasmMemoryGrow(...@@ -5488,6 +5489,16 @@ fn zirWasmMemoryGrow(
5488 return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirWasmMemoryGrow", .{});5489 return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirWasmMemoryGrow", .{});
5489}5490}
54905491
5492fn zirBuiltinExtern(
5493 sema: *Sema,
5494 block: *Scope.Block,
5495 extended: Zir.Inst.Extended.InstData,
5496) InnerError!*Inst {
5497 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
5498 const src: LazySrcLoc = .{ .node_offset = extra.node };
5499 return sema.mod.fail(&block.base, src, "TODO: implement Sema.zirBuiltinExtern", .{});
5500}
5501
5491fn requireFunctionBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void {5502fn requireFunctionBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void {
5492 if (sema.func == null) {5503 if (sema.func == null) {
5493 return sema.mod.fail(&block.base, src, "instruction illegal outside function body", .{});5504 return sema.mod.fail(&block.base, src, "instruction illegal outside function body", .{});
src/Zir.zig+9
...@@ -1258,6 +1258,9 @@ pub const Inst = struct {...@@ -1258,6 +1258,9 @@ pub const Inst = struct {
1258 /// * 0b0X00 - 1=const, 0=var1258 /// * 0b0X00 - 1=const, 0=var
1259 /// * 0bX000 - is comptime1259 /// * 0bX000 - is comptime
1260 alloc,1260 alloc,
1261 /// The `@extern` builtin.
1262 /// `operand` is payload index to `BinNode`.
1263 builtin_extern,
1261 /// `operand` is payload index to `UnNode`.1264 /// `operand` is payload index to `UnNode`.
1262 c_undef,1265 c_undef,
1263 /// `operand` is payload index to `UnNode`.1266 /// `operand` is payload index to `UnNode`.
...@@ -1353,6 +1356,7 @@ pub const Inst = struct {...@@ -1353,6 +1356,7 @@ pub const Inst = struct {
1353 reduce_op_type,1356 reduce_op_type,
1354 call_options_type,1357 call_options_type,
1355 export_options_type,1358 export_options_type,
1359 extern_options_type,
13561360
1357 /// `undefined` (untyped)1361 /// `undefined` (untyped)
1358 undef,1362 undef,
...@@ -1580,6 +1584,10 @@ pub const Inst = struct {...@@ -1580,6 +1584,10 @@ pub const Inst = struct {
1580 .ty = Type.initTag(.type),1584 .ty = Type.initTag(.type),
1581 .val = Value.initTag(.export_options_type),1585 .val = Value.initTag(.export_options_type),
1582 },1586 },
1587 .extern_options_type = .{
1588 .ty = Type.initTag(.type),
1589 .val = Value.initTag(.extern_options_type),
1590 },
15831591
1584 .undef = .{1592 .undef = .{
1585 .ty = Type.initTag(.@"undefined"),1593 .ty = Type.initTag(.@"undefined"),
...@@ -2598,6 +2606,7 @@ const Writer = struct {...@@ -2598,6 +2606,7 @@ const Writer = struct {
25982606
2599 .func,2607 .func,
2600 .alloc,2608 .alloc,
2609 .builtin_extern,
2601 .c_undef,2610 .c_undef,
2602 .c_include,2611 .c_include,
2603 .c_define,2612 .c_define,
src/type.zig+18
...@@ -100,6 +100,7 @@ pub const Type = extern union {...@@ -100,6 +100,7 @@ pub const Type = extern union {
100 .@"struct",100 .@"struct",
101 .call_options,101 .call_options,
102 .export_options,102 .export_options,
103 .extern_options,
103 => return .Struct,104 => return .Struct,
104105
105 .enum_full,106 .enum_full,
...@@ -618,6 +619,7 @@ pub const Type = extern union {...@@ -618,6 +619,7 @@ pub const Type = extern union {
618 .reduce_op,619 .reduce_op,
619 .call_options,620 .call_options,
620 .export_options,621 .export_options,
622 .extern_options,
621 => unreachable,623 => unreachable,
622624
623 .array_u8,625 .array_u8,
...@@ -797,6 +799,7 @@ pub const Type = extern union {...@@ -797,6 +799,7 @@ pub const Type = extern union {
797 .reduce_op => return writer.writeAll("std.builtin.ReduceOp"),799 .reduce_op => return writer.writeAll("std.builtin.ReduceOp"),
798 .call_options => return writer.writeAll("std.builtin.CallOptions"),800 .call_options => return writer.writeAll("std.builtin.CallOptions"),
799 .export_options => return writer.writeAll("std.builtin.ExportOptions"),801 .export_options => return writer.writeAll("std.builtin.ExportOptions"),
802 .extern_options => return writer.writeAll("std.builtin.ExternOptions"),
800 .function => {803 .function => {
801 const payload = ty.castTag(.function).?.data;804 const payload = ty.castTag(.function).?.data;
802 try writer.writeAll("fn(");805 try writer.writeAll("fn(");
...@@ -1012,6 +1015,7 @@ pub const Type = extern union {...@@ -1012,6 +1015,7 @@ pub const Type = extern union {
1012 .reduce_op => return Value.initTag(.reduce_op_type),1015 .reduce_op => return Value.initTag(.reduce_op_type),
1013 .call_options => return Value.initTag(.call_options_type),1016 .call_options => return Value.initTag(.call_options_type),
1014 .export_options => return Value.initTag(.export_options_type),1017 .export_options => return Value.initTag(.export_options_type),
1018 .extern_options => return Value.initTag(.extern_options_type),
1015 .inferred_alloc_const => unreachable,1019 .inferred_alloc_const => unreachable,
1016 .inferred_alloc_mut => unreachable,1020 .inferred_alloc_mut => unreachable,
1017 else => return Value.Tag.ty.create(allocator, self),1021 else => return Value.Tag.ty.create(allocator, self),
...@@ -1070,6 +1074,7 @@ pub const Type = extern union {...@@ -1070,6 +1074,7 @@ pub const Type = extern union {
1070 .reduce_op,1074 .reduce_op,
1071 .call_options,1075 .call_options,
1072 .export_options,1076 .export_options,
1077 .extern_options,
1073 => true,1078 => true,
10741079
1075 .@"struct" => {1080 .@"struct" => {
...@@ -1181,6 +1186,7 @@ pub const Type = extern union {...@@ -1181,6 +1186,7 @@ pub const Type = extern union {
1181 .reduce_op,1186 .reduce_op,
1182 .call_options,1187 .call_options,
1183 .export_options,1188 .export_options,
1189 .extern_options,
1184 => return 1,1190 => return 1,
11851191
1186 .fn_noreturn_no_args, // represents machine code; not a pointer1192 .fn_noreturn_no_args, // represents machine code; not a pointer
...@@ -1359,6 +1365,7 @@ pub const Type = extern union {...@@ -1359,6 +1365,7 @@ pub const Type = extern union {
1359 .reduce_op,1365 .reduce_op,
1360 .call_options,1366 .call_options,
1361 .export_options,1367 .export_options,
1368 .extern_options,
1362 => return 1,1369 => return 1,
13631370
1364 .array_u8 => self.castTag(.array_u8).?.data,1371 .array_u8 => self.castTag(.array_u8).?.data,
...@@ -1623,6 +1630,7 @@ pub const Type = extern union {...@@ -1623,6 +1630,7 @@ pub const Type = extern union {
1623 .reduce_op,1630 .reduce_op,
1624 .call_options,1631 .call_options,
1625 .export_options,1632 .export_options,
1633 .extern_options,
1626 => @panic("TODO at some point we gotta resolve builtin types"),1634 => @panic("TODO at some point we gotta resolve builtin types"),
1627 };1635 };
1628 }1636 }
...@@ -2247,6 +2255,7 @@ pub const Type = extern union {...@@ -2247,6 +2255,7 @@ pub const Type = extern union {
2247 .reduce_op,2255 .reduce_op,
2248 .call_options,2256 .call_options,
2249 .export_options,2257 .export_options,
2258 .extern_options,
2250 => return null,2259 => return null,
22512260
2252 .@"struct" => {2261 .@"struct" => {
...@@ -2413,6 +2422,7 @@ pub const Type = extern union {...@@ -2413,6 +2422,7 @@ pub const Type = extern union {
2413 .reduce_op,2422 .reduce_op,
2414 .call_options,2423 .call_options,
2415 .export_options,2424 .export_options,
2425 .extern_options,
2416 => @panic("TODO resolve std.builtin types"),2426 => @panic("TODO resolve std.builtin types"),
24172427
2418 else => unreachable,2428 else => unreachable,
...@@ -2436,6 +2446,7 @@ pub const Type = extern union {...@@ -2436,6 +2446,7 @@ pub const Type = extern union {
2436 .reduce_op,2446 .reduce_op,
2437 .call_options,2447 .call_options,
2438 .export_options,2448 .export_options,
2449 .extern_options,
2439 => @panic("TODO resolve std.builtin types"),2450 => @panic("TODO resolve std.builtin types"),
2440 else => unreachable,2451 else => unreachable,
2441 }2452 }
...@@ -2458,6 +2469,7 @@ pub const Type = extern union {...@@ -2458,6 +2469,7 @@ pub const Type = extern union {
2458 .reduce_op,2469 .reduce_op,
2459 .call_options,2470 .call_options,
2460 .export_options,2471 .export_options,
2472 .extern_options,
2461 => @panic("TODO resolve std.builtin types"),2473 => @panic("TODO resolve std.builtin types"),
2462 else => unreachable,2474 else => unreachable,
2463 }2475 }
...@@ -2502,6 +2514,7 @@ pub const Type = extern union {...@@ -2502,6 +2514,7 @@ pub const Type = extern union {
2502 .reduce_op,2514 .reduce_op,
2503 .call_options,2515 .call_options,
2504 .export_options,2516 .export_options,
2517 .extern_options,
2505 => @panic("TODO resolve std.builtin types"),2518 => @panic("TODO resolve std.builtin types"),
2506 else => unreachable,2519 else => unreachable,
2507 }2520 }
...@@ -2532,6 +2545,7 @@ pub const Type = extern union {...@@ -2532,6 +2545,7 @@ pub const Type = extern union {
2532 .reduce_op,2545 .reduce_op,
2533 .call_options,2546 .call_options,
2534 .export_options,2547 .export_options,
2548 .extern_options,
2535 => @panic("TODO resolve std.builtin types"),2549 => @panic("TODO resolve std.builtin types"),
2536 else => unreachable,2550 else => unreachable,
2537 }2551 }
...@@ -2563,6 +2577,7 @@ pub const Type = extern union {...@@ -2563,6 +2577,7 @@ pub const Type = extern union {
2563 .reduce_op,2577 .reduce_op,
2564 .call_options,2578 .call_options,
2565 .export_options,2579 .export_options,
2580 .extern_options,
2566 => @panic("TODO resolve std.builtin types"),2581 => @panic("TODO resolve std.builtin types"),
2567 else => unreachable,2582 else => unreachable,
2568 }2583 }
...@@ -2603,6 +2618,7 @@ pub const Type = extern union {...@@ -2603,6 +2618,7 @@ pub const Type = extern union {
2603 .reduce_op,2618 .reduce_op,
2604 .call_options,2619 .call_options,
2605 .export_options,2620 .export_options,
2621 .extern_options,
2606 => @panic("TODO resolve std.builtin types"),2622 => @panic("TODO resolve std.builtin types"),
26072623
2608 else => unreachable,2624 else => unreachable,
...@@ -2660,6 +2676,7 @@ pub const Type = extern union {...@@ -2660,6 +2676,7 @@ pub const Type = extern union {
2660 reduce_op,2676 reduce_op,
2661 call_options,2677 call_options,
2662 export_options,2678 export_options,
2679 extern_options,
2663 @"null",2680 @"null",
2664 @"undefined",2681 @"undefined",
2665 fn_noreturn_no_args,2682 fn_noreturn_no_args,
...@@ -2772,6 +2789,7 @@ pub const Type = extern union {...@@ -2772,6 +2789,7 @@ pub const Type = extern union {
2772 .reduce_op,2789 .reduce_op,
2773 .call_options,2790 .call_options,
2774 .export_options,2791 .export_options,
2792 .extern_options,
2775 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),2793 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
27762794
2777 .array_u8,2795 .array_u8,
src/value.zig+7
...@@ -73,6 +73,7 @@ pub const Value = extern union {...@@ -73,6 +73,7 @@ pub const Value = extern union {
73 reduce_op_type,73 reduce_op_type,
74 call_options_type,74 call_options_type,
75 export_options_type,75 export_options_type,
76 extern_options_type,
7677
77 undef,78 undef,
78 zero,79 zero,
...@@ -187,6 +188,7 @@ pub const Value = extern union {...@@ -187,6 +188,7 @@ pub const Value = extern union {
187 .reduce_op_type,188 .reduce_op_type,
188 .call_options_type,189 .call_options_type,
189 .export_options_type,190 .export_options_type,
191 .extern_options_type,
190 => @compileError("Value Tag " ++ @tagName(t) ++ " has no payload"),192 => @compileError("Value Tag " ++ @tagName(t) ++ " has no payload"),
191193
192 .int_big_positive,194 .int_big_positive,
...@@ -354,6 +356,7 @@ pub const Value = extern union {...@@ -354,6 +356,7 @@ pub const Value = extern union {
354 .reduce_op_type,356 .reduce_op_type,
355 .call_options_type,357 .call_options_type,
356 .export_options_type,358 .export_options_type,
359 .extern_options_type,
357 => unreachable,360 => unreachable,
358361
359 .ty => {362 .ty => {
...@@ -510,6 +513,7 @@ pub const Value = extern union {...@@ -510,6 +513,7 @@ pub const Value = extern union {
510 .reduce_op_type => return out_stream.writeAll("std.builtin.ReduceOp"),513 .reduce_op_type => return out_stream.writeAll("std.builtin.ReduceOp"),
511 .call_options_type => return out_stream.writeAll("std.builtin.CallOptions"),514 .call_options_type => return out_stream.writeAll("std.builtin.CallOptions"),
512 .export_options_type => return out_stream.writeAll("std.builtin.ExportOptions"),515 .export_options_type => return out_stream.writeAll("std.builtin.ExportOptions"),
516 .extern_options_type => return out_stream.writeAll("std.builtin.ExternOptions"),
513 .abi_align_default => return out_stream.writeAll("(default ABI alignment)"),517 .abi_align_default => return out_stream.writeAll("(default ABI alignment)"),
514518
515 .empty_struct_value => return out_stream.writeAll("struct {}{}"),519 .empty_struct_value => return out_stream.writeAll("struct {}{}"),
...@@ -640,6 +644,7 @@ pub const Value = extern union {...@@ -640,6 +644,7 @@ pub const Value = extern union {
640 .reduce_op_type => Type.initTag(.reduce_op),644 .reduce_op_type => Type.initTag(.reduce_op),
641 .call_options_type => Type.initTag(.call_options),645 .call_options_type => Type.initTag(.call_options),
642 .export_options_type => Type.initTag(.export_options),646 .export_options_type => Type.initTag(.export_options),
647 .extern_options_type => Type.initTag(.extern_options),
643648
644 .int_type => {649 .int_type => {
645 const payload = self.castTag(.int_type).?.data;650 const payload = self.castTag(.int_type).?.data;
...@@ -1187,6 +1192,7 @@ pub const Value = extern union {...@@ -1187,6 +1192,7 @@ pub const Value = extern union {
1187 .reduce_op_type,1192 .reduce_op_type,
1188 .call_options_type,1193 .call_options_type,
1189 .export_options_type,1194 .export_options_type,
1195 .extern_options_type,
1190 => @panic("TODO this hash function looks pretty broken. audit it"),1196 => @panic("TODO this hash function looks pretty broken. audit it"),
1191 }1197 }
1192 return hasher.final();1198 return hasher.final();
...@@ -1343,6 +1349,7 @@ pub const Value = extern union {...@@ -1343,6 +1349,7 @@ pub const Value = extern union {
1343 .reduce_op_type,1349 .reduce_op_type,
1344 .call_options_type,1350 .call_options_type,
1345 .export_options_type,1351 .export_options_type,
1352 .extern_options_type,
1346 => true,1353 => true,
13471354
1348 .zero,1355 .zero,