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 {...@@ -290,6 +290,8 @@ pub const Fn = struct {
290 },290 },
291 owner_decl: *Decl,291 owner_decl: *Decl,
292292
293 is_pub: bool,
294
293 /// This memory is temporary and points to stack memory for the duration295 /// This memory is temporary and points to stack memory for the duration
294 /// of Fn analysis.296 /// of Fn analysis.
295 pub const Analysis = struct {297 pub const Analysis = struct {
...@@ -323,7 +325,11 @@ pub const Fn = struct {...@@ -323,7 +325,11 @@ pub const Fn = struct {
323pub const Var = struct {325pub const Var = struct {
324 value: ?Value,326 value: ?Value,
325 owner_decl: *Decl,327 owner_decl: *Decl,
328
329 is_pub: bool,
330 is_extern: bool,
326 is_mutable: bool,331 is_mutable: bool,
332 is_threadlocal: bool,
327};333};
328334
329pub const Scope = struct {335pub const Scope = struct {
...@@ -1241,6 +1247,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {...@@ -1241,6 +1247,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
1241 };1247 };
1242 defer fn_type_scope.instructions.deinit(self.gpa);1248 defer fn_type_scope.instructions.deinit(self.gpa);
12431249
1250 const is_pub = fn_proto.getTrailer("visib_token") != null;
1244 const body_node = fn_proto.getTrailer("body_node") orelse1251 const body_node = fn_proto.getTrailer("body_node") orelse
1245 return self.failTok(&fn_type_scope.base, fn_proto.fn_token, "TODO implement extern functions", .{});1252 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 {...@@ -1378,6 +1385,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
1378 new_func.* = .{1385 new_func.* = .{
1379 .analysis = .{ .queued = fn_zir },1386 .analysis = .{ .queued = fn_zir },
1380 .owner_decl = decl,1387 .owner_decl = decl,
1388 .is_pub = is_pub,
1381 };1389 };
1382 fn_payload.* = .{ .func = new_func };1390 fn_payload.* = .{ .func = new_func };
13831391
...@@ -1430,13 +1438,6 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {...@@ -1430,13 +1438,6 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
14301438
1431 decl.analysis = .in_progress;1439 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
1440 // We need the memory for the Type to go into the arena for the Decl1441 // We need the memory for the Type to go into the arena for the Decl
1441 var decl_arena = std.heap.ArenaAllocator.init(self.gpa);1442 var decl_arena = std.heap.ArenaAllocator.init(self.gpa);
1442 errdefer decl_arena.deinit();1443 errdefer decl_arena.deinit();
...@@ -1451,6 +1452,32 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {...@@ -1451,6 +1452,32 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
1451 };1452 };
1452 defer block_scope.instructions.deinit(self.gpa);1453 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
1454 const explicit_type = blk: {1481 const explicit_type = blk: {
1455 const type_node = var_decl.getTrailer("type_node") orelse1482 const type_node = var_decl.getTrailer("type_node") orelse
1456 break :blk null;1483 break :blk null;
...@@ -1543,7 +1570,10 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {...@@ -1543,7 +1570,10 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
1543 new_variable.* = .{1570 new_variable.* = .{
1544 .value = value,1571 .value = value,
1545 .owner_decl = decl,1572 .owner_decl = decl,
1573 .is_pub = is_pub,
1574 .is_extern = is_extern,
1546 .is_mutable = is_mutable,1575 .is_mutable = is_mutable,
1576 .is_threadlocal = is_threadlocal,
1547 };1577 };
1548 var_payload.* = .{ .variable = new_variable };1578 var_payload.* = .{ .variable = new_variable };
15491579
...@@ -2394,7 +2424,7 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn...@@ -2394,7 +2424,7 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn
23942424
2395 const decl_tv = try decl.typedValue();2425 const decl_tv = try decl.typedValue();
2396 if (decl_tv.val.tag() == .variable) {2426 if (decl_tv.val.tag() == .variable) {
2397 return self.getVarRef(scope, src, decl_tv);2427 return self.analyzeVarRef(scope, src, decl_tv);
2398 }2428 }
2399 const ty = try self.singlePtrType(scope, src, false, decl_tv.ty);2429 const ty = try self.singlePtrType(scope, src, false, decl_tv.ty);
2400 const val_payload = try scope.arena().create(Value.Payload.DeclRef);2430 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...@@ -2406,11 +2436,11 @@ pub fn analyzeDeclRef(self: *Module, scope: *Scope, src: usize, decl: *Decl) Inn
2406 });2436 });
2407}2437}
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 {
2410 const variable = tv.val.cast(Value.Payload.Variable).?.variable;2440 const variable = tv.val.cast(Value.Payload.Variable).?.variable;
24112441
2412 const ty = try self.singlePtrType(scope, src, variable.is_mutable, tv.ty);2442 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) {
2414 const val_payload = try scope.arena().create(Value.Payload.RefVal);2444 const val_payload = try scope.arena().create(Value.Payload.RefVal);
2415 val_payload.* = .{ .val = variable.value.? };2445 val_payload.* = .{ .val = variable.value.? };
2416 return self.constInst(scope, src, .{2446 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!...@@ -666,6 +666,7 @@ fn analyzeInstFn(mod: *Module, scope: *Scope, fn_inst: *zir.Inst.Fn) InnerError!
666 new_func.* = .{666 new_func.* = .{
667 .analysis = .{ .queued = fn_zir },667 .analysis = .{ .queued = fn_zir },
668 .owner_decl = scope.decl().?,668 .owner_decl = scope.decl().?,
669 .is_pub = false,
669 };670 };
670 const fn_payload = try scope.arena().create(Value.Payload.Function);671 const fn_payload = try scope.arena().create(Value.Payload.Function);
671 fn_payload.* = .{ .func = new_func };672 fn_payload.* = .{ .func = new_func };