| ... | ... | @@ -2471,12 +2471,23 @@ pub const SrcLoc = struct { |
| 2471 | 2471 | } |
| 2472 | 2472 | } else unreachable; |
| 2473 | 2473 | }, |
| 2474 | | .node_offset_switch_prong_capture => |node_off| { |
| 2474 | .node_offset_switch_prong_capture, |
| 2475 | .node_offset_switch_prong_tag_capture, |
| 2476 | => |node_off| { |
| 2475 | 2477 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2476 | 2478 | const case_node = src_loc.declRelativeToNodeIndex(node_off); |
| 2477 | 2479 | const case = tree.fullSwitchCase(case_node).?; |
| 2478 | | const start_tok = case.payload_token.?; |
| 2479 | 2480 | const token_tags = tree.tokens.items(.tag); |
| 2481 | const start_tok = switch (src_loc.lazy) { |
| 2482 | .node_offset_switch_prong_capture => case.payload_token.?, |
| 2483 | .node_offset_switch_prong_tag_capture => blk: { |
| 2484 | var tok = case.payload_token.?; |
| 2485 | if (token_tags[tok] == .asterisk) tok += 1; |
| 2486 | tok += 2; // skip over comma |
| 2487 | break :blk tok; |
| 2488 | }, |
| 2489 | else => unreachable, |
| 2490 | }; |
| 2480 | 2491 | const end_tok = switch (token_tags[start_tok]) { |
| 2481 | 2492 | .asterisk => start_tok + 1, |
| 2482 | 2493 | else => start_tok, |
| ... | ... | @@ -2957,6 +2968,9 @@ pub const LazySrcLoc = union(enum) { |
| 2957 | 2968 | /// The source location points to the capture of a switch_prong. |
| 2958 | 2969 | /// The Decl is determined contextually. |
| 2959 | 2970 | node_offset_switch_prong_capture: i32, |
| 2971 | /// The source location points to the tag capture of a switch_prong. |
| 2972 | /// The Decl is determined contextually. |
| 2973 | node_offset_switch_prong_tag_capture: i32, |
| 2960 | 2974 | /// The source location points to the align expr of a function type |
| 2961 | 2975 | /// expression, found by taking this AST node index offset from the containing |
| 2962 | 2976 | /// Decl AST node, which points to a function type AST node. Next, navigate to |
| ... | ... | @@ -3130,6 +3144,7 @@ pub const LazySrcLoc = union(enum) { |
| 3130 | 3144 | .node_offset_switch_special_prong, |
| 3131 | 3145 | .node_offset_switch_range, |
| 3132 | 3146 | .node_offset_switch_prong_capture, |
| 3147 | .node_offset_switch_prong_tag_capture, |
| 3133 | 3148 | .node_offset_fn_type_align, |
| 3134 | 3149 | .node_offset_fn_type_addrspace, |
| 3135 | 3150 | .node_offset_fn_type_section, |
| ... | ... | @@ -5867,11 +5882,26 @@ fn lockAndClearFileCompileError(mod: *Module, file: *File) void { |
| 5867 | 5882 | } |
| 5868 | 5883 | |
| 5869 | 5884 | pub const SwitchProngSrc = union(enum) { |
| 5885 | /// The item for a scalar prong. |
| 5870 | 5886 | scalar: u32, |
| 5887 | /// A given single item for a multi prong. |
| 5871 | 5888 | multi: Multi, |
| 5889 | /// A given range item for a multi prong. |
| 5872 | 5890 | range: Multi, |
| 5873 | | multi_capture: u32, |
| 5891 | /// The item for the special prong. |
| 5874 | 5892 | special, |
| 5893 | /// The main capture for a scalar prong. |
| 5894 | scalar_capture: u32, |
| 5895 | /// The main capture for a multi prong. |
| 5896 | multi_capture: u32, |
| 5897 | /// The main capture for the special prong. |
| 5898 | special_capture, |
| 5899 | /// The tag capture for a scalar prong. |
| 5900 | scalar_tag_capture: u32, |
| 5901 | /// The tag capture for a multi prong. |
| 5902 | multi_tag_capture: u32, |
| 5903 | /// The tag capture for the special prong. |
| 5904 | special_tag_capture, |
| 5875 | 5905 | |
| 5876 | 5906 | pub const Multi = struct { |
| 5877 | 5907 | prong: u32, |
| ... | ... | @@ -5887,6 +5917,7 @@ pub const SwitchProngSrc = union(enum) { |
| 5887 | 5917 | mod: *Module, |
| 5888 | 5918 | decl: *Decl, |
| 5889 | 5919 | switch_node_offset: i32, |
| 5920 | /// Ignored if `prong_src` is not `.range` |
| 5890 | 5921 | range_expand: RangeExpand, |
| 5891 | 5922 | ) LazySrcLoc { |
| 5892 | 5923 | @setCold(true); |
| ... | ... | @@ -5907,7 +5938,7 @@ pub const SwitchProngSrc = union(enum) { |
| 5907 | 5938 | |
| 5908 | 5939 | var multi_i: u32 = 0; |
| 5909 | 5940 | var scalar_i: u32 = 0; |
| 5910 | | for (case_nodes) |case_node| { |
| 5941 | const case_node = for (case_nodes) |case_node| { |
| 5911 | 5942 | const case = tree.fullSwitchCase(case_node).?; |
| 5912 | 5943 | |
| 5913 | 5944 | const is_special = special: { |
| ... | ... | @@ -5919,60 +5950,85 @@ pub const SwitchProngSrc = union(enum) { |
| 5919 | 5950 | }; |
| 5920 | 5951 | |
| 5921 | 5952 | if (is_special) { |
| 5922 | | if (prong_src != .special) continue; |
| 5923 | | return LazySrcLoc.nodeOffset( |
| 5924 | | decl.nodeIndexToRelative(case.ast.values[0]), |
| 5925 | | ); |
| 5953 | switch (prong_src) { |
| 5954 | .special, .special_capture, .special_tag_capture => break case_node, |
| 5955 | else => continue, |
| 5956 | } |
| 5926 | 5957 | } |
| 5927 | 5958 | |
| 5928 | 5959 | const is_multi = case.ast.values.len != 1 or |
| 5929 | 5960 | node_tags[case.ast.values[0]] == .switch_range; |
| 5930 | 5961 | |
| 5931 | 5962 | switch (prong_src) { |
| 5932 | | .scalar => |i| if (!is_multi and i == scalar_i) return LazySrcLoc.nodeOffset( |
| 5933 | | decl.nodeIndexToRelative(case.ast.values[0]), |
| 5934 | | ), |
| 5935 | | .multi_capture => |i| if (is_multi and i == multi_i) { |
| 5936 | | return LazySrcLoc{ .node_offset_switch_prong_capture = decl.nodeIndexToRelative(case_node) }; |
| 5937 | | }, |
| 5938 | | .multi => |s| if (is_multi and s.prong == multi_i) { |
| 5939 | | var item_i: u32 = 0; |
| 5940 | | for (case.ast.values) |item_node| { |
| 5941 | | if (node_tags[item_node] == .switch_range) continue; |
| 5942 | | |
| 5943 | | if (item_i == s.item) return LazySrcLoc.nodeOffset( |
| 5944 | | decl.nodeIndexToRelative(item_node), |
| 5945 | | ); |
| 5946 | | item_i += 1; |
| 5947 | | } else unreachable; |
| 5948 | | }, |
| 5949 | | .range => |s| if (is_multi and s.prong == multi_i) { |
| 5950 | | var range_i: u32 = 0; |
| 5951 | | for (case.ast.values) |range| { |
| 5952 | | if (node_tags[range] != .switch_range) continue; |
| 5953 | | |
| 5954 | | if (range_i == s.item) switch (range_expand) { |
| 5955 | | .none => return LazySrcLoc.nodeOffset( |
| 5956 | | decl.nodeIndexToRelative(range), |
| 5957 | | ), |
| 5958 | | .first => return LazySrcLoc.nodeOffset( |
| 5959 | | decl.nodeIndexToRelative(node_datas[range].lhs), |
| 5960 | | ), |
| 5961 | | .last => return LazySrcLoc.nodeOffset( |
| 5962 | | decl.nodeIndexToRelative(node_datas[range].rhs), |
| 5963 | | ), |
| 5964 | | }; |
| 5965 | | range_i += 1; |
| 5966 | | } else unreachable; |
| 5967 | | }, |
| 5968 | | .special => {}, |
| 5963 | .scalar, |
| 5964 | .scalar_capture, |
| 5965 | .scalar_tag_capture, |
| 5966 | => |i| if (!is_multi and i == scalar_i) break case_node, |
| 5967 | |
| 5968 | .multi_capture, |
| 5969 | .multi_tag_capture, |
| 5970 | => |i| if (is_multi and i == multi_i) break case_node, |
| 5971 | |
| 5972 | .multi, |
| 5973 | .range, |
| 5974 | => |m| if (is_multi and m.prong == multi_i) break case_node, |
| 5975 | |
| 5976 | .special, |
| 5977 | .special_capture, |
| 5978 | .special_tag_capture, |
| 5979 | => {}, |
| 5969 | 5980 | } |
| 5981 | |
| 5970 | 5982 | if (is_multi) { |
| 5971 | 5983 | multi_i += 1; |
| 5972 | 5984 | } else { |
| 5973 | 5985 | scalar_i += 1; |
| 5974 | 5986 | } |
| 5975 | 5987 | } else unreachable; |
| 5988 | |
| 5989 | const case = tree.fullSwitchCase(case_node).?; |
| 5990 | |
| 5991 | switch (prong_src) { |
| 5992 | .scalar, .special => return LazySrcLoc.nodeOffset( |
| 5993 | decl.nodeIndexToRelative(case.ast.values[0]), |
| 5994 | ), |
| 5995 | .multi => |m| { |
| 5996 | var item_i: u32 = 0; |
| 5997 | for (case.ast.values) |item_node| { |
| 5998 | if (node_tags[item_node] == .switch_range) continue; |
| 5999 | if (item_i == m.item) return LazySrcLoc.nodeOffset( |
| 6000 | decl.nodeIndexToRelative(item_node), |
| 6001 | ); |
| 6002 | item_i += 1; |
| 6003 | } |
| 6004 | unreachable; |
| 6005 | }, |
| 6006 | .range => |m| { |
| 6007 | var range_i: u32 = 0; |
| 6008 | for (case.ast.values) |range| { |
| 6009 | if (node_tags[range] != .switch_range) continue; |
| 6010 | if (range_i == m.item) switch (range_expand) { |
| 6011 | .none => return LazySrcLoc.nodeOffset( |
| 6012 | decl.nodeIndexToRelative(range), |
| 6013 | ), |
| 6014 | .first => return LazySrcLoc.nodeOffset( |
| 6015 | decl.nodeIndexToRelative(node_datas[range].lhs), |
| 6016 | ), |
| 6017 | .last => return LazySrcLoc.nodeOffset( |
| 6018 | decl.nodeIndexToRelative(node_datas[range].rhs), |
| 6019 | ), |
| 6020 | }; |
| 6021 | range_i += 1; |
| 6022 | } |
| 6023 | unreachable; |
| 6024 | }, |
| 6025 | .scalar_capture, .multi_capture, .special_capture => { |
| 6026 | return .{ .node_offset_switch_prong_capture = decl.nodeIndexToRelative(case_node) }; |
| 6027 | }, |
| 6028 | .scalar_tag_capture, .multi_tag_capture, .special_tag_capture => { |
| 6029 | return .{ .node_offset_switch_prong_tag_capture = decl.nodeIndexToRelative(case_node) }; |
| 6030 | }, |
| 6031 | } |
| 5976 | 6032 | } |
| 5977 | 6033 | }; |
| 5978 | 6034 | |