authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-29 19:56:01-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-29 19:56:01-07:00
log8944240aec6b53106856bb0ac2eb9da180f6b326
tree47672df25bcc997cee0aa61ebe28e0709704c980
parent86d564eed8b9eacd0447598dd364ab04c5b1b04d

AstGen: represent global variables directly

Rather than with `block_inline_var`. This matches how function declarations work and how extern variables work.

4 files changed, 30 insertions(+), 25 deletions(-)

src/AstGen.zig+27-17
...@@ -1854,7 +1854,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner...@@ -1854,7 +1854,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
1854 .bit_or,1854 .bit_or,
1855 .block,1855 .block,
1856 .block_inline,1856 .block_inline,
1857 .block_inline_var,
1858 .suspend_block,1857 .suspend_block,
1859 .loop,1858 .loop,
1860 .bool_br_and,1859 .bool_br_and,
...@@ -2917,10 +2916,9 @@ fn globalVarDecl(...@@ -2917,10 +2916,9 @@ fn globalVarDecl(
2917 const token_tags = tree.tokens.items(.tag);2916 const token_tags = tree.tokens.items(.tag);
29182917
2919 const is_mutable = token_tags[var_decl.ast.mut_token] == .keyword_var;2918 const is_mutable = token_tags[var_decl.ast.mut_token] == .keyword_var;
2920 const tag: Zir.Inst.Tag = if (is_mutable) .block_inline_var else .block_inline;
2921 // We do this at the beginning so that the instruction index marks the range start2919 // We do this at the beginning so that the instruction index marks the range start
2922 // of the top level declaration.2920 // of the top level declaration.
2923 const block_inst = try gz.addBlock(tag, node);2921 const block_inst = try gz.addBlock(.block_inline, node);
29242922
2925 var block_scope: GenZir = .{2923 var block_scope: GenZir = .{
2926 .parent = scope,2924 .parent = scope,
...@@ -2961,7 +2959,7 @@ fn globalVarDecl(...@@ -2961,7 +2959,7 @@ fn globalVarDecl(
29612959
2962 assert(var_decl.comptime_token == null); // handled by parser2960 assert(var_decl.comptime_token == null); // handled by parser
29632961
2964 if (var_decl.ast.init_node != 0) {2962 const var_inst: Zir.Inst.Ref = if (var_decl.ast.init_node != 0) vi: {
2965 if (is_extern) {2963 if (is_extern) {
2966 return astgen.failNode(2964 return astgen.failNode(
2967 var_decl.ast.init_node,2965 var_decl.ast.init_node,
...@@ -2970,43 +2968,55 @@ fn globalVarDecl(...@@ -2970,43 +2968,55 @@ fn globalVarDecl(
2970 );2968 );
2971 }2969 }
29722970
2973 const init_result_loc: AstGen.ResultLoc = if (var_decl.ast.type_node != 0) .{2971 const type_inst: Zir.Inst.Ref = if (var_decl.ast.type_node != 0)
2974 .ty = try expr(2972 try expr(
2975 &block_scope,2973 &block_scope,
2976 &block_scope.base,2974 &block_scope.base,
2977 .{ .ty = .type_type },2975 .{ .ty = .type_type },
2978 var_decl.ast.type_node,2976 var_decl.ast.type_node,
2979 ),2977 )
2980 } else .none;2978 else
2979 .none;
29812980
2982 const init_inst = try expr(2981 const init_inst = try expr(
2983 &block_scope,2982 &block_scope,
2984 &block_scope.base,2983 &block_scope.base,
2985 init_result_loc,2984 if (type_inst != .none) .{ .ty = type_inst } else .none,
2986 var_decl.ast.init_node,2985 var_decl.ast.init_node,
2987 );2986 );
29882987
2989 // We do this at the end so that the instruction index marks the end2988 if (is_mutable) {
2990 // range of a top level declaration.2989 const var_inst = try block_scope.addVar(.{
2991 _ = try block_scope.addBreak(.break_inline, block_inst, init_inst);2990 .var_type = type_inst,
2991 .lib_name = 0,
2992 .align_inst = .none, // passed via the decls data
2993 .init = init_inst,
2994 .is_extern = false,
2995 });
2996 break :vi var_inst;
2997 } else {
2998 break :vi init_inst;
2999 }
2992 } else if (!is_extern) {3000 } else if (!is_extern) {
2993 return astgen.failNode(node, "variables must be initialized", .{});3001 return astgen.failNode(node, "variables must be initialized", .{});
2994 } else if (var_decl.ast.type_node != 0) {3002 } else if (var_decl.ast.type_node != 0) vi: {
2995 // Extern variable which has an explicit type.3003 // Extern variable which has an explicit type.
2996 const type_inst = try typeExpr(&block_scope, &block_scope.base, var_decl.ast.type_node);3004 const type_inst = try typeExpr(&block_scope, &block_scope.base, var_decl.ast.type_node);
29973005
2998 const var_inst = try block_scope.addVar(.{3006 const var_inst = try block_scope.addVar(.{
2999 .var_type = type_inst,3007 .var_type = type_inst,
3000 .lib_name = lib_name,3008 .lib_name = lib_name,
3001 .align_inst = .none, // passed in the decls data3009 .align_inst = .none, // passed via the decls data
3002 .init = .none,3010 .init = .none,
3003 .is_extern = true,3011 .is_extern = true,
3004 });3012 });
30053013 break :vi var_inst;
3006 _ = try block_scope.addBreak(.break_inline, block_inst, var_inst);
3007 } else {3014 } else {
3008 return astgen.failNode(node, "unable to infer variable type", .{});3015 return astgen.failNode(node, "unable to infer variable type", .{});
3009 }3016 };
3017 // We do this at the end so that the instruction index marks the end
3018 // range of a top level declaration.
3019 _ = try block_scope.addBreak(.break_inline, block_inst, var_inst);
3010 try block_scope.setBlockBody(block_inst);3020 try block_scope.setBlockBody(block_inst);
30113021
3012 const name_token = var_decl.ast.mut_token + 1;3022 const name_token = var_decl.ast.mut_token + 1;
src/Module.zig+1-1
...@@ -3478,7 +3478,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3478,7 +3478,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3478 }3478 }
3479 return type_changed or is_inline != prev_is_inline;3479 return type_changed or is_inline != prev_is_inline;
3480 } else {3480 } else {
3481 const is_mutable = zir_tags[zir_block_index] == .block_inline_var;3481 const is_mutable = decl_tv.val.tag() == .variable;
34823482
3483 var is_threadlocal = false; // TODO implement threadlocal variables3483 var is_threadlocal = false; // TODO implement threadlocal variables
3484 var is_extern = false; // TODO implement extern variables3484 var is_extern = false; // TODO implement extern variables
src/Sema.zig+1-1
...@@ -439,7 +439,7 @@ pub fn analyzeBody(...@@ -439,7 +439,7 @@ pub fn analyzeBody(
439 i = 0;439 i = 0;
440 continue;440 continue;
441 },441 },
442 .block_inline, .block_inline_var => blk: {442 .block_inline => blk: {
443 // Directly analyze the block body without introducing a new block.443 // Directly analyze the block body without introducing a new block.
444 const inst_data = datas[inst].pl_node;444 const inst_data = datas[inst].pl_node;
445 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);445 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
src/Zir.zig+1-6
...@@ -214,8 +214,6 @@ pub const Inst = struct {...@@ -214,8 +214,6 @@ pub const Inst = struct {
214 /// a noreturn instruction.214 /// a noreturn instruction.
215 /// Uses the `pl_node` union field. Payload is `Block`.215 /// Uses the `pl_node` union field. Payload is `Block`.
216 block_inline,216 block_inline,
217 /// Same as `block_inline` but it additionally marks a decl as being a variable.
218 block_inline_var,
219 /// Implements `suspend {...}`.217 /// Implements `suspend {...}`.
220 /// Uses the `pl_node` union field. Payload is `Block`.218 /// Uses the `pl_node` union field. Payload is `Block`.
221 suspend_block,219 suspend_block,
...@@ -982,7 +980,6 @@ pub const Inst = struct {...@@ -982,7 +980,6 @@ pub const Inst = struct {
982 .bit_or,980 .bit_or,
983 .block,981 .block,
984 .block_inline,982 .block_inline,
985 .block_inline_var,
986 .suspend_block,983 .suspend_block,
987 .loop,984 .loop,
988 .bool_br_and,985 .bool_br_and,
...@@ -1240,7 +1237,6 @@ pub const Inst = struct {...@@ -1240,7 +1237,6 @@ pub const Inst = struct {
1240 .bit_or = .pl_node,1237 .bit_or = .pl_node,
1241 .block = .pl_node,1238 .block = .pl_node,
1242 .block_inline = .pl_node,1239 .block_inline = .pl_node,
1243 .block_inline_var = .pl_node,
1244 .suspend_block = .pl_node,1240 .suspend_block = .pl_node,
1245 .bool_and = .pl_node,1241 .bool_and = .pl_node,
1246 .bool_not = .un_node,1242 .bool_not = .un_node,
...@@ -2517,7 +2513,7 @@ pub const Inst = struct {...@@ -2517,7 +2513,7 @@ pub const Inst = struct {
2517 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace2513 /// - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
2518 /// - 1 means test decl with no name.2514 /// - 1 means test decl with no name.
2519 /// value: Index,2515 /// value: Index,
2520 /// - one of: block_inline, block_inline_var2516 /// - one of: block_inline
2521 /// align: Ref, // if corresponding bit is set2517 /// align: Ref, // if corresponding bit is set
2522 /// link_section: Ref, // if corresponding bit is set2518 /// link_section: Ref, // if corresponding bit is set
2523 /// }2519 /// }
...@@ -2933,7 +2929,6 @@ const Writer = struct {...@@ -2933,7 +2929,6 @@ const Writer = struct {
29332929
2934 .block,2930 .block,
2935 .block_inline,2931 .block_inline,
2936 .block_inline_var,
2937 .suspend_block,2932 .suspend_block,
2938 .loop,2933 .loop,
2939 .validate_struct_init_ptr,2934 .validate_struct_init_ptr,