| ... | ... | @@ -271,7 +271,7 @@ pub const Decl = struct { |
| 271 | 271 | const func = payload.data; |
| 272 | 272 | func.deinit(gpa); |
| 273 | 273 | } |
| 274 | | if (decl.value_arena) |a| a.promote(gpa).deinit(); |
| 274 | decl.clearValues(gpa); |
| 275 | 275 | } |
| 276 | 276 | decl.dependants.deinit(gpa); |
| 277 | 277 | decl.dependencies.deinit(gpa); |
| ... | ... | @@ -284,6 +284,14 @@ pub const Decl = struct { |
| 284 | 284 | } |
| 285 | 285 | } |
| 286 | 286 | |
| 287 | pub fn clearValues(decl: *Decl, gpa: *Allocator) void { |
| 288 | if (decl.value_arena) |arena_state| { |
| 289 | arena_state.promote(gpa).deinit(); |
| 290 | decl.value_arena = null; |
| 291 | decl.has_tv = false; |
| 292 | } |
| 293 | } |
| 294 | |
| 287 | 295 | /// This name is relative to the containing namespace of the decl. |
| 288 | 296 | /// The memory is owned by the containing File ZIR. |
| 289 | 297 | pub fn getName(decl: Decl) ?[:0]const u8 { |
| ... | ... | @@ -319,7 +327,7 @@ pub const Decl = struct { |
| 319 | 327 | return @intToEnum(Zir.Inst.Ref, zir.extra[decl.zir_decl_index + 6]); |
| 320 | 328 | } |
| 321 | 329 | |
| 322 | | pub fn zirLinkSectionRef(decl: Decl) Zir.Inst.Ref { |
| 330 | pub fn zirLinksectionRef(decl: Decl) Zir.Inst.Ref { |
| 323 | 331 | if (!decl.has_linksection) return .none; |
| 324 | 332 | const zir = decl.namespace.file_scope.zir; |
| 325 | 333 | const extra_index = decl.zir_decl_index + 6 + @boolToInt(decl.has_align); |
| ... | ... | @@ -727,10 +735,11 @@ pub const Scope = struct { |
| 727 | 735 | base: Scope = Scope{ .tag = base_tag }, |
| 728 | 736 | status: enum { |
| 729 | 737 | never_loaded, |
| 738 | retryable_failure, |
| 730 | 739 | parse_failure, |
| 731 | 740 | astgen_failure, |
| 732 | | retryable_failure, |
| 733 | | success, |
| 741 | success_zir, |
| 742 | success_air, |
| 734 | 743 | }, |
| 735 | 744 | source_loaded: bool, |
| 736 | 745 | tree_loaded: bool, |
| ... | ... | @@ -2043,7 +2052,7 @@ pub const SrcLoc = struct { |
| 2043 | 2052 | return @bitCast(ast.Node.Index, offset + @bitCast(i32, src_loc.parent_decl_node)); |
| 2044 | 2053 | } |
| 2045 | 2054 | |
| 2046 | | pub fn byteOffset(src_loc: SrcLoc) !u32 { |
| 2055 | pub fn byteOffset(src_loc: SrcLoc, gpa: *Allocator) !u32 { |
| 2047 | 2056 | switch (src_loc.lazy) { |
| 2048 | 2057 | .unneeded => unreachable, |
| 2049 | 2058 | .entire_file => return 0, |
| ... | ... | @@ -2051,30 +2060,31 @@ pub const SrcLoc = struct { |
| 2051 | 2060 | .byte_abs => |byte_index| return byte_index, |
| 2052 | 2061 | |
| 2053 | 2062 | .token_abs => |tok_index| { |
| 2054 | | const tree = src_loc.file_scope.tree; |
| 2063 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2055 | 2064 | const token_starts = tree.tokens.items(.start); |
| 2056 | 2065 | return token_starts[tok_index]; |
| 2057 | 2066 | }, |
| 2058 | 2067 | .node_abs => |node| { |
| 2059 | | const tree = src_loc.file_scope.tree; |
| 2068 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2060 | 2069 | const token_starts = tree.tokens.items(.start); |
| 2061 | 2070 | const tok_index = tree.firstToken(node); |
| 2062 | 2071 | return token_starts[tok_index]; |
| 2063 | 2072 | }, |
| 2064 | 2073 | .byte_offset => |byte_off| { |
| 2065 | | const tree = src_loc.file_scope.tree; |
| 2074 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2066 | 2075 | const token_starts = tree.tokens.items(.start); |
| 2067 | 2076 | return token_starts[src_loc.declSrcToken()] + byte_off; |
| 2068 | 2077 | }, |
| 2069 | 2078 | .token_offset => |tok_off| { |
| 2070 | 2079 | const tok_index = src_loc.declSrcToken() + tok_off; |
| 2071 | | const tree = src_loc.file_scope.tree; |
| 2080 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2072 | 2081 | const token_starts = tree.tokens.items(.start); |
| 2073 | 2082 | return token_starts[tok_index]; |
| 2074 | 2083 | }, |
| 2075 | 2084 | .node_offset, .node_offset_bin_op => |node_off| { |
| 2076 | 2085 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| 2077 | | const tree = src_loc.file_scope.tree; |
| 2086 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2087 | assert(src_loc.file_scope.tree_loaded); |
| 2078 | 2088 | const main_tokens = tree.nodes.items(.main_token); |
| 2079 | 2089 | const tok_index = main_tokens[node]; |
| 2080 | 2090 | const token_starts = tree.tokens.items(.start); |
| ... | ... | @@ -2082,14 +2092,14 @@ pub const SrcLoc = struct { |
| 2082 | 2092 | }, |
| 2083 | 2093 | .node_offset_back2tok => |node_off| { |
| 2084 | 2094 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| 2085 | | const tree = src_loc.file_scope.tree; |
| 2095 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2086 | 2096 | const tok_index = tree.firstToken(node) - 2; |
| 2087 | 2097 | const token_starts = tree.tokens.items(.start); |
| 2088 | 2098 | return token_starts[tok_index]; |
| 2089 | 2099 | }, |
| 2090 | 2100 | .node_offset_var_decl_ty => |node_off| { |
| 2091 | 2101 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| 2092 | | const tree = src_loc.file_scope.tree; |
| 2102 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2093 | 2103 | const node_tags = tree.nodes.items(.tag); |
| 2094 | 2104 | const full = switch (node_tags[node]) { |
| 2095 | 2105 | .global_var_decl => tree.globalVarDecl(node), |
| ... | ... | @@ -2108,7 +2118,7 @@ pub const SrcLoc = struct { |
| 2108 | 2118 | return token_starts[tok_index]; |
| 2109 | 2119 | }, |
| 2110 | 2120 | .node_offset_builtin_call_arg0 => |node_off| { |
| 2111 | | const tree = src_loc.file_scope.tree; |
| 2121 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2112 | 2122 | const node_datas = tree.nodes.items(.data); |
| 2113 | 2123 | const node_tags = tree.nodes.items(.tag); |
| 2114 | 2124 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| ... | ... | @@ -2123,7 +2133,7 @@ pub const SrcLoc = struct { |
| 2123 | 2133 | return token_starts[tok_index]; |
| 2124 | 2134 | }, |
| 2125 | 2135 | .node_offset_builtin_call_arg1 => |node_off| { |
| 2126 | | const tree = src_loc.file_scope.tree; |
| 2136 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2127 | 2137 | const node_datas = tree.nodes.items(.data); |
| 2128 | 2138 | const node_tags = tree.nodes.items(.tag); |
| 2129 | 2139 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| ... | ... | @@ -2138,7 +2148,7 @@ pub const SrcLoc = struct { |
| 2138 | 2148 | return token_starts[tok_index]; |
| 2139 | 2149 | }, |
| 2140 | 2150 | .node_offset_array_access_index => |node_off| { |
| 2141 | | const tree = src_loc.file_scope.tree; |
| 2151 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2142 | 2152 | const node_datas = tree.nodes.items(.data); |
| 2143 | 2153 | const node_tags = tree.nodes.items(.tag); |
| 2144 | 2154 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| ... | ... | @@ -2148,7 +2158,7 @@ pub const SrcLoc = struct { |
| 2148 | 2158 | return token_starts[tok_index]; |
| 2149 | 2159 | }, |
| 2150 | 2160 | .node_offset_slice_sentinel => |node_off| { |
| 2151 | | const tree = src_loc.file_scope.tree; |
| 2161 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2152 | 2162 | const node_datas = tree.nodes.items(.data); |
| 2153 | 2163 | const node_tags = tree.nodes.items(.tag); |
| 2154 | 2164 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| ... | ... | @@ -2164,7 +2174,7 @@ pub const SrcLoc = struct { |
| 2164 | 2174 | return token_starts[tok_index]; |
| 2165 | 2175 | }, |
| 2166 | 2176 | .node_offset_call_func => |node_off| { |
| 2167 | | const tree = src_loc.file_scope.tree; |
| 2177 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2168 | 2178 | const node_datas = tree.nodes.items(.data); |
| 2169 | 2179 | const node_tags = tree.nodes.items(.tag); |
| 2170 | 2180 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| ... | ... | @@ -2190,7 +2200,7 @@ pub const SrcLoc = struct { |
| 2190 | 2200 | return token_starts[tok_index]; |
| 2191 | 2201 | }, |
| 2192 | 2202 | .node_offset_field_name => |node_off| { |
| 2193 | | const tree = src_loc.file_scope.tree; |
| 2203 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2194 | 2204 | const node_datas = tree.nodes.items(.data); |
| 2195 | 2205 | const node_tags = tree.nodes.items(.tag); |
| 2196 | 2206 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| ... | ... | @@ -2202,7 +2212,7 @@ pub const SrcLoc = struct { |
| 2202 | 2212 | return token_starts[tok_index]; |
| 2203 | 2213 | }, |
| 2204 | 2214 | .node_offset_deref_ptr => |node_off| { |
| 2205 | | const tree = src_loc.file_scope.tree; |
| 2215 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2206 | 2216 | const node_datas = tree.nodes.items(.data); |
| 2207 | 2217 | const node_tags = tree.nodes.items(.tag); |
| 2208 | 2218 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| ... | ... | @@ -2211,7 +2221,7 @@ pub const SrcLoc = struct { |
| 2211 | 2221 | return token_starts[tok_index]; |
| 2212 | 2222 | }, |
| 2213 | 2223 | .node_offset_asm_source => |node_off| { |
| 2214 | | const tree = src_loc.file_scope.tree; |
| 2224 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2215 | 2225 | const node_datas = tree.nodes.items(.data); |
| 2216 | 2226 | const node_tags = tree.nodes.items(.tag); |
| 2217 | 2227 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| ... | ... | @@ -2226,7 +2236,7 @@ pub const SrcLoc = struct { |
| 2226 | 2236 | return token_starts[tok_index]; |
| 2227 | 2237 | }, |
| 2228 | 2238 | .node_offset_asm_ret_ty => |node_off| { |
| 2229 | | const tree = src_loc.file_scope.tree; |
| 2239 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2230 | 2240 | const node_datas = tree.nodes.items(.data); |
| 2231 | 2241 | const node_tags = tree.nodes.items(.tag); |
| 2232 | 2242 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| ... | ... | @@ -2243,7 +2253,7 @@ pub const SrcLoc = struct { |
| 2243 | 2253 | |
| 2244 | 2254 | .node_offset_for_cond, .node_offset_if_cond => |node_off| { |
| 2245 | 2255 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| 2246 | | const tree = src_loc.file_scope.tree; |
| 2256 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2247 | 2257 | const node_tags = tree.nodes.items(.tag); |
| 2248 | 2258 | const src_node = switch (node_tags[node]) { |
| 2249 | 2259 | .if_simple => tree.ifSimple(node).ast.cond_expr, |
| ... | ... | @@ -2262,7 +2272,7 @@ pub const SrcLoc = struct { |
| 2262 | 2272 | }, |
| 2263 | 2273 | .node_offset_bin_lhs => |node_off| { |
| 2264 | 2274 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| 2265 | | const tree = src_loc.file_scope.tree; |
| 2275 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2266 | 2276 | const node_datas = tree.nodes.items(.data); |
| 2267 | 2277 | const src_node = node_datas[node].lhs; |
| 2268 | 2278 | const main_tokens = tree.nodes.items(.main_token); |
| ... | ... | @@ -2272,7 +2282,7 @@ pub const SrcLoc = struct { |
| 2272 | 2282 | }, |
| 2273 | 2283 | .node_offset_bin_rhs => |node_off| { |
| 2274 | 2284 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| 2275 | | const tree = src_loc.file_scope.tree; |
| 2285 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2276 | 2286 | const node_datas = tree.nodes.items(.data); |
| 2277 | 2287 | const src_node = node_datas[node].rhs; |
| 2278 | 2288 | const main_tokens = tree.nodes.items(.main_token); |
| ... | ... | @@ -2283,7 +2293,7 @@ pub const SrcLoc = struct { |
| 2283 | 2293 | |
| 2284 | 2294 | .node_offset_switch_operand => |node_off| { |
| 2285 | 2295 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| 2286 | | const tree = src_loc.file_scope.tree; |
| 2296 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2287 | 2297 | const node_datas = tree.nodes.items(.data); |
| 2288 | 2298 | const src_node = node_datas[node].lhs; |
| 2289 | 2299 | const main_tokens = tree.nodes.items(.main_token); |
| ... | ... | @@ -2294,7 +2304,7 @@ pub const SrcLoc = struct { |
| 2294 | 2304 | |
| 2295 | 2305 | .node_offset_switch_special_prong => |node_off| { |
| 2296 | 2306 | const switch_node = src_loc.declRelativeToNodeIndex(node_off); |
| 2297 | | const tree = src_loc.file_scope.tree; |
| 2307 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2298 | 2308 | const node_datas = tree.nodes.items(.data); |
| 2299 | 2309 | const node_tags = tree.nodes.items(.tag); |
| 2300 | 2310 | const main_tokens = tree.nodes.items(.main_token); |
| ... | ... | @@ -2320,7 +2330,7 @@ pub const SrcLoc = struct { |
| 2320 | 2330 | |
| 2321 | 2331 | .node_offset_switch_range => |node_off| { |
| 2322 | 2332 | const switch_node = src_loc.declRelativeToNodeIndex(node_off); |
| 2323 | | const tree = src_loc.file_scope.tree; |
| 2333 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2324 | 2334 | const node_datas = tree.nodes.items(.data); |
| 2325 | 2335 | const node_tags = tree.nodes.items(.tag); |
| 2326 | 2336 | const main_tokens = tree.nodes.items(.main_token); |
| ... | ... | @@ -2349,7 +2359,7 @@ pub const SrcLoc = struct { |
| 2349 | 2359 | }, |
| 2350 | 2360 | |
| 2351 | 2361 | .node_offset_fn_type_cc => |node_off| { |
| 2352 | | const tree = src_loc.file_scope.tree; |
| 2362 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2353 | 2363 | const node_datas = tree.nodes.items(.data); |
| 2354 | 2364 | const node_tags = tree.nodes.items(.tag); |
| 2355 | 2365 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| ... | ... | @@ -2368,7 +2378,7 @@ pub const SrcLoc = struct { |
| 2368 | 2378 | }, |
| 2369 | 2379 | |
| 2370 | 2380 | .node_offset_fn_type_ret_ty => |node_off| { |
| 2371 | | const tree = src_loc.file_scope.tree; |
| 2381 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2372 | 2382 | const node_datas = tree.nodes.items(.data); |
| 2373 | 2383 | const node_tags = tree.nodes.items(.tag); |
| 2374 | 2384 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| ... | ... | @@ -2387,7 +2397,7 @@ pub const SrcLoc = struct { |
| 2387 | 2397 | }, |
| 2388 | 2398 | |
| 2389 | 2399 | .node_offset_anyframe_type => |node_off| { |
| 2390 | | const tree = src_loc.file_scope.tree; |
| 2400 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2391 | 2401 | const node_datas = tree.nodes.items(.data); |
| 2392 | 2402 | const node_tags = tree.nodes.items(.tag); |
| 2393 | 2403 | const parent_node = src_loc.declRelativeToNodeIndex(node_off); |
| ... | ... | @@ -2912,7 +2922,7 @@ pub fn astGenFile(mod: *Module, file: *Scope.File, prog_node: *std.Progress.Node |
| 2912 | 2922 | file.stat_size = header.stat_size; |
| 2913 | 2923 | file.stat_inode = header.stat_inode; |
| 2914 | 2924 | file.stat_mtime = header.stat_mtime; |
| 2915 | | file.status = .success; |
| 2925 | file.status = .success_zir; |
| 2916 | 2926 | log.debug("AstGen cached success: {s}", .{file.sub_file_path}); |
| 2917 | 2927 | |
| 2918 | 2928 | // TODO don't report compile errors until Sema @importFile |
| ... | ... | @@ -2927,7 +2937,7 @@ pub fn astGenFile(mod: *Module, file: *Scope.File, prog_node: *std.Progress.Node |
| 2927 | 2937 | } |
| 2928 | 2938 | return; |
| 2929 | 2939 | }, |
| 2930 | | .parse_failure, .astgen_failure, .success => { |
| 2940 | .parse_failure, .astgen_failure, .success_zir, .success_air => { |
| 2931 | 2941 | const unchanged_metadata = |
| 2932 | 2942 | stat.size == file.stat_size and |
| 2933 | 2943 | stat.mtime == file.stat_mtime and |
| ... | ... | @@ -3024,7 +3034,7 @@ pub fn astGenFile(mod: *Module, file: *Scope.File, prog_node: *std.Progress.Node |
| 3024 | 3034 | |
| 3025 | 3035 | file.zir = try AstGen.generate(gpa, file); |
| 3026 | 3036 | file.zir_loaded = true; |
| 3027 | | file.status = .success; |
| 3037 | file.status = .success_zir; |
| 3028 | 3038 | log.debug("AstGen fresh success: {s}", .{file.sub_file_path}); |
| 3029 | 3039 | |
| 3030 | 3040 | const safety_buffer = if (data_has_safety_tag) |
| ... | ... | @@ -3197,11 +3207,13 @@ pub fn semaPkg(mod: *Module, pkg: *Package) !void { |
| 3197 | 3207 | } |
| 3198 | 3208 | |
| 3199 | 3209 | pub fn semaFile(mod: *Module, file: *Scope.File) InnerError!void { |
| 3210 | if (file.status == .success_air) return; |
| 3211 | |
| 3200 | 3212 | const tracy = trace(@src()); |
| 3201 | 3213 | defer tracy.end(); |
| 3202 | 3214 | |
| 3203 | 3215 | assert(file.zir_loaded); |
| 3204 | | assert(!file.zir.hasCompileErrors()); |
| 3216 | assert(file.status == .success_zir); |
| 3205 | 3217 | |
| 3206 | 3218 | const gpa = mod.gpa; |
| 3207 | 3219 | var decl_arena = std.heap.ArenaAllocator.init(gpa); |
| ... | ... | @@ -3279,6 +3291,7 @@ pub fn semaFile(mod: *Module, file: *Scope.File) InnerError!void { |
| 3279 | 3291 | if (dep == struct_decl) continue; |
| 3280 | 3292 | _ = try mod.declareDeclDependency(struct_decl, dep); |
| 3281 | 3293 | } |
| 3294 | file.status = .success_air; |
| 3282 | 3295 | } |
| 3283 | 3296 | |
| 3284 | 3297 | /// Returns `true` if the Decl type changed. |
| ... | ... | @@ -3319,26 +3332,128 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { |
| 3319 | 3332 | }; |
| 3320 | 3333 | defer block_scope.instructions.deinit(gpa); |
| 3321 | 3334 | |
| 3335 | const zir_datas = zir.instructions.items(.data); |
| 3336 | const zir_tags = zir.instructions.items(.tag); |
| 3337 | |
| 3322 | 3338 | const zir_block_index = decl.zirBlockIndex(); |
| 3323 | | const inst_data = zir.instructions.items(.data)[zir_block_index].pl_node; |
| 3339 | const inst_data = zir_datas[zir_block_index].pl_node; |
| 3324 | 3340 | const extra = zir.extraData(Zir.Inst.Block, inst_data.payload_index); |
| 3325 | 3341 | const body = zir.extra[extra.end..][0..extra.data.body_len]; |
| 3326 | 3342 | const break_index = try sema.analyzeBody(&block_scope, body); |
| 3343 | const result_ref = zir_datas[break_index].@"break".operand; |
| 3344 | const decl_tv = try sema.resolveInstConst(&block_scope, inst_data.src(), result_ref); |
| 3345 | const align_val = blk: { |
| 3346 | const align_ref = decl.zirAlignRef(); |
| 3347 | if (align_ref == .none) break :blk Value.initTag(.null_value); |
| 3348 | break :blk (try sema.resolveInstConst(&block_scope, inst_data.src(), align_ref)).val; |
| 3349 | }; |
| 3350 | const linksection_val = blk: { |
| 3351 | const linksection_ref = decl.zirLinksectionRef(); |
| 3352 | if (linksection_ref == .none) break :blk Value.initTag(.null_value); |
| 3353 | break :blk (try sema.resolveInstConst(&block_scope, inst_data.src(), linksection_ref)).val; |
| 3354 | }; |
| 3327 | 3355 | |
| 3328 | | if (decl.zirAlignRef() != .none) { |
| 3329 | | @panic("TODO implement decl align"); |
| 3330 | | } |
| 3331 | | if (decl.zirLinkSectionRef() != .none) { |
| 3332 | | @panic("TODO implement decl linksection"); |
| 3333 | | } |
| 3356 | // We need the memory for the Type to go into the arena for the Decl |
| 3357 | var decl_arena = std.heap.ArenaAllocator.init(gpa); |
| 3358 | errdefer decl_arena.deinit(); |
| 3359 | const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State); |
| 3360 | |
| 3361 | if (decl_tv.val.tag() == .function) { |
| 3362 | var prev_type_has_bits = false; |
| 3363 | var prev_is_inline = false; |
| 3364 | var type_changed = true; |
| 3365 | |
| 3366 | if (decl.has_tv) { |
| 3367 | prev_type_has_bits = decl.ty.hasCodeGenBits(); |
| 3368 | type_changed = !decl.ty.eql(decl_tv.ty); |
| 3369 | if (decl.val.castTag(.function)) |payload| { |
| 3370 | const prev_func = payload.data; |
| 3371 | prev_is_inline = prev_func.state == .inline_only; |
| 3372 | prev_func.deinit(gpa); |
| 3373 | } |
| 3374 | decl.clearValues(gpa); |
| 3375 | } |
| 3334 | 3376 | |
| 3335 | | decl.analysis = .complete; |
| 3336 | | decl.generation = mod.generation; |
| 3377 | decl.ty = try decl_tv.ty.copy(&decl_arena.allocator); |
| 3378 | decl.val = try decl_tv.val.copy(&decl_arena.allocator); |
| 3379 | decl.align_val = try align_val.copy(&decl_arena.allocator); |
| 3380 | decl.linksection_val = try linksection_val.copy(&decl_arena.allocator); |
| 3381 | decl.has_tv = true; |
| 3382 | decl_arena_state.* = decl_arena.state; |
| 3383 | decl.value_arena = decl_arena_state; |
| 3384 | decl.analysis = .complete; |
| 3385 | decl.generation = mod.generation; |
| 3386 | |
| 3387 | const is_inline = decl_tv.ty.fnCallingConvention() == .Inline; |
| 3388 | if (!is_inline and decl_tv.ty.hasCodeGenBits()) { |
| 3389 | // We don't fully codegen the decl until later, but we do need to reserve a global |
| 3390 | // offset table index for it. This allows us to codegen decls out of dependency order, |
| 3391 | // increasing how many computations can be done in parallel. |
| 3392 | try mod.comp.bin_file.allocateDeclIndexes(decl); |
| 3393 | try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl }); |
| 3394 | if (type_changed and mod.emit_h != null) { |
| 3395 | try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl }); |
| 3396 | } |
| 3397 | } else if (!prev_is_inline and prev_type_has_bits) { |
| 3398 | mod.comp.bin_file.freeDecl(decl); |
| 3399 | } |
| 3400 | |
| 3401 | if (decl.is_exported) { |
| 3402 | const export_src = inst_data.src(); // TODO make this point at `export` token |
| 3403 | if (is_inline) { |
| 3404 | return mod.fail(&block_scope.base, export_src, "export of inline function", .{}); |
| 3405 | } |
| 3406 | // The scope needs to have the decl in it. |
| 3407 | try mod.analyzeExport(&block_scope.base, export_src, mem.spanZ(decl.name), decl); |
| 3408 | } |
| 3409 | return type_changed or is_inline != prev_is_inline; |
| 3410 | } else { |
| 3411 | const is_mutable = zir_tags[zir_block_index] == .block_inline_var; |
| 3337 | 3412 | |
| 3338 | | // TODO inspect the type and return a proper type_changed result |
| 3339 | | @breakpoint(); |
| 3413 | var is_threadlocal = false; // TODO implement threadlocal variables |
| 3414 | var is_extern = false; // TODO implement extern variables |
| 3340 | 3415 | |
| 3341 | | return true; |
| 3416 | if (is_mutable and !decl_tv.ty.isValidVarType(is_extern)) { |
| 3417 | return mod.fail( |
| 3418 | &block_scope.base, |
| 3419 | inst_data.src(), // TODO point at the mut token |
| 3420 | "variable of type '{}' must be const", |
| 3421 | .{decl_tv.ty}, |
| 3422 | ); |
| 3423 | } |
| 3424 | |
| 3425 | var type_changed = true; |
| 3426 | if (decl.has_tv) { |
| 3427 | type_changed = !decl.ty.eql(decl_tv.ty); |
| 3428 | decl.clearValues(gpa); |
| 3429 | } |
| 3430 | |
| 3431 | const new_variable = try decl_arena.allocator.create(Var); |
| 3432 | new_variable.* = .{ |
| 3433 | .owner_decl = decl, |
| 3434 | .init = try decl_tv.val.copy(&decl_arena.allocator), |
| 3435 | .is_extern = is_extern, |
| 3436 | .is_mutable = is_mutable, |
| 3437 | .is_threadlocal = is_threadlocal, |
| 3438 | }; |
| 3439 | |
| 3440 | decl.ty = try decl_tv.ty.copy(&decl_arena.allocator); |
| 3441 | decl.val = try Value.Tag.variable.create(&decl_arena.allocator, new_variable); |
| 3442 | decl.align_val = try align_val.copy(&decl_arena.allocator); |
| 3443 | decl.linksection_val = try linksection_val.copy(&decl_arena.allocator); |
| 3444 | decl.has_tv = true; |
| 3445 | decl_arena_state.* = decl_arena.state; |
| 3446 | decl.value_arena = decl_arena_state; |
| 3447 | decl.analysis = .complete; |
| 3448 | decl.generation = mod.generation; |
| 3449 | |
| 3450 | if (decl.is_exported) { |
| 3451 | const export_src = inst_data.src(); // TODO point to the export token |
| 3452 | // The scope needs to have the decl in it. |
| 3453 | try mod.analyzeExport(&block_scope.base, export_src, mem.spanZ(decl.name), decl); |
| 3454 | } |
| 3455 | return type_changed; |
| 3456 | } |
| 3342 | 3457 | } |
| 3343 | 3458 | |
| 3344 | 3459 | /// Returns the depender's index of the dependee. |
| ... | ... | @@ -4160,6 +4275,7 @@ fn getNextAnonNameIndex(mod: *Module) usize { |
| 4160 | 4275 | |
| 4161 | 4276 | /// This looks up a bare identifier in the given scope. This will walk up the tree of namespaces |
| 4162 | 4277 | /// in scope and check each one for the identifier. |
| 4278 | /// TODO emit a compile error if more than one decl would be matched. |
| 4163 | 4279 | pub fn lookupIdentifier(mod: *Module, scope: *Scope, ident_name: []const u8) ?*Decl { |
| 4164 | 4280 | var namespace = scope.namespace(); |
| 4165 | 4281 | while (true) { |
| ... | ... | @@ -4179,13 +4295,14 @@ pub fn lookupInNamespace( |
| 4179 | 4295 | ident_name: []const u8, |
| 4180 | 4296 | only_pub_usingnamespaces: bool, |
| 4181 | 4297 | ) ?*Decl { |
| 4182 | | @panic("TODO lookupInNamespace"); |
| 4298 | // TODO the decl doing the looking up needs to create a decl dependency |
| 4299 | // TODO implement usingnamespace |
| 4300 | if (namespace.decls.get(ident_name)) |decl| { |
| 4301 | return decl; |
| 4302 | } |
| 4303 | return null; |
| 4183 | 4304 | //// TODO handle decl collision with usingnamespace |
| 4184 | | //// TODO the decl doing the looking up needs to create a decl dependency |
| 4185 | 4305 | //// on each usingnamespace decl here. |
| 4186 | | //if (mod.decl_table.get(name_hash)) |decl| { |
| 4187 | | // return decl; |
| 4188 | | //} |
| 4189 | 4306 | //{ |
| 4190 | 4307 | // var it = namespace.usingnamespace_set.iterator(); |
| 4191 | 4308 | // while (it.next()) |entry| { |
| ... | ... | @@ -4198,7 +4315,6 @@ pub fn lookupInNamespace( |
| 4198 | 4315 | // } |
| 4199 | 4316 | // } |
| 4200 | 4317 | //} |
| 4201 | | //return null; |
| 4202 | 4318 | } |
| 4203 | 4319 | |
| 4204 | 4320 | pub fn makeIntType(arena: *Allocator, signedness: std.builtin.Signedness, bits: u16) !Type { |
| ... | ... | @@ -4659,7 +4775,7 @@ pub fn optimizeMode(mod: Module) std.builtin.Mode { |
| 4659 | 4775 | |
| 4660 | 4776 | fn lockAndClearFileCompileError(mod: *Module, file: *Scope.File) void { |
| 4661 | 4777 | switch (file.status) { |
| 4662 | | .success, .retryable_failure => {}, |
| 4778 | .success_zir, .success_air, .retryable_failure => {}, |
| 4663 | 4779 | .never_loaded, .parse_failure, .astgen_failure => { |
| 4664 | 4780 | const lock = mod.comp.mutex.acquire(); |
| 4665 | 4781 | defer lock.release(); |