| ... | @@ -28,6 +28,8 @@ static Error ATTRIBUTE_MUST_USE resolve_union_zero_bits(CodeGen *g, ZigType *uni | ... | @@ -28,6 +28,8 @@ static Error ATTRIBUTE_MUST_USE resolve_union_zero_bits(CodeGen *g, ZigType *uni |
| 28 | static Error ATTRIBUTE_MUST_USE resolve_union_alignment(CodeGen *g, ZigType *union_type); | 28 | static Error ATTRIBUTE_MUST_USE resolve_union_alignment(CodeGen *g, ZigType *union_type); |
| 29 | static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry); | 29 | static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry); |
| 30 | static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status); | 30 | static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status); |
| | 31 | static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, ScopeDecls *dest_decls_scope); |
| | 32 | static void resolve_use_decl(CodeGen *g, TldUsingNamespace *tld_using_namespace, ScopeDecls *dest_decls_scope); |
| 31 | | 33 | |
| 32 | static bool is_top_level_struct(ZigType *import) { | 34 | static bool is_top_level_struct(ZigType *import) { |
| 33 | return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr; | 35 | return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr; |
| ... | @@ -2854,6 +2856,8 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { | ... | @@ -2854,6 +2856,8 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { |
| 2854 | add_node_error(g, tld->source_node, buf_sprintf("non-extern function has no body")); | 2856 | add_node_error(g, tld->source_node, buf_sprintf("non-extern function has no body")); |
| 2855 | return; | 2857 | return; |
| 2856 | } | 2858 | } |
| | 2859 | } else if (tld->id == TldIdUsingNamespace) { |
| | 2860 | g->resolve_queue.append(tld); |
| 2857 | } | 2861 | } |
| 2858 | if (is_export) { | 2862 | if (is_export) { |
| 2859 | g->resolve_queue.append(tld); | 2863 | g->resolve_queue.append(tld); |
| ... | @@ -2867,7 +2871,7 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { | ... | @@ -2867,7 +2871,7 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { |
| 2867 | } | 2871 | } |
| 2868 | } | 2872 | } |
| 2869 | | 2873 | |
| 2870 | { | 2874 | if (tld->name != nullptr) { |
| 2871 | auto entry = decls_scope->decl_table.put_unique(tld->name, tld); | 2875 | auto entry = decls_scope->decl_table.put_unique(tld->name, tld); |
| 2872 | if (entry) { | 2876 | if (entry) { |
| 2873 | Tld *other_tld = entry->value; | 2877 | Tld *other_tld = entry->value; |
| ... | @@ -2875,9 +2879,7 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { | ... | @@ -2875,9 +2879,7 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { |
| 2875 | add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition is here")); | 2879 | add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition is here")); |
| 2876 | return; | 2880 | return; |
| 2877 | } | 2881 | } |
| 2878 | } | | |
| 2879 | | 2882 | |
| 2880 | { | | |
| 2881 | ZigType *type; | 2883 | ZigType *type; |
| 2882 | if (get_primitive_type(g, tld->name, &type) != ErrorPrimitiveTypeNotFound) { | 2884 | if (get_primitive_type(g, tld->name, &type) != ErrorPrimitiveTypeNotFound) { |
| 2883 | add_node_error(g, tld->source_node, | 2885 | add_node_error(g, tld->source_node, |
| ... | @@ -2977,12 +2979,14 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { | ... | @@ -2977,12 +2979,14 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { |
| 2977 | | 2979 | |
| 2978 | break; | 2980 | break; |
| 2979 | } | 2981 | } |
| 2980 | case NodeTypeUse: | 2982 | case NodeTypeUsingNamespace: { |
| 2981 | { | 2983 | VisibMod visib_mod = node->data.using_namespace.visib_mod; |
| 2982 | g->use_queue.append(node); | 2984 | TldUsingNamespace *tld_using_namespace = allocate<TldUsingNamespace>(1); |
| 2983 | decls_scope->use_decls.append(node); | 2985 | init_tld(&tld_using_namespace->base, TldIdUsingNamespace, nullptr, visib_mod, node, &decls_scope->base); |
| 2984 | break; | 2986 | add_top_level_decl(g, decls_scope, &tld_using_namespace->base); |
| 2985 | } | 2987 | decls_scope->use_decls.append(tld_using_namespace); |
| | 2988 | break; |
| | 2989 | } |
| 2986 | case NodeTypeTestDecl: | 2990 | case NodeTypeTestDecl: |
| 2987 | preview_test_decl(g, node, decls_scope); | 2991 | preview_test_decl(g, node, decls_scope); |
| 2988 | break; | 2992 | break; |
| ... | @@ -3266,6 +3270,117 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { | ... | @@ -3266,6 +3270,117 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { |
| 3266 | g->global_vars.append(tld_var); | 3270 | g->global_vars.append(tld_var); |
| 3267 | } | 3271 | } |
| 3268 | | 3272 | |
| | 3273 | static void add_symbols_from_container(CodeGen *g, TldUsingNamespace *src_using_namespace, |
| | 3274 | TldUsingNamespace *dst_using_namespace, ScopeDecls* dest_decls_scope) |
| | 3275 | { |
| | 3276 | if (src_using_namespace->base.resolution == TldResolutionUnresolved || |
| | 3277 | src_using_namespace->base.resolution == TldResolutionResolving) |
| | 3278 | { |
| | 3279 | assert(src_using_namespace->base.parent_scope->id == ScopeIdDecls); |
| | 3280 | ScopeDecls *src_decls_scope = (ScopeDecls *)src_using_namespace->base.parent_scope; |
| | 3281 | preview_use_decl(g, src_using_namespace, src_decls_scope); |
| | 3282 | if (src_using_namespace != dst_using_namespace) { |
| | 3283 | resolve_use_decl(g, src_using_namespace, src_decls_scope); |
| | 3284 | } |
| | 3285 | } |
| | 3286 | |
| | 3287 | ConstExprValue *use_expr = src_using_namespace->using_namespace_value; |
| | 3288 | if (type_is_invalid(use_expr->type)) { |
| | 3289 | dest_decls_scope->any_imports_failed = true; |
| | 3290 | return; |
| | 3291 | } |
| | 3292 | |
| | 3293 | dst_using_namespace->base.resolution = TldResolutionOk; |
| | 3294 | |
| | 3295 | assert(use_expr->special != ConstValSpecialRuntime); |
| | 3296 | |
| | 3297 | // The source scope for the imported symbols |
| | 3298 | ScopeDecls *src_scope = get_container_scope(use_expr->data.x_type); |
| | 3299 | // The top-level container where the symbols are defined, it's used in the |
| | 3300 | // loop below in order to exclude the ones coming from an import statement |
| | 3301 | ZigType *src_import = get_scope_import(&src_scope->base); |
| | 3302 | assert(src_import != nullptr); |
| | 3303 | |
| | 3304 | if (src_scope->any_imports_failed) { |
| | 3305 | dest_decls_scope->any_imports_failed = true; |
| | 3306 | } |
| | 3307 | |
| | 3308 | auto it = src_scope->decl_table.entry_iterator(); |
| | 3309 | for (;;) { |
| | 3310 | auto *entry = it.next(); |
| | 3311 | if (!entry) |
| | 3312 | break; |
| | 3313 | |
| | 3314 | Buf *target_tld_name = entry->key; |
| | 3315 | Tld *target_tld = entry->value; |
| | 3316 | |
| | 3317 | if (target_tld->visib_mod == VisibModPrivate) { |
| | 3318 | continue; |
| | 3319 | } |
| | 3320 | |
| | 3321 | if (target_tld->import != src_import) { |
| | 3322 | continue; |
| | 3323 | } |
| | 3324 | |
| | 3325 | auto existing_entry = dest_decls_scope->decl_table.put_unique(target_tld_name, target_tld); |
| | 3326 | if (existing_entry) { |
| | 3327 | Tld *existing_decl = existing_entry->value; |
| | 3328 | if (existing_decl != target_tld) { |
| | 3329 | ErrorMsg *msg = add_node_error(g, dst_using_namespace->base.source_node, |
| | 3330 | buf_sprintf("import of '%s' overrides existing definition", |
| | 3331 | buf_ptr(target_tld_name))); |
| | 3332 | add_error_note(g, msg, existing_decl->source_node, buf_sprintf("previous definition here")); |
| | 3333 | add_error_note(g, msg, target_tld->source_node, buf_sprintf("imported definition here")); |
| | 3334 | } |
| | 3335 | } |
| | 3336 | } |
| | 3337 | |
| | 3338 | for (size_t i = 0; i < src_scope->use_decls.length; i += 1) { |
| | 3339 | TldUsingNamespace *tld_using_namespace = src_scope->use_decls.at(i); |
| | 3340 | if (tld_using_namespace->base.visib_mod != VisibModPrivate) |
| | 3341 | add_symbols_from_container(g, tld_using_namespace, dst_using_namespace, dest_decls_scope); |
| | 3342 | } |
| | 3343 | } |
| | 3344 | |
| | 3345 | static void resolve_use_decl(CodeGen *g, TldUsingNamespace *tld_using_namespace, ScopeDecls *dest_decls_scope) { |
| | 3346 | if (tld_using_namespace->base.resolution == TldResolutionOk || |
| | 3347 | tld_using_namespace->base.resolution == TldResolutionInvalid) |
| | 3348 | { |
| | 3349 | return; |
| | 3350 | } |
| | 3351 | add_symbols_from_container(g, tld_using_namespace, tld_using_namespace, dest_decls_scope); |
| | 3352 | } |
| | 3353 | |
| | 3354 | static void preview_use_decl(CodeGen *g, TldUsingNamespace *using_namespace, ScopeDecls *dest_decls_scope) { |
| | 3355 | if (using_namespace->base.resolution == TldResolutionOk || |
| | 3356 | using_namespace->base.resolution == TldResolutionInvalid) |
| | 3357 | { |
| | 3358 | return; |
| | 3359 | } |
| | 3360 | |
| | 3361 | using_namespace->base.resolution = TldResolutionResolving; |
| | 3362 | assert(using_namespace->base.source_node->type == NodeTypeUsingNamespace); |
| | 3363 | ConstExprValue *result = analyze_const_value(g, &dest_decls_scope->base, |
| | 3364 | using_namespace->base.source_node->data.using_namespace.expr, g->builtin_types.entry_type, nullptr); |
| | 3365 | using_namespace->using_namespace_value = result; |
| | 3366 | |
| | 3367 | if (type_is_invalid(result->type)) { |
| | 3368 | dest_decls_scope->any_imports_failed = true; |
| | 3369 | using_namespace->base.resolution = TldResolutionInvalid; |
| | 3370 | using_namespace->using_namespace_value = &g->invalid_instruction->value; |
| | 3371 | return; |
| | 3372 | } |
| | 3373 | |
| | 3374 | if (!is_container(result->data.x_type)) { |
| | 3375 | add_node_error(g, using_namespace->base.source_node, |
| | 3376 | buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&result->data.x_type->name))); |
| | 3377 | dest_decls_scope->any_imports_failed = true; |
| | 3378 | using_namespace->base.resolution = TldResolutionInvalid; |
| | 3379 | using_namespace->using_namespace_value = &g->invalid_instruction->value; |
| | 3380 | return; |
| | 3381 | } |
| | 3382 | } |
| | 3383 | |
| 3269 | void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) { | 3384 | void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) { |
| 3270 | if (tld->resolution != TldResolutionUnresolved) | 3385 | if (tld->resolution != TldResolutionUnresolved) |
| 3271 | return; | 3386 | return; |
| ... | @@ -3299,6 +3414,14 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) { | ... | @@ -3299,6 +3414,14 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) { |
| 3299 | resolve_decl_comptime(g, tld_comptime); | 3414 | resolve_decl_comptime(g, tld_comptime); |
| 3300 | break; | 3415 | break; |
| 3301 | } | 3416 | } |
| | 3417 | case TldIdUsingNamespace: { |
| | 3418 | TldUsingNamespace *tld_using_namespace = (TldUsingNamespace *)tld; |
| | 3419 | assert(tld_using_namespace->base.parent_scope->id == ScopeIdDecls); |
| | 3420 | ScopeDecls *dest_decls_scope = (ScopeDecls *)tld_using_namespace->base.parent_scope; |
| | 3421 | preview_use_decl(g, tld_using_namespace, dest_decls_scope); |
| | 3422 | resolve_use_decl(g, tld_using_namespace, dest_decls_scope); |
| | 3423 | break; |
| | 3424 | } |
| 3302 | } | 3425 | } |
| 3303 | | 3426 | |
| 3304 | tld->resolution = TldResolutionOk; | 3427 | tld->resolution = TldResolutionOk; |
| ... | @@ -3308,10 +3431,10 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) { | ... | @@ -3308,10 +3431,10 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, AstNode *source_node) { |
| 3308 | Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) { | 3431 | Tld *find_container_decl(CodeGen *g, ScopeDecls *decls_scope, Buf *name) { |
| 3309 | // resolve all the using_namespace decls | 3432 | // resolve all the using_namespace decls |
| 3310 | for (size_t i = 0; i < decls_scope->use_decls.length; i += 1) { | 3433 | for (size_t i = 0; i < decls_scope->use_decls.length; i += 1) { |
| 3311 | AstNode *use_decl_node = decls_scope->use_decls.at(i); | 3434 | TldUsingNamespace *tld_using_namespace = decls_scope->use_decls.at(i); |
| 3312 | if (use_decl_node->data.using_namespace.resolution == TldResolutionUnresolved) { | 3435 | if (tld_using_namespace->base.resolution == TldResolutionUnresolved) { |
| 3313 | preview_use_decl(g, use_decl_node, decls_scope); | 3436 | preview_use_decl(g, tld_using_namespace, decls_scope); |
| 3314 | resolve_use_decl(g, use_decl_node, decls_scope); | 3437 | resolve_use_decl(g, tld_using_namespace, decls_scope); |
| 3315 | } | 3438 | } |
| 3316 | } | 3439 | } |
| 3317 | | 3440 | |
| ... | @@ -3752,110 +3875,6 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) { | ... | @@ -3752,110 +3875,6 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) { |
| 3752 | analyze_fn_ir(g, fn_table_entry, return_type_node); | 3875 | analyze_fn_ir(g, fn_table_entry, return_type_node); |
| 3753 | } | 3876 | } |
| 3754 | | 3877 | |
| 3755 | static void add_symbols_from_container(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node, ScopeDecls* decls_scope) { | | |
| 3756 | if (src_use_node->data.using_namespace.resolution == TldResolutionUnresolved) { | | |
| 3757 | preview_use_decl(g, src_use_node, decls_scope); | | |
| 3758 | } | | |
| 3759 | | | |
| 3760 | ConstExprValue *use_expr = src_use_node->data.using_namespace.using_namespace_value; | | |
| 3761 | if (type_is_invalid(use_expr->type)) { | | |
| 3762 | decls_scope->any_imports_failed = true; | | |
| 3763 | return; | | |
| 3764 | } | | |
| 3765 | | | |
| 3766 | dst_use_node->data.using_namespace.resolution = TldResolutionOk; | | |
| 3767 | | | |
| 3768 | assert(use_expr->special != ConstValSpecialRuntime); | | |
| 3769 | | | |
| 3770 | // The source struct for the imported symbols | | |
| 3771 | ZigType *src_ty = use_expr->data.x_type; | | |
| 3772 | assert(src_ty); | | |
| 3773 | | | |
| 3774 | if (!is_container(src_ty)) { | | |
| 3775 | add_node_error(g, dst_use_node, | | |
| 3776 | buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&src_ty->name))); | | |
| 3777 | decls_scope->any_imports_failed = true; | | |
| 3778 | return; | | |
| 3779 | } | | |
| 3780 | | | |
| 3781 | // The source scope for the imported symbols | | |
| 3782 | ScopeDecls *src_scope = get_container_scope(src_ty); | | |
| 3783 | // The top-level container where the symbols are defined, it's used in the | | |
| 3784 | // loop below in order to exclude the ones coming from an import statement | | |
| 3785 | ZigType *src_import = get_scope_import(&src_scope->base); | | |
| 3786 | assert(src_import != nullptr); | | |
| 3787 | | | |
| 3788 | if (src_scope->any_imports_failed) { | | |
| 3789 | decls_scope->any_imports_failed = true; | | |
| 3790 | } | | |
| 3791 | | | |
| 3792 | auto it = src_scope->decl_table.entry_iterator(); | | |
| 3793 | for (;;) { | | |
| 3794 | auto *entry = it.next(); | | |
| 3795 | if (!entry) | | |
| 3796 | break; | | |
| 3797 | | | |
| 3798 | Buf *target_tld_name = entry->key; | | |
| 3799 | Tld *target_tld = entry->value; | | |
| 3800 | | | |
| 3801 | if (target_tld->visib_mod == VisibModPrivate) { | | |
| 3802 | continue; | | |
| 3803 | } | | |
| 3804 | | | |
| 3805 | if (target_tld->import != src_import) { | | |
| 3806 | continue; | | |
| 3807 | } | | |
| 3808 | | | |
| 3809 | auto existing_entry = decls_scope->decl_table.put_unique(target_tld_name, target_tld); | | |
| 3810 | if (existing_entry) { | | |
| 3811 | Tld *existing_decl = existing_entry->value; | | |
| 3812 | if (existing_decl != target_tld) { | | |
| 3813 | ErrorMsg *msg = add_node_error(g, dst_use_node, | | |
| 3814 | buf_sprintf("import of '%s' overrides existing definition", | | |
| 3815 | buf_ptr(target_tld_name))); | | |
| 3816 | add_error_note(g, msg, existing_decl->source_node, buf_sprintf("previous definition here")); | | |
| 3817 | add_error_note(g, msg, target_tld->source_node, buf_sprintf("imported definition here")); | | |
| 3818 | } | | |
| 3819 | } | | |
| 3820 | } | | |
| 3821 | | | |
| 3822 | for (size_t i = 0; i < src_scope->use_decls.length; i += 1) { | | |
| 3823 | AstNode *use_decl_node = src_scope->use_decls.at(i); | | |
| 3824 | if (use_decl_node->data.using_namespace.visib_mod != VisibModPrivate) | | |
| 3825 | add_symbols_from_container(g, use_decl_node, dst_use_node, decls_scope); | | |
| 3826 | } | | |
| 3827 | } | | |
| 3828 | | | |
| 3829 | void resolve_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) { | | |
| 3830 | assert(node->type == NodeTypeUse); | | |
| 3831 | | | |
| 3832 | if (node->data.using_namespace.resolution == TldResolutionOk || | | |
| 3833 | node->data.using_namespace.resolution == TldResolutionInvalid) | | |
| 3834 | { | | |
| 3835 | return; | | |
| 3836 | } | | |
| 3837 | add_symbols_from_container(g, node, node, decls_scope); | | |
| 3838 | } | | |
| 3839 | | | |
| 3840 | void preview_use_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) { | | |
| 3841 | assert(node->type == NodeTypeUse); | | |
| 3842 | | | |
| 3843 | if (node->data.using_namespace.resolution == TldResolutionOk || | | |
| 3844 | node->data.using_namespace.resolution == TldResolutionInvalid) | | |
| 3845 | { | | |
| 3846 | return; | | |
| 3847 | } | | |
| 3848 | | | |
| 3849 | node->data.using_namespace.resolution = TldResolutionResolving; | | |
| 3850 | ConstExprValue *result = analyze_const_value(g, &decls_scope->base, | | |
| 3851 | node->data.using_namespace.expr, g->builtin_types.entry_type, nullptr); | | |
| 3852 | | | |
| 3853 | if (type_is_invalid(result->type)) | | |
| 3854 | decls_scope->any_imports_failed = true; | | |
| 3855 | | | |
| 3856 | node->data.using_namespace.using_namespace_value = result; | | |
| 3857 | } | | |
| 3858 | | | |
| 3859 | ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Buf *source_code, | 3878 | ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Buf *source_code, |
| 3860 | SourceKind source_kind) | 3879 | SourceKind source_kind) |
| 3861 | { | 3880 | { |
| ... | @@ -3975,18 +3994,8 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu | ... | @@ -3975,18 +3994,8 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu |
| 3975 | | 3994 | |
| 3976 | void semantic_analyze(CodeGen *g) { | 3995 | void semantic_analyze(CodeGen *g) { |
| 3977 | while (g->resolve_queue_index < g->resolve_queue.length || | 3996 | while (g->resolve_queue_index < g->resolve_queue.length || |
| 3978 | g->fn_defs_index < g->fn_defs.length || | 3997 | g->fn_defs_index < g->fn_defs.length) |
| 3979 | g->use_queue_index < g->use_queue.length) | | |
| 3980 | { | 3998 | { |
| 3981 | for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) { | | |
| 3982 | AstNode *use_decl_node = g->use_queue.at(g->use_queue_index); | | |
| 3983 | // Get the top-level scope where `using_namespace` is used | | |
| 3984 | ScopeDecls *decls_scope = get_container_scope(use_decl_node->owner); | | |
| 3985 | if (use_decl_node->data.using_namespace.resolution == TldResolutionUnresolved) { | | |
| 3986 | preview_use_decl(g, use_decl_node, decls_scope); | | |
| 3987 | resolve_use_decl(g, use_decl_node, decls_scope); | | |
| 3988 | } | | |
| 3989 | } | | |
| 3990 | for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) { | 3999 | for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) { |
| 3991 | Tld *tld = g->resolve_queue.at(g->resolve_queue_index); | 4000 | Tld *tld = g->resolve_queue.at(g->resolve_queue_index); |
| 3992 | AstNode *source_node = nullptr; | 4001 | AstNode *source_node = nullptr; |