authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-08-19 15:19:00+03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-19 16:12:29-07:00
log9801047bdb26c86da430310aa5d043f6899adbfe
tree0304d67ff942414a9e8f11ca9b984de2c030103f
parentab8a9a6605900fc0b064c321504ac4e7dc1ca6f4

stage2: handle var attributes


2 files changed, 41 insertions(+), 10 deletions(-)

src-self-hosted/Module.zig+40-10
......@@ -290,6 +290,8 @@ pub const Fn = struct {
290290 },
291291 owner_decl: *Decl,
292292
293 is_pub: bool,
294
293295 /// This memory is temporary and points to stack memory for the duration
294296 /// of Fn analysis.
295297 pub const Analysis = struct {
......@@ -323,7 +325,11 @@ pub const Fn = struct {
323325pub const Var = struct {
324326 value: ?Value,
325327 owner_decl: *Decl,
328
329 is_pub: bool,
330 is_extern: bool,
326331 is_mutable: bool,
332 is_threadlocal: bool,
327333};
328334
329335pub const Scope = struct {
......@@ -1241,6 +1247,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
12411247 };
12421248 defer fn_type_scope.instructions.deinit(self.gpa);
12431249
1250 const is_pub = fn_proto.getTrailer("visib_token") != null;
12441251 const body_node = fn_proto.getTrailer("body_node") orelse
12451252 return self.failTok(&fn_type_scope.base, fn_proto.fn_token, "TODO implement extern functions", .{});
12461253
......@@ -1378,6 +1385,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
13781385 new_func.* = .{
13791386 .analysis = .{ .queued = fn_zir },
13801387 .owner_decl = decl,
1388 .is_pub = is_pub,
13811389 };
13821390 fn_payload.* = .{ .func = new_func };
13831391
......@@ -1430,13 +1438,6 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
14301438
14311439 decl.analysis = .in_progress;
14321440
1433 const is_extern = blk: {
1434 const maybe_extern_token = var_decl.getTrailer("extern_export_token") orelse
1435 break :blk false;
1436 break :blk tree.token_ids[maybe_extern_token] == .Keyword_extern;
1437 };
1438 const is_mutable = tree.token_ids[var_decl.mut_token] == .Keyword_var;
1439
14401441 // We need the memory for the Type to go into the arena for the Decl
14411442 var decl_arena = std.heap.ArenaAllocator.init(self.gpa);
14421443 errdefer decl_arena.deinit();
......@@ -1451,6 +1452,32 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
14511452 };
14521453 defer block_scope.instructions.deinit(self.gpa);
14531454
1455 const is_pub = var_decl.getTrailer("visib_token") != null;
1456 const is_extern = blk: {
1457 const maybe_extern_token = var_decl.getTrailer("extern_export_token") orelse
1458 break :blk false;
1459 break :blk tree.token_ids[maybe_extern_token] == .Keyword_extern;
1460 };
1461 if (var_decl.getTrailer("lib_name")) |lib_name| {
1462 assert(is_extern);
1463 return self.failNode(&block_scope.base, lib_name, "TODO implement function library name", .{});
1464 }
1465 const is_mutable = tree.token_ids[var_decl.mut_token] == .Keyword_var;
1466 const is_threadlocal = if (var_decl.getTrailer("thread_local_token")) |some| blk: {
1467 if (!is_mutable) {
1468 return self.failTok(&block_scope.base, some, "threadlocal variable cannot be constant", .{});
1469 }
1470 break :blk true;
1471 } else false;
1472 assert(var_decl.getTrailer("comptime_token") == null);
1473 if (var_decl.getTrailer("align_node")) |align_expr| {
1474 return self.failNode(&block_scope.base, align_expr, "TODO implement function align expression", .{});
1475 }
1476 if (var_decl.getTrailer("section_node")) |sect_expr| {
1477 return self.failNode(&block_scope.base, sect_expr, "TODO implement function section expression", .{});
1478 }
1479
1480
14541481 const explicit_type = blk: {
14551482 const type_node = var_decl.getTrailer("type_node") orelse
14561483 break :blk null;
......@@ -1543,7 +1570,10 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
15431570 new_variable.* = .{
15441571 .value = value,
15451572 .owner_decl = decl,
1573 .is_pub = is_pub,
1574 .is_extern = is_extern,
15461575 .is_mutable = is_mutable,
1576 .is_threadlocal = is_threadlocal,
15471577 };
15481578 var_payload.* = .{ .variable = new_variable };
15491579
......@@ -2394,7 +2424,7 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn
23942424
23952425 const decl_tv = try decl.typedValue();
23962426 if (decl_tv.val.tag() == .variable) {
2397 return self.getVarRef(scope, src, decl_tv);
2427 return self.analyzeVarRef(scope, src, decl_tv);
23982428 }
23992429 const ty = try self.singlePtrType(scope, src, false, decl_tv.ty);
24002430 const val_payload = try scope.arena().create(Value.Payload.DeclRef);
......@@ -2406,11 +2436,11 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn
24062436 });
24072437}
24082438
2409fn getVarRef(self: *Module, scope: *Scope, src: usize, tv: TypedValue) InnerError!*Inst {
2439fn analyzeVarRef(self: *Module, scope: *Scope, src: usize, tv: TypedValue) InnerError!*Inst {
24102440 const variable = tv.val.cast(Value.Payload.Variable).?.variable;
24112441
24122442 const ty = try self.singlePtrType(scope, src, variable.is_mutable, tv.ty);
2413 if (!variable.is_mutable and variable.value != null) {
2443 if (!variable.is_mutable and !variable.is_extern and variable.value != null) {
24142444 const val_payload = try scope.arena().create(Value.Payload.RefVal);
24152445 val_payload.* = .{ .val = variable.value.? };
24162446 return self.constInst(scope, src, .{
src-self-hosted/zir_sema.zig+1
......@@ -666,6 +666,7 @@ fn analyzeInstFn(mod: *Module, scope: *Scope, fn_inst: *zir.Inst.Fn) InnerError!
666666 new_func.* = .{
667667 .analysis = .{ .queued = fn_zir },
668668 .owner_decl = scope.decl().?,
669 .is_pub = false,
669670 };
670671 const fn_payload = try scope.arena().create(Value.Payload.Function);
671672 fn_payload.* = .{ .func = new_func };