authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-13 23:51:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-13 23:51:22-07:00
log8344a50e1c545bbeb63debc90cb91289be53b689
tree83df1936d65e78c1369acc544b2d261c2127ecf4
parent93896ef860da734cbb1247e796c0d14706b1c235

AstGen: add compile error for decl name conflicts

* Remove the ability for GenZir parent Scope to be null. Now there is a Top Scope at the top. * Introduce Scope.Namespace to contain a table of decl names in order to emit a compile error for name conflicts. * Fix use of invalid memory when reporting compile errors by duplicating decl names into a temporary heap allocated buffer. * Fix memory leak in while and for loops, not cleaning up their labeled_breaks and store_to_block_ptr_list arrays. * Fix stage2 test cases because now the source location of redundant comptime keyword compile errors is improved. * Implement compile error for local variable shadowing declaration.

3 files changed, 192 insertions(+), 84 deletions(-)

BRANCH_TODO-2
...@@ -1,8 +1,6 @@...@@ -1,8 +1,6 @@
1 * get stage2 tests passing1 * get stage2 tests passing
2 - after the error from an empty file, "has no member main" is invalidated2 - after the error from an empty file, "has no member main" is invalidated
3 but the comptime block incorrectly does not get re-run3 but the comptime block incorrectly does not get re-run
4 - redundant comptime wrong source loc
5 - redeclaration of 'foo' not showing 'previously declared here'
6 - segfault in one of the tests4 - segfault in one of the tests
7 - memory leaks5 - memory leaks
8 * modify stage2 tests so that only 1 uses _start and the rest use6 * modify stage2 tests so that only 1 uses _start and the rest use
src/AstGen.zig+183-79
...@@ -82,9 +82,11 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) InnerError!Zir {...@@ -82,9 +82,11 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) InnerError!Zir {
82 try astgen.extra.ensureTotalCapacity(gpa, tree.nodes.len + reserved_count);82 try astgen.extra.ensureTotalCapacity(gpa, tree.nodes.len + reserved_count);
83 astgen.extra.items.len += reserved_count;83 astgen.extra.items.len += reserved_count;
8484
85 var top_scope: Scope.Top = .{};
86
85 var gen_scope: GenZir = .{87 var gen_scope: GenZir = .{
86 .force_comptime = true,88 .force_comptime = true,
87 .parent = null,89 .parent = &top_scope.base,
88 .anon_name_strategy = .parent,90 .anon_name_strategy = .parent,
89 .decl_node_index = 0,91 .decl_node_index = 0,
90 .decl_line = 0,92 .decl_line = 0,
...@@ -1514,7 +1516,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn...@@ -1514,7 +1516,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn
1514 } else if (block_gz.break_block != 0) {1516 } else if (block_gz.break_block != 0) {
1515 break :blk block_gz.break_block;1517 break :blk block_gz.break_block;
1516 }1518 }
1517 scope = block_gz.parent orelse break;1519 scope = block_gz.parent;
1518 continue;1520 continue;
1519 };1521 };
15201522
...@@ -1545,6 +1547,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn...@@ -1545,6 +1547,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn
1545 },1547 },
1546 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,1548 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
1547 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,1549 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
1550 .namespace => break,
1548 .defer_normal => {1551 .defer_normal => {
1549 const defer_scope = scope.cast(Scope.Defer).?;1552 const defer_scope = scope.cast(Scope.Defer).?;
1550 scope = defer_scope.parent;1553 scope = defer_scope.parent;
...@@ -1552,6 +1555,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn...@@ -1552,6 +1555,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn
1552 try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);1555 try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);
1553 },1556 },
1554 .defer_error => scope = scope.cast(Scope.Defer).?.parent,1557 .defer_error => scope = scope.cast(Scope.Defer).?.parent,
1558 .top => unreachable,
1555 }1559 }
1556 }1560 }
1557 if (break_label != 0) {1561 if (break_label != 0) {
...@@ -1576,7 +1580,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)...@@ -1576,7 +1580,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)
1576 const gen_zir = scope.cast(GenZir).?;1580 const gen_zir = scope.cast(GenZir).?;
1577 const continue_block = gen_zir.continue_block;1581 const continue_block = gen_zir.continue_block;
1578 if (continue_block == 0) {1582 if (continue_block == 0) {
1579 scope = gen_zir.parent orelse break;1583 scope = gen_zir.parent;
1580 continue;1584 continue;
1581 }1585 }
1582 if (break_label != 0) blk: {1586 if (break_label != 0) blk: {
...@@ -1587,7 +1591,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)...@@ -1587,7 +1591,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)
1587 }1591 }
1588 }1592 }
1589 // found continue but either it has a different label, or no label1593 // found continue but either it has a different label, or no label
1590 scope = gen_zir.parent orelse break;1594 scope = gen_zir.parent;
1591 continue;1595 continue;
1592 }1596 }
15931597
...@@ -1604,6 +1608,8 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)...@@ -1604,6 +1608,8 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)
1604 try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);1608 try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);
1605 },1609 },
1606 .defer_error => scope = scope.cast(Scope.Defer).?.parent,1610 .defer_error => scope = scope.cast(Scope.Defer).?.parent,
1611 .namespace => break,
1612 .top => unreachable,
1607 }1613 }
1608 }1614 }
1609 if (break_label != 0) {1615 if (break_label != 0) {
...@@ -1664,11 +1670,13 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.Toke...@@ -1664,11 +1670,13 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.Toke
1664 });1670 });
1665 }1671 }
1666 }1672 }
1667 scope = gen_zir.parent orelse return;1673 scope = gen_zir.parent;
1668 },1674 },
1669 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,1675 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
1670 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,1676 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
1671 .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent,1677 .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent,
1678 .namespace => break,
1679 .top => unreachable,
1672 }1680 }
1673 }1681 }
1674}1682}
...@@ -2103,7 +2111,7 @@ fn genDefers(...@@ -2103,7 +2111,7 @@ fn genDefers(
2103 var scope = inner_scope;2111 var scope = inner_scope;
2104 while (scope != outer_scope) {2112 while (scope != outer_scope) {
2105 switch (scope.tag) {2113 switch (scope.tag) {
2106 .gen_zir => scope = scope.cast(GenZir).?.parent.?,2114 .gen_zir => scope = scope.cast(GenZir).?.parent,
2107 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,2115 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
2108 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,2116 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
2109 .defer_normal => {2117 .defer_normal => {
...@@ -2119,6 +2127,8 @@ fn genDefers(...@@ -2119,6 +2127,8 @@ fn genDefers(
2119 const expr_node = node_datas[defer_scope.defer_node].rhs;2127 const expr_node = node_datas[defer_scope.defer_node].rhs;
2120 try unusedResultExpr(gz, defer_scope.parent, expr_node);2128 try unusedResultExpr(gz, defer_scope.parent, expr_node);
2121 },2129 },
2130 .namespace => unreachable,
2131 .top => unreachable,
2122 }2132 }
2123 }2133 }
2124}2134}
...@@ -2162,12 +2172,14 @@ fn varDecl(...@@ -2162,12 +2172,14 @@ fn varDecl(
2162 .local_val => {2172 .local_val => {
2163 const local_val = s.cast(Scope.LocalVal).?;2173 const local_val = s.cast(Scope.LocalVal).?;
2164 if (local_val.name == ident_name) {2174 if (local_val.name == ident_name) {
2175 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));
2176 defer gpa.free(name);
2165 return astgen.failTokNotes(name_token, "redeclaration of '{s}'", .{2177 return astgen.failTokNotes(name_token, "redeclaration of '{s}'", .{
2166 astgen.nullTerminatedString(ident_name),2178 name,
2167 }, &[_]u32{2179 }, &[_]u32{
2168 try astgen.errNoteTok(2180 try astgen.errNoteTok(
2169 local_val.token_src,2181 local_val.token_src,
2170 "previous declaration is here",2182 "previously declared here",
2171 .{},2183 .{},
2172 ),2184 ),
2173 });2185 });
...@@ -2177,20 +2189,37 @@ fn varDecl(...@@ -2177,20 +2189,37 @@ fn varDecl(
2177 .local_ptr => {2189 .local_ptr => {
2178 const local_ptr = s.cast(Scope.LocalPtr).?;2190 const local_ptr = s.cast(Scope.LocalPtr).?;
2179 if (local_ptr.name == ident_name) {2191 if (local_ptr.name == ident_name) {
2192 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));
2193 defer gpa.free(name);
2180 return astgen.failTokNotes(name_token, "redeclaration of '{s}'", .{2194 return astgen.failTokNotes(name_token, "redeclaration of '{s}'", .{
2181 astgen.nullTerminatedString(ident_name),2195 name,
2182 }, &[_]u32{2196 }, &[_]u32{
2183 try astgen.errNoteTok(2197 try astgen.errNoteTok(
2184 local_ptr.token_src,2198 local_ptr.token_src,
2185 "previous declaration is here",2199 "previously declared here",
2186 .{},2200 .{},
2187 ),2201 ),
2188 });2202 });
2189 }2203 }
2190 s = local_ptr.parent;2204 s = local_ptr.parent;
2191 },2205 },
2192 .gen_zir => s = s.cast(GenZir).?.parent orelse break,2206 .namespace => {
2207 const ns = s.cast(Scope.Namespace).?;
2208 const decl_node = ns.decls.get(ident_name) orelse {
2209 s = ns.parent;
2210 continue;
2211 };
2212 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));
2213 defer gpa.free(name);
2214 return astgen.failTokNotes(name_token, "local shadows declaration of '{s}'", .{
2215 name,
2216 }, &[_]u32{
2217 try astgen.errNoteNode(decl_node, "declared here", .{}),
2218 });
2219 },
2220 .gen_zir => s = s.cast(GenZir).?.parent,
2193 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,2221 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
2222 .top => break,
2194 };2223 };
2195 }2224 }
21962225
...@@ -2676,6 +2705,7 @@ const WipDecls = struct {...@@ -2676,6 +2705,7 @@ const WipDecls = struct {
2676fn fnDecl(2705fn fnDecl(
2677 astgen: *AstGen,2706 astgen: *AstGen,
2678 gz: *GenZir,2707 gz: *GenZir,
2708 scope: *Scope,
2679 wip_decls: *WipDecls,2709 wip_decls: *WipDecls,
2680 decl_node: ast.Node.Index,2710 decl_node: ast.Node.Index,
2681 body_node: ast.Node.Index,2711 body_node: ast.Node.Index,
...@@ -2685,6 +2715,13 @@ fn fnDecl(...@@ -2685,6 +2715,13 @@ fn fnDecl(
2685 const tree = astgen.tree;2715 const tree = astgen.tree;
2686 const token_tags = tree.tokens.items(.tag);2716 const token_tags = tree.tokens.items(.tag);
26872717
2718 const fn_name_token = fn_proto.name_token orelse {
2719 return astgen.failTok(fn_proto.ast.fn_token, "missing function name", .{});
2720 };
2721 const fn_name_str_index = try astgen.identAsString(fn_name_token);
2722
2723 try astgen.declareNewName(scope, fn_name_str_index, decl_node);
2724
2688 // We insert this at the beginning so that its instruction index marks the2725 // We insert this at the beginning so that its instruction index marks the
2689 // start of the top level declaration.2726 // start of the top level declaration.
2690 const block_inst = try gz.addBlock(.block_inline, fn_proto.ast.proto_node);2727 const block_inst = try gz.addBlock(.block_inline, fn_proto.ast.proto_node);
...@@ -2693,7 +2730,7 @@ fn fnDecl(...@@ -2693,7 +2730,7 @@ fn fnDecl(
2693 .force_comptime = true,2730 .force_comptime = true,
2694 .decl_node_index = fn_proto.ast.proto_node,2731 .decl_node_index = fn_proto.ast.proto_node,
2695 .decl_line = gz.calcLine(decl_node),2732 .decl_line = gz.calcLine(decl_node),
2696 .parent = &gz.base,2733 .parent = scope,
2697 .astgen = astgen,2734 .astgen = astgen,
2698 };2735 };
2699 defer decl_gz.instructions.deinit(gpa);2736 defer decl_gz.instructions.deinit(gpa);
...@@ -2891,11 +2928,6 @@ fn fnDecl(...@@ -2891,11 +2928,6 @@ fn fnDecl(
2891 });2928 });
2892 };2929 };
28932930
2894 const fn_name_token = fn_proto.name_token orelse {
2895 return astgen.failTok(fn_proto.ast.fn_token, "missing function name", .{});
2896 };
2897 const fn_name_str_index = try astgen.identAsString(fn_name_token);
2898
2899 // We add this at the end so that its instruction index marks the end range2931 // We add this at the end so that its instruction index marks the end range
2900 // of the top level declaration.2932 // of the top level declaration.
2901 _ = try decl_gz.addBreak(.break_inline, block_inst, func_inst);2933 _ = try decl_gz.addBreak(.break_inline, block_inst, func_inst);
...@@ -2941,6 +2973,8 @@ fn globalVarDecl(...@@ -2941,6 +2973,8 @@ fn globalVarDecl(
2941 const name_token = var_decl.ast.mut_token + 1;2973 const name_token = var_decl.ast.mut_token + 1;
2942 const name_str_index = try astgen.identAsString(name_token);2974 const name_str_index = try astgen.identAsString(name_token);
29432975
2976 try astgen.declareNewName(scope, name_str_index, node);
2977
2944 var block_scope: GenZir = .{2978 var block_scope: GenZir = .{
2945 .parent = scope,2979 .parent = scope,
2946 .decl_node_index = node,2980 .decl_node_index = node,
...@@ -3289,6 +3323,9 @@ fn structDeclInner(...@@ -3289,6 +3323,9 @@ fn structDeclInner(
3289 };3323 };
3290 defer block_scope.instructions.deinit(gpa);3324 defer block_scope.instructions.deinit(gpa);
32913325
3326 var namespace: Scope.Namespace = .{ .parent = &gz.base };
3327 defer namespace.decls.deinit(gpa);
3328
3292 var wip_decls: WipDecls = .{};3329 var wip_decls: WipDecls = .{};
3293 defer wip_decls.deinit(gpa);3330 defer wip_decls.deinit(gpa);
32943331
...@@ -3317,14 +3354,14 @@ fn structDeclInner(...@@ -3317,14 +3354,14 @@ fn structDeclInner(
3317 switch (node_tags[fn_proto]) {3354 switch (node_tags[fn_proto]) {
3318 .fn_proto_simple => {3355 .fn_proto_simple => {
3319 var params: [1]ast.Node.Index = undefined;3356 var params: [1]ast.Node.Index = undefined;
3320 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {3357 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
3321 error.OutOfMemory => return error.OutOfMemory,3358 error.OutOfMemory => return error.OutOfMemory,
3322 error.AnalysisFail => {},3359 error.AnalysisFail => {},
3323 };3360 };
3324 continue;3361 continue;
3325 },3362 },
3326 .fn_proto_multi => {3363 .fn_proto_multi => {
3327 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {3364 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
3328 error.OutOfMemory => return error.OutOfMemory,3365 error.OutOfMemory => return error.OutOfMemory,
3329 error.AnalysisFail => {},3366 error.AnalysisFail => {},
3330 };3367 };
...@@ -3332,14 +3369,14 @@ fn structDeclInner(...@@ -3332,14 +3369,14 @@ fn structDeclInner(
3332 },3369 },
3333 .fn_proto_one => {3370 .fn_proto_one => {
3334 var params: [1]ast.Node.Index = undefined;3371 var params: [1]ast.Node.Index = undefined;
3335 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {3372 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
3336 error.OutOfMemory => return error.OutOfMemory,3373 error.OutOfMemory => return error.OutOfMemory,
3337 error.AnalysisFail => {},3374 error.AnalysisFail => {},
3338 };3375 };
3339 continue;3376 continue;
3340 },3377 },
3341 .fn_proto => {3378 .fn_proto => {
3342 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {3379 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
3343 error.OutOfMemory => return error.OutOfMemory,3380 error.OutOfMemory => return error.OutOfMemory,
3344 error.AnalysisFail => {},3381 error.AnalysisFail => {},
3345 };3382 };
...@@ -3350,14 +3387,14 @@ fn structDeclInner(...@@ -3350,14 +3387,14 @@ fn structDeclInner(
3350 },3387 },
3351 .fn_proto_simple => {3388 .fn_proto_simple => {
3352 var params: [1]ast.Node.Index = undefined;3389 var params: [1]ast.Node.Index = undefined;
3353 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {3390 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
3354 error.OutOfMemory => return error.OutOfMemory,3391 error.OutOfMemory => return error.OutOfMemory,
3355 error.AnalysisFail => {},3392 error.AnalysisFail => {},
3356 };3393 };
3357 continue;3394 continue;
3358 },3395 },
3359 .fn_proto_multi => {3396 .fn_proto_multi => {
3360 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {3397 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
3361 error.OutOfMemory => return error.OutOfMemory,3398 error.OutOfMemory => return error.OutOfMemory,
3362 error.AnalysisFail => {},3399 error.AnalysisFail => {},
3363 };3400 };
...@@ -3365,14 +3402,14 @@ fn structDeclInner(...@@ -3365,14 +3402,14 @@ fn structDeclInner(
3365 },3402 },
3366 .fn_proto_one => {3403 .fn_proto_one => {
3367 var params: [1]ast.Node.Index = undefined;3404 var params: [1]ast.Node.Index = undefined;
3368 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {3405 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
3369 error.OutOfMemory => return error.OutOfMemory,3406 error.OutOfMemory => return error.OutOfMemory,
3370 error.AnalysisFail => {},3407 error.AnalysisFail => {},
3371 };3408 };
3372 continue;3409 continue;
3373 },3410 },
3374 .fn_proto => {3411 .fn_proto => {
3375 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {3412 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
3376 error.OutOfMemory => return error.OutOfMemory,3413 error.OutOfMemory => return error.OutOfMemory,
3377 error.AnalysisFail => {},3414 error.AnalysisFail => {},
3378 };3415 };
...@@ -3380,28 +3417,28 @@ fn structDeclInner(...@@ -3380,28 +3417,28 @@ fn structDeclInner(
3380 },3417 },
33813418
3382 .global_var_decl => {3419 .global_var_decl => {
3383 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {3420 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
3384 error.OutOfMemory => return error.OutOfMemory,3421 error.OutOfMemory => return error.OutOfMemory,
3385 error.AnalysisFail => {},3422 error.AnalysisFail => {},
3386 };3423 };
3387 continue;3424 continue;
3388 },3425 },
3389 .local_var_decl => {3426 .local_var_decl => {
3390 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {3427 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
3391 error.OutOfMemory => return error.OutOfMemory,3428 error.OutOfMemory => return error.OutOfMemory,
3392 error.AnalysisFail => {},3429 error.AnalysisFail => {},
3393 };3430 };
3394 continue;3431 continue;
3395 },3432 },
3396 .simple_var_decl => {3433 .simple_var_decl => {
3397 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {3434 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
3398 error.OutOfMemory => return error.OutOfMemory,3435 error.OutOfMemory => return error.OutOfMemory,
3399 error.AnalysisFail => {},3436 error.AnalysisFail => {},
3400 };3437 };
3401 continue;3438 continue;
3402 },3439 },
3403 .aligned_var_decl => {3440 .aligned_var_decl => {
3404 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {3441 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
3405 error.OutOfMemory => return error.OutOfMemory,3442 error.OutOfMemory => return error.OutOfMemory,
3406 error.AnalysisFail => {},3443 error.AnalysisFail => {},
3407 };3444 };
...@@ -3409,21 +3446,21 @@ fn structDeclInner(...@@ -3409,21 +3446,21 @@ fn structDeclInner(
3409 },3446 },
34103447
3411 .@"comptime" => {3448 .@"comptime" => {
3412 astgen.comptimeDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {3449 astgen.comptimeDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
3413 error.OutOfMemory => return error.OutOfMemory,3450 error.OutOfMemory => return error.OutOfMemory,
3414 error.AnalysisFail => {},3451 error.AnalysisFail => {},
3415 };3452 };
3416 continue;3453 continue;
3417 },3454 },
3418 .@"usingnamespace" => {3455 .@"usingnamespace" => {
3419 astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {3456 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
3420 error.OutOfMemory => return error.OutOfMemory,3457 error.OutOfMemory => return error.OutOfMemory,
3421 error.AnalysisFail => {},3458 error.AnalysisFail => {},
3422 };3459 };
3423 continue;3460 continue;
3424 },3461 },
3425 .test_decl => {3462 .test_decl => {
3426 astgen.testDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {3463 astgen.testDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
3427 error.OutOfMemory => return error.OutOfMemory,3464 error.OutOfMemory => return error.OutOfMemory,
3428 error.AnalysisFail => {},3465 error.AnalysisFail => {},
3429 };3466 };
...@@ -3547,6 +3584,9 @@ fn unionDeclInner(...@@ -3547,6 +3584,9 @@ fn unionDeclInner(
3547 };3584 };
3548 defer block_scope.instructions.deinit(gpa);3585 defer block_scope.instructions.deinit(gpa);
35493586
3587 var namespace: Scope.Namespace = .{ .parent = &gz.base };
3588 defer namespace.decls.deinit(gpa);
3589
3550 var wip_decls: WipDecls = .{};3590 var wip_decls: WipDecls = .{};
3551 defer wip_decls.deinit(gpa);3591 defer wip_decls.deinit(gpa);
35523592
...@@ -3575,14 +3615,14 @@ fn unionDeclInner(...@@ -3575,14 +3615,14 @@ fn unionDeclInner(
3575 switch (node_tags[fn_proto]) {3615 switch (node_tags[fn_proto]) {
3576 .fn_proto_simple => {3616 .fn_proto_simple => {
3577 var params: [1]ast.Node.Index = undefined;3617 var params: [1]ast.Node.Index = undefined;
3578 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {3618 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
3579 error.OutOfMemory => return error.OutOfMemory,3619 error.OutOfMemory => return error.OutOfMemory,
3580 error.AnalysisFail => {},3620 error.AnalysisFail => {},
3581 };3621 };
3582 continue;3622 continue;
3583 },3623 },
3584 .fn_proto_multi => {3624 .fn_proto_multi => {
3585 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {3625 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
3586 error.OutOfMemory => return error.OutOfMemory,3626 error.OutOfMemory => return error.OutOfMemory,
3587 error.AnalysisFail => {},3627 error.AnalysisFail => {},
3588 };3628 };
...@@ -3590,14 +3630,14 @@ fn unionDeclInner(...@@ -3590,14 +3630,14 @@ fn unionDeclInner(
3590 },3630 },
3591 .fn_proto_one => {3631 .fn_proto_one => {
3592 var params: [1]ast.Node.Index = undefined;3632 var params: [1]ast.Node.Index = undefined;
3593 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {3633 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
3594 error.OutOfMemory => return error.OutOfMemory,3634 error.OutOfMemory => return error.OutOfMemory,
3595 error.AnalysisFail => {},3635 error.AnalysisFail => {},
3596 };3636 };
3597 continue;3637 continue;
3598 },3638 },
3599 .fn_proto => {3639 .fn_proto => {
3600 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {3640 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
3601 error.OutOfMemory => return error.OutOfMemory,3641 error.OutOfMemory => return error.OutOfMemory,
3602 error.AnalysisFail => {},3642 error.AnalysisFail => {},
3603 };3643 };
...@@ -3608,14 +3648,14 @@ fn unionDeclInner(...@@ -3608,14 +3648,14 @@ fn unionDeclInner(
3608 },3648 },
3609 .fn_proto_simple => {3649 .fn_proto_simple => {
3610 var params: [1]ast.Node.Index = undefined;3650 var params: [1]ast.Node.Index = undefined;
3611 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {3651 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
3612 error.OutOfMemory => return error.OutOfMemory,3652 error.OutOfMemory => return error.OutOfMemory,
3613 error.AnalysisFail => {},3653 error.AnalysisFail => {},
3614 };3654 };
3615 continue;3655 continue;
3616 },3656 },
3617 .fn_proto_multi => {3657 .fn_proto_multi => {
3618 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {3658 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
3619 error.OutOfMemory => return error.OutOfMemory,3659 error.OutOfMemory => return error.OutOfMemory,
3620 error.AnalysisFail => {},3660 error.AnalysisFail => {},
3621 };3661 };
...@@ -3623,14 +3663,14 @@ fn unionDeclInner(...@@ -3623,14 +3663,14 @@ fn unionDeclInner(
3623 },3663 },
3624 .fn_proto_one => {3664 .fn_proto_one => {
3625 var params: [1]ast.Node.Index = undefined;3665 var params: [1]ast.Node.Index = undefined;
3626 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {3666 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
3627 error.OutOfMemory => return error.OutOfMemory,3667 error.OutOfMemory => return error.OutOfMemory,
3628 error.AnalysisFail => {},3668 error.AnalysisFail => {},
3629 };3669 };
3630 continue;3670 continue;
3631 },3671 },
3632 .fn_proto => {3672 .fn_proto => {
3633 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {3673 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
3634 error.OutOfMemory => return error.OutOfMemory,3674 error.OutOfMemory => return error.OutOfMemory,
3635 error.AnalysisFail => {},3675 error.AnalysisFail => {},
3636 };3676 };
...@@ -3638,28 +3678,28 @@ fn unionDeclInner(...@@ -3638,28 +3678,28 @@ fn unionDeclInner(
3638 },3678 },
36393679
3640 .global_var_decl => {3680 .global_var_decl => {
3641 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {3681 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
3642 error.OutOfMemory => return error.OutOfMemory,3682 error.OutOfMemory => return error.OutOfMemory,
3643 error.AnalysisFail => {},3683 error.AnalysisFail => {},
3644 };3684 };
3645 continue;3685 continue;
3646 },3686 },
3647 .local_var_decl => {3687 .local_var_decl => {
3648 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {3688 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
3649 error.OutOfMemory => return error.OutOfMemory,3689 error.OutOfMemory => return error.OutOfMemory,
3650 error.AnalysisFail => {},3690 error.AnalysisFail => {},
3651 };3691 };
3652 continue;3692 continue;
3653 },3693 },
3654 .simple_var_decl => {3694 .simple_var_decl => {
3655 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {3695 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
3656 error.OutOfMemory => return error.OutOfMemory,3696 error.OutOfMemory => return error.OutOfMemory,
3657 error.AnalysisFail => {},3697 error.AnalysisFail => {},
3658 };3698 };
3659 continue;3699 continue;
3660 },3700 },
3661 .aligned_var_decl => {3701 .aligned_var_decl => {
3662 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {3702 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
3663 error.OutOfMemory => return error.OutOfMemory,3703 error.OutOfMemory => return error.OutOfMemory,
3664 error.AnalysisFail => {},3704 error.AnalysisFail => {},
3665 };3705 };
...@@ -3667,21 +3707,21 @@ fn unionDeclInner(...@@ -3667,21 +3707,21 @@ fn unionDeclInner(
3667 },3707 },
36683708
3669 .@"comptime" => {3709 .@"comptime" => {
3670 astgen.comptimeDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {3710 astgen.comptimeDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
3671 error.OutOfMemory => return error.OutOfMemory,3711 error.OutOfMemory => return error.OutOfMemory,
3672 error.AnalysisFail => {},3712 error.AnalysisFail => {},
3673 };3713 };
3674 continue;3714 continue;
3675 },3715 },
3676 .@"usingnamespace" => {3716 .@"usingnamespace" => {
3677 astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {3717 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
3678 error.OutOfMemory => return error.OutOfMemory,3718 error.OutOfMemory => return error.OutOfMemory,
3679 error.AnalysisFail => {},3719 error.AnalysisFail => {},
3680 };3720 };
3681 continue;3721 continue;
3682 },3722 },
3683 .test_decl => {3723 .test_decl => {
3684 astgen.testDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {3724 astgen.testDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
3685 error.OutOfMemory => return error.OutOfMemory,3725 error.OutOfMemory => return error.OutOfMemory,
3686 error.AnalysisFail => {},3726 error.AnalysisFail => {},
3687 };3727 };
...@@ -3940,6 +3980,9 @@ fn containerDecl(...@@ -3940,6 +3980,9 @@ fn containerDecl(
3940 };3980 };
3941 defer block_scope.instructions.deinit(gpa);3981 defer block_scope.instructions.deinit(gpa);
39423982
3983 var namespace: Scope.Namespace = .{ .parent = &gz.base };
3984 defer namespace.decls.deinit(gpa);
3985
3943 var wip_decls: WipDecls = .{};3986 var wip_decls: WipDecls = .{};
3944 defer wip_decls.deinit(gpa);3987 defer wip_decls.deinit(gpa);
39453988
...@@ -3968,14 +4011,14 @@ fn containerDecl(...@@ -3968,14 +4011,14 @@ fn containerDecl(
3968 switch (node_tags[fn_proto]) {4011 switch (node_tags[fn_proto]) {
3969 .fn_proto_simple => {4012 .fn_proto_simple => {
3970 var params: [1]ast.Node.Index = undefined;4013 var params: [1]ast.Node.Index = undefined;
3971 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {4014 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
3972 error.OutOfMemory => return error.OutOfMemory,4015 error.OutOfMemory => return error.OutOfMemory,
3973 error.AnalysisFail => {},4016 error.AnalysisFail => {},
3974 };4017 };
3975 continue;4018 continue;
3976 },4019 },
3977 .fn_proto_multi => {4020 .fn_proto_multi => {
3978 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {4021 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
3979 error.OutOfMemory => return error.OutOfMemory,4022 error.OutOfMemory => return error.OutOfMemory,
3980 error.AnalysisFail => {},4023 error.AnalysisFail => {},
3981 };4024 };
...@@ -3983,14 +4026,14 @@ fn containerDecl(...@@ -3983,14 +4026,14 @@ fn containerDecl(
3983 },4026 },
3984 .fn_proto_one => {4027 .fn_proto_one => {
3985 var params: [1]ast.Node.Index = undefined;4028 var params: [1]ast.Node.Index = undefined;
3986 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {4029 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
3987 error.OutOfMemory => return error.OutOfMemory,4030 error.OutOfMemory => return error.OutOfMemory,
3988 error.AnalysisFail => {},4031 error.AnalysisFail => {},
3989 };4032 };
3990 continue;4033 continue;
3991 },4034 },
3992 .fn_proto => {4035 .fn_proto => {
3993 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {4036 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
3994 error.OutOfMemory => return error.OutOfMemory,4037 error.OutOfMemory => return error.OutOfMemory,
3995 error.AnalysisFail => {},4038 error.AnalysisFail => {},
3996 };4039 };
...@@ -4001,14 +4044,14 @@ fn containerDecl(...@@ -4001,14 +4044,14 @@ fn containerDecl(
4001 },4044 },
4002 .fn_proto_simple => {4045 .fn_proto_simple => {
4003 var params: [1]ast.Node.Index = undefined;4046 var params: [1]ast.Node.Index = undefined;
4004 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {4047 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
4005 error.OutOfMemory => return error.OutOfMemory,4048 error.OutOfMemory => return error.OutOfMemory,
4006 error.AnalysisFail => {},4049 error.AnalysisFail => {},
4007 };4050 };
4008 continue;4051 continue;
4009 },4052 },
4010 .fn_proto_multi => {4053 .fn_proto_multi => {
4011 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {4054 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
4012 error.OutOfMemory => return error.OutOfMemory,4055 error.OutOfMemory => return error.OutOfMemory,
4013 error.AnalysisFail => {},4056 error.AnalysisFail => {},
4014 };4057 };
...@@ -4016,14 +4059,14 @@ fn containerDecl(...@@ -4016,14 +4059,14 @@ fn containerDecl(
4016 },4059 },
4017 .fn_proto_one => {4060 .fn_proto_one => {
4018 var params: [1]ast.Node.Index = undefined;4061 var params: [1]ast.Node.Index = undefined;
4019 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {4062 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
4020 error.OutOfMemory => return error.OutOfMemory,4063 error.OutOfMemory => return error.OutOfMemory,
4021 error.AnalysisFail => {},4064 error.AnalysisFail => {},
4022 };4065 };
4023 continue;4066 continue;
4024 },4067 },
4025 .fn_proto => {4068 .fn_proto => {
4026 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {4069 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
4027 error.OutOfMemory => return error.OutOfMemory,4070 error.OutOfMemory => return error.OutOfMemory,
4028 error.AnalysisFail => {},4071 error.AnalysisFail => {},
4029 };4072 };
...@@ -4031,28 +4074,28 @@ fn containerDecl(...@@ -4031,28 +4074,28 @@ fn containerDecl(
4031 },4074 },
40324075
4033 .global_var_decl => {4076 .global_var_decl => {
4034 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {4077 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
4035 error.OutOfMemory => return error.OutOfMemory,4078 error.OutOfMemory => return error.OutOfMemory,
4036 error.AnalysisFail => {},4079 error.AnalysisFail => {},
4037 };4080 };
4038 continue;4081 continue;
4039 },4082 },
4040 .local_var_decl => {4083 .local_var_decl => {
4041 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {4084 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
4042 error.OutOfMemory => return error.OutOfMemory,4085 error.OutOfMemory => return error.OutOfMemory,
4043 error.AnalysisFail => {},4086 error.AnalysisFail => {},
4044 };4087 };
4045 continue;4088 continue;
4046 },4089 },
4047 .simple_var_decl => {4090 .simple_var_decl => {
4048 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {4091 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
4049 error.OutOfMemory => return error.OutOfMemory,4092 error.OutOfMemory => return error.OutOfMemory,
4050 error.AnalysisFail => {},4093 error.AnalysisFail => {},
4051 };4094 };
4052 continue;4095 continue;
4053 },4096 },
4054 .aligned_var_decl => {4097 .aligned_var_decl => {
4055 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {4098 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
4056 error.OutOfMemory => return error.OutOfMemory,4099 error.OutOfMemory => return error.OutOfMemory,
4057 error.AnalysisFail => {},4100 error.AnalysisFail => {},
4058 };4101 };
...@@ -4060,21 +4103,21 @@ fn containerDecl(...@@ -4060,21 +4103,21 @@ fn containerDecl(
4060 },4103 },
40614104
4062 .@"comptime" => {4105 .@"comptime" => {
4063 astgen.comptimeDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {4106 astgen.comptimeDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4064 error.OutOfMemory => return error.OutOfMemory,4107 error.OutOfMemory => return error.OutOfMemory,
4065 error.AnalysisFail => {},4108 error.AnalysisFail => {},
4066 };4109 };
4067 continue;4110 continue;
4068 },4111 },
4069 .@"usingnamespace" => {4112 .@"usingnamespace" => {
4070 astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {4113 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4071 error.OutOfMemory => return error.OutOfMemory,4114 error.OutOfMemory => return error.OutOfMemory,
4072 error.AnalysisFail => {},4115 error.AnalysisFail => {},
4073 };4116 };
4074 continue;4117 continue;
4075 },4118 },
4076 .test_decl => {4119 .test_decl => {
4077 astgen.testDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {4120 astgen.testDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4078 error.OutOfMemory => return error.OutOfMemory,4121 error.OutOfMemory => return error.OutOfMemory,
4079 error.AnalysisFail => {},4122 error.AnalysisFail => {},
4080 };4123 };
...@@ -4164,6 +4207,9 @@ fn containerDecl(...@@ -4164,6 +4207,9 @@ fn containerDecl(
4164 return rvalue(gz, scope, rl, gz.indexToRef(decl_inst), node);4207 return rvalue(gz, scope, rl, gz.indexToRef(decl_inst), node);
4165 },4208 },
4166 .keyword_opaque => {4209 .keyword_opaque => {
4210 var namespace: Scope.Namespace = .{ .parent = &gz.base };
4211 defer namespace.decls.deinit(gpa);
4212
4167 var wip_decls: WipDecls = .{};4213 var wip_decls: WipDecls = .{};
4168 defer wip_decls.deinit(gpa);4214 defer wip_decls.deinit(gpa);
41694215
...@@ -4179,14 +4225,14 @@ fn containerDecl(...@@ -4179,14 +4225,14 @@ fn containerDecl(
4179 switch (node_tags[fn_proto]) {4225 switch (node_tags[fn_proto]) {
4180 .fn_proto_simple => {4226 .fn_proto_simple => {
4181 var params: [1]ast.Node.Index = undefined;4227 var params: [1]ast.Node.Index = undefined;
4182 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {4228 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
4183 error.OutOfMemory => return error.OutOfMemory,4229 error.OutOfMemory => return error.OutOfMemory,
4184 error.AnalysisFail => {},4230 error.AnalysisFail => {},
4185 };4231 };
4186 continue;4232 continue;
4187 },4233 },
4188 .fn_proto_multi => {4234 .fn_proto_multi => {
4189 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {4235 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
4190 error.OutOfMemory => return error.OutOfMemory,4236 error.OutOfMemory => return error.OutOfMemory,
4191 error.AnalysisFail => {},4237 error.AnalysisFail => {},
4192 };4238 };
...@@ -4194,14 +4240,14 @@ fn containerDecl(...@@ -4194,14 +4240,14 @@ fn containerDecl(
4194 },4240 },
4195 .fn_proto_one => {4241 .fn_proto_one => {
4196 var params: [1]ast.Node.Index = undefined;4242 var params: [1]ast.Node.Index = undefined;
4197 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {4243 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
4198 error.OutOfMemory => return error.OutOfMemory,4244 error.OutOfMemory => return error.OutOfMemory,
4199 error.AnalysisFail => {},4245 error.AnalysisFail => {},
4200 };4246 };
4201 continue;4247 continue;
4202 },4248 },
4203 .fn_proto => {4249 .fn_proto => {
4204 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {4250 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
4205 error.OutOfMemory => return error.OutOfMemory,4251 error.OutOfMemory => return error.OutOfMemory,
4206 error.AnalysisFail => {},4252 error.AnalysisFail => {},
4207 };4253 };
...@@ -4212,14 +4258,14 @@ fn containerDecl(...@@ -4212,14 +4258,14 @@ fn containerDecl(
4212 },4258 },
4213 .fn_proto_simple => {4259 .fn_proto_simple => {
4214 var params: [1]ast.Node.Index = undefined;4260 var params: [1]ast.Node.Index = undefined;
4215 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {4261 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
4216 error.OutOfMemory => return error.OutOfMemory,4262 error.OutOfMemory => return error.OutOfMemory,
4217 error.AnalysisFail => {},4263 error.AnalysisFail => {},
4218 };4264 };
4219 continue;4265 continue;
4220 },4266 },
4221 .fn_proto_multi => {4267 .fn_proto_multi => {
4222 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {4268 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
4223 error.OutOfMemory => return error.OutOfMemory,4269 error.OutOfMemory => return error.OutOfMemory,
4224 error.AnalysisFail => {},4270 error.AnalysisFail => {},
4225 };4271 };
...@@ -4227,14 +4273,14 @@ fn containerDecl(...@@ -4227,14 +4273,14 @@ fn containerDecl(
4227 },4273 },
4228 .fn_proto_one => {4274 .fn_proto_one => {
4229 var params: [1]ast.Node.Index = undefined;4275 var params: [1]ast.Node.Index = undefined;
4230 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {4276 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
4231 error.OutOfMemory => return error.OutOfMemory,4277 error.OutOfMemory => return error.OutOfMemory,
4232 error.AnalysisFail => {},4278 error.AnalysisFail => {},
4233 };4279 };
4234 continue;4280 continue;
4235 },4281 },
4236 .fn_proto => {4282 .fn_proto => {
4237 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {4283 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
4238 error.OutOfMemory => return error.OutOfMemory,4284 error.OutOfMemory => return error.OutOfMemory,
4239 error.AnalysisFail => {},4285 error.AnalysisFail => {},
4240 };4286 };
...@@ -4242,28 +4288,28 @@ fn containerDecl(...@@ -4242,28 +4288,28 @@ fn containerDecl(
4242 },4288 },
42434289
4244 .global_var_decl => {4290 .global_var_decl => {
4245 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {4291 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
4246 error.OutOfMemory => return error.OutOfMemory,4292 error.OutOfMemory => return error.OutOfMemory,
4247 error.AnalysisFail => {},4293 error.AnalysisFail => {},
4248 };4294 };
4249 continue;4295 continue;
4250 },4296 },
4251 .local_var_decl => {4297 .local_var_decl => {
4252 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {4298 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
4253 error.OutOfMemory => return error.OutOfMemory,4299 error.OutOfMemory => return error.OutOfMemory,
4254 error.AnalysisFail => {},4300 error.AnalysisFail => {},
4255 };4301 };
4256 continue;4302 continue;
4257 },4303 },
4258 .simple_var_decl => {4304 .simple_var_decl => {
4259 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {4305 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
4260 error.OutOfMemory => return error.OutOfMemory,4306 error.OutOfMemory => return error.OutOfMemory,
4261 error.AnalysisFail => {},4307 error.AnalysisFail => {},
4262 };4308 };
4263 continue;4309 continue;
4264 },4310 },
4265 .aligned_var_decl => {4311 .aligned_var_decl => {
4266 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {4312 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
4267 error.OutOfMemory => return error.OutOfMemory,4313 error.OutOfMemory => return error.OutOfMemory,
4268 error.AnalysisFail => {},4314 error.AnalysisFail => {},
4269 };4315 };
...@@ -4271,21 +4317,21 @@ fn containerDecl(...@@ -4271,21 +4317,21 @@ fn containerDecl(
4271 },4317 },
42724318
4273 .@"comptime" => {4319 .@"comptime" => {
4274 astgen.comptimeDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {4320 astgen.comptimeDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4275 error.OutOfMemory => return error.OutOfMemory,4321 error.OutOfMemory => return error.OutOfMemory,
4276 error.AnalysisFail => {},4322 error.AnalysisFail => {},
4277 };4323 };
4278 continue;4324 continue;
4279 },4325 },
4280 .@"usingnamespace" => {4326 .@"usingnamespace" => {
4281 astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {4327 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4282 error.OutOfMemory => return error.OutOfMemory,4328 error.OutOfMemory => return error.OutOfMemory,
4283 error.AnalysisFail => {},4329 error.AnalysisFail => {},
4284 };4330 };
4285 continue;4331 continue;
4286 },4332 },
4287 .test_decl => {4333 .test_decl => {
4288 astgen.testDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {4334 astgen.testDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
4289 error.OutOfMemory => return error.OutOfMemory,4335 error.OutOfMemory => return error.OutOfMemory,
4290 error.AnalysisFail => {},4336 error.AnalysisFail => {},
4291 };4337 };
...@@ -4971,6 +5017,8 @@ fn whileExpr(...@@ -4971,6 +5017,8 @@ fn whileExpr(
4971 var loop_scope = parent_gz.makeSubBlock(scope);5017 var loop_scope = parent_gz.makeSubBlock(scope);
4972 loop_scope.setBreakResultLoc(rl);5018 loop_scope.setBreakResultLoc(rl);
4973 defer loop_scope.instructions.deinit(astgen.gpa);5019 defer loop_scope.instructions.deinit(astgen.gpa);
5020 defer loop_scope.labeled_breaks.deinit(astgen.gpa);
5021 defer loop_scope.labeled_store_to_block_ptr_list.deinit(astgen.gpa);
49745022
4975 var continue_scope = parent_gz.makeSubBlock(&loop_scope.base);5023 var continue_scope = parent_gz.makeSubBlock(&loop_scope.base);
4976 defer continue_scope.instructions.deinit(astgen.gpa);5024 defer continue_scope.instructions.deinit(astgen.gpa);
...@@ -5178,6 +5226,8 @@ fn forExpr(...@@ -5178,6 +5226,8 @@ fn forExpr(
5178 var loop_scope = parent_gz.makeSubBlock(scope);5226 var loop_scope = parent_gz.makeSubBlock(scope);
5179 loop_scope.setBreakResultLoc(rl);5227 loop_scope.setBreakResultLoc(rl);
5180 defer loop_scope.instructions.deinit(astgen.gpa);5228 defer loop_scope.instructions.deinit(astgen.gpa);
5229 defer loop_scope.labeled_breaks.deinit(astgen.gpa);
5230 defer loop_scope.labeled_store_to_block_ptr_list.deinit(astgen.gpa);
51815231
5182 var cond_scope = parent_gz.makeSubBlock(&loop_scope.base);5232 var cond_scope = parent_gz.makeSubBlock(&loop_scope.base);
5183 defer cond_scope.instructions.deinit(astgen.gpa);5233 defer cond_scope.instructions.deinit(astgen.gpa);
...@@ -6006,8 +6056,9 @@ fn identifier(...@@ -6006,8 +6056,9 @@ fn identifier(
6006 }6056 }
6007 s = local_ptr.parent;6057 s = local_ptr.parent;
6008 },6058 },
6009 .gen_zir => s = s.cast(GenZir).?.parent orelse break,6059 .gen_zir => s = s.cast(GenZir).?.parent,
6010 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,6060 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
6061 .namespace, .top => break, // TODO look for ambiguous references to decls
6011 };6062 };
6012 }6063 }
60136064
...@@ -7922,6 +7973,8 @@ const Scope = struct {...@@ -7922,6 +7973,8 @@ const Scope = struct {
7922 local_ptr,7973 local_ptr,
7923 defer_normal,7974 defer_normal,
7924 defer_error,7975 defer_error,
7976 namespace,
7977 top,
7925 };7978 };
79267979
7927 /// This is always a `const` local and importantly the `inst` is a value type, not a pointer.7980 /// This is always a `const` local and importantly the `inst` is a value type, not a pointer.
...@@ -7962,6 +8015,23 @@ const Scope = struct {...@@ -7962,6 +8015,23 @@ const Scope = struct {
7962 parent: *Scope,8015 parent: *Scope,
7963 defer_node: ast.Node.Index,8016 defer_node: ast.Node.Index,
7964 };8017 };
8018
8019 /// Represents a global scope that has any number of declarations in it.
8020 /// Each declaration has this as the parent scope.
8021 const Namespace = struct {
8022 const base_tag: Tag = .namespace;
8023 base: Scope = Scope{ .tag = base_tag },
8024
8025 parent: *Scope,
8026 /// Maps string table index to the source location of declaration,
8027 /// for the purposes of reporting name shadowing compile errors.
8028 decls: std.AutoHashMapUnmanaged(u32, ast.Node.Index) = .{},
8029 };
8030
8031 const Top = struct {
8032 const base_tag: Scope.Tag = .top;
8033 base: Scope = Scope{ .tag = base_tag },
8034 };
7965};8035};
79668036
7967/// This is a temporary structure; references to it are valid only8037/// This is a temporary structure; references to it are valid only
...@@ -7979,7 +8049,7 @@ const GenZir = struct {...@@ -7979,7 +8049,7 @@ const GenZir = struct {
7979 decl_node_index: ast.Node.Index,8049 decl_node_index: ast.Node.Index,
7980 /// The containing decl line index, absolute.8050 /// The containing decl line index, absolute.
7981 decl_line: u32,8051 decl_line: u32,
7982 parent: ?*Scope,8052 parent: *Scope,
7983 /// All `GenZir` scopes for the same ZIR share this.8053 /// All `GenZir` scopes for the same ZIR share this.
7984 astgen: *AstGen,8054 astgen: *AstGen,
7985 /// Keeps track of the list of instructions in this scope only. Indexes8055 /// Keeps track of the list of instructions in this scope only. Indexes
...@@ -8989,3 +9059,37 @@ const GenZir = struct {...@@ -8989,3 +9059,37 @@ const GenZir = struct {
8989fn nullTerminatedString(astgen: AstGen, index: usize) [*:0]const u8 {9059fn nullTerminatedString(astgen: AstGen, index: usize) [*:0]const u8 {
8990 return @ptrCast([*:0]const u8, astgen.string_bytes.items.ptr) + index;9060 return @ptrCast([*:0]const u8, astgen.string_bytes.items.ptr) + index;
8991}9061}
9062
9063fn declareNewName(
9064 astgen: *AstGen,
9065 start_scope: *Scope,
9066 name_index: u32,
9067 node: ast.Node.Index,
9068) !void {
9069 const gpa = astgen.gpa;
9070 var scope = start_scope;
9071 while (true) {
9072 switch (scope.tag) {
9073 .gen_zir => scope = scope.cast(GenZir).?.parent,
9074 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
9075 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
9076 .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent,
9077 .namespace => {
9078 const ns = scope.cast(Scope.Namespace).?;
9079 const gop = try ns.decls.getOrPut(gpa, name_index);
9080 if (gop.found_existing) {
9081 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(name_index)));
9082 defer gpa.free(name);
9083 return astgen.failNodeNotes(node, "redeclaration of '{s}'", .{
9084 name,
9085 }, &[_]u32{
9086 try astgen.errNoteNode(gop.entry.value, "other declaration here", .{}),
9087 });
9088 }
9089 gop.entry.value = node;
9090 break;
9091 },
9092 .top => break,
9093 }
9094 }
9095}
test/stage2/test.zig+9-3
...@@ -1137,7 +1137,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1137,7 +1137,7 @@ pub fn addCases(ctx: *TestContext) !void {
1137 \\ var a: comptime u32 = 0;1137 \\ var a: comptime u32 = 0;
1138 \\}1138 \\}
1139 ,1139 ,
1140 &.{":2:21: error: redundant comptime keyword in already comptime scope"},1140 &.{":2:12: error: redundant comptime keyword in already comptime scope"},
1141 );1141 );
1142 case.addError(1142 case.addError(
1143 \\pub export fn _start() void {1143 \\pub export fn _start() void {
...@@ -1146,7 +1146,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1146,7 +1146,7 @@ pub fn addCases(ctx: *TestContext) !void {
1146 \\ }1146 \\ }
1147 \\}1147 \\}
1148 ,1148 ,
1149 &.{":3:31: error: redundant comptime keyword in already comptime scope"},1149 &.{":3:22: error: redundant comptime keyword in already comptime scope"},
1150 );1150 );
1151 }1151 }
1152 {1152 {
...@@ -1195,9 +1195,15 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1195,9 +1195,15 @@ pub fn addCases(ctx: *TestContext) !void {
1195 \\// dummy comment1195 \\// dummy comment
1196 \\fn entry() void {}1196 \\fn entry() void {}
1197 \\fn entry() void {}1197 \\fn entry() void {}
1198 \\
1199 \\fn foo() void {
1200 \\ var foo = 1234;
1201 \\}
1198 , &[_][]const u8{1202 , &[_][]const u8{
1199 ":3:4: error: redeclaration of 'entry'",1203 ":3:1: error: redeclaration of 'entry'",
1200 ":2:1: note: previously declared here",1204 ":2:1: note: previously declared here",
1205 ":6:9: error: local shadows declaration of 'foo'",
1206 ":5:1: note: declared here",
1201 });1207 });
12021208
1203 ctx.compileError("global variable redeclaration", linux_x64,1209 ctx.compileError("global variable redeclaration", linux_x64,