| ... | @@ -2842,20 +2842,231 @@ void normalize_parent_ptrs(AstNode *node) { | ... | @@ -2842,20 +2842,231 @@ void normalize_parent_ptrs(AstNode *node) { |
| 2842 | ast_visit_node_children(node, normalize_parent_ptrs_visit, nullptr); | 2842 | ast_visit_node_children(node, normalize_parent_ptrs_visit, nullptr); |
| 2843 | } | 2843 | } |
| 2844 | | 2844 | |
| 2845 | static AstNode *clone_node(AstNode *old_node) { | 2845 | static void clone_subtree_list(ZigList<AstNode *> *dest, ZigList<AstNode *> *src, uint32_t *next_node_index) { |
| 2846 | AstNode *new_node = allocate_nonzero<AstNode>(1); | 2846 | memset(dest, 0, sizeof(ZigList<AstNode *>)); |
| 2847 | memcpy(new_node, old_node, sizeof(AstNode)); | 2847 | dest->resize(src->length); |
| 2848 | return new_node; | 2848 | for (int i = 0; i < src->length; i += 1) { |
| | 2849 | dest->at(i) = ast_clone_subtree(src->at(i), next_node_index); |
| | 2850 | } |
| 2849 | } | 2851 | } |
| 2850 | | 2852 | |
| 2851 | static void ast_clone_subtree_visit(AstNode **node, void *context) { | 2853 | static void clone_subtree_list_ptr(ZigList<AstNode *> **dest_ptr, ZigList<AstNode *> *src, |
| 2852 | *node = clone_node(*node); | 2854 | uint32_t *next_node_index) |
| 2853 | (*node)->parent_field = node; | 2855 | { |
| 2854 | ast_visit_node_children(*node, ast_clone_subtree_visit, nullptr); | 2856 | if (src) { |
| | 2857 | ZigList<AstNode *> *dest = allocate<ZigList<AstNode *>>(1); |
| | 2858 | *dest_ptr = dest; |
| | 2859 | clone_subtree_list(dest, src, next_node_index); |
| | 2860 | } |
| | 2861 | } |
| | 2862 | |
| | 2863 | static void clone_subtree_field(AstNode **dest, AstNode *src, uint32_t *next_node_index) { |
| | 2864 | *dest = ast_clone_subtree(src, next_node_index); |
| | 2865 | (*dest)->parent_field = dest; |
| | 2866 | } |
| | 2867 | |
| | 2868 | static void clone_subtree_tld(TopLevelDecl *dest, TopLevelDecl *src, uint32_t *next_node_index) { |
| | 2869 | clone_subtree_list_ptr(&dest->directives, src->directives, next_node_index); |
| 2855 | } | 2870 | } |
| 2856 | | 2871 | |
| 2857 | AstNode *ast_clone_subtree(AstNode *old_node) { | 2872 | AstNode *ast_clone_subtree(AstNode *old_node, uint32_t *next_node_index) { |
| 2858 | AstNode *new_node = clone_node(old_node); | 2873 | AstNode *new_node = allocate_nonzero<AstNode>(1); |
| 2859 | ast_visit_node_children(new_node, ast_clone_subtree_visit, nullptr); | 2874 | memcpy(new_node, old_node, sizeof(AstNode)); |
| | 2875 | new_node->create_index = *next_node_index; |
| | 2876 | *next_node_index += 1; |
| | 2877 | |
| | 2878 | switch (new_node->type) { |
| | 2879 | case NodeTypeRoot: |
| | 2880 | clone_subtree_list(&new_node->data.root.top_level_decls, &old_node->data.root.top_level_decls, |
| | 2881 | next_node_index); |
| | 2882 | break; |
| | 2883 | case NodeTypeFnProto: |
| | 2884 | clone_subtree_tld(&new_node->data.fn_proto.top_level_decl, &old_node->data.fn_proto.top_level_decl, |
| | 2885 | next_node_index); |
| | 2886 | clone_subtree_field(&new_node->data.fn_proto.return_type, old_node->data.fn_proto.return_type, |
| | 2887 | next_node_index); |
| | 2888 | clone_subtree_list(&new_node->data.fn_proto.generic_params, |
| | 2889 | &old_node->data.fn_proto.generic_params, next_node_index); |
| | 2890 | clone_subtree_list(&new_node->data.fn_proto.params, &old_node->data.fn_proto.params, |
| | 2891 | next_node_index); |
| | 2892 | |
| | 2893 | break; |
| | 2894 | case NodeTypeFnDef: |
| | 2895 | clone_subtree_field(&new_node->data.fn_def.fn_proto, old_node->data.fn_def.fn_proto, next_node_index); |
| | 2896 | new_node->data.fn_def.fn_proto->data.fn_proto.fn_def_node = new_node; |
| | 2897 | clone_subtree_field(&new_node->data.fn_def.body, old_node->data.fn_def.body, next_node_index); |
| | 2898 | break; |
| | 2899 | case NodeTypeFnDecl: |
| | 2900 | clone_subtree_field(&new_node->data.fn_decl.fn_proto, old_node->data.fn_decl.fn_proto, |
| | 2901 | next_node_index); |
| | 2902 | break; |
| | 2903 | case NodeTypeParamDecl: |
| | 2904 | clone_subtree_field(&new_node->data.param_decl.type, old_node->data.param_decl.type, next_node_index); |
| | 2905 | break; |
| | 2906 | case NodeTypeBlock: |
| | 2907 | clone_subtree_list(&new_node->data.block.statements, &old_node->data.block.statements, |
| | 2908 | next_node_index); |
| | 2909 | break; |
| | 2910 | case NodeTypeDirective: |
| | 2911 | clone_subtree_field(&new_node->data.directive.expr, old_node->data.directive.expr, next_node_index); |
| | 2912 | break; |
| | 2913 | case NodeTypeReturnExpr: |
| | 2914 | clone_subtree_field(&new_node->data.return_expr.expr, old_node->data.return_expr.expr, next_node_index); |
| | 2915 | break; |
| | 2916 | case NodeTypeDefer: |
| | 2917 | clone_subtree_field(&new_node->data.defer.expr, old_node->data.defer.expr, next_node_index); |
| | 2918 | break; |
| | 2919 | case NodeTypeVariableDeclaration: |
| | 2920 | clone_subtree_list_ptr(&new_node->data.variable_declaration.top_level_decl.directives, |
| | 2921 | old_node->data.variable_declaration.top_level_decl.directives, next_node_index); |
| | 2922 | clone_subtree_field(&new_node->data.variable_declaration.type, old_node->data.variable_declaration.type, next_node_index); |
| | 2923 | clone_subtree_field(&new_node->data.variable_declaration.expr, old_node->data.variable_declaration.expr, next_node_index); |
| | 2924 | break; |
| | 2925 | case NodeTypeTypeDecl: |
| | 2926 | clone_subtree_list_ptr(&new_node->data.type_decl.top_level_decl.directives, |
| | 2927 | old_node->data.type_decl.top_level_decl.directives, next_node_index); |
| | 2928 | clone_subtree_field(&new_node->data.type_decl.child_type, old_node->data.type_decl.child_type, next_node_index); |
| | 2929 | break; |
| | 2930 | case NodeTypeErrorValueDecl: |
| | 2931 | // none |
| | 2932 | break; |
| | 2933 | case NodeTypeBinOpExpr: |
| | 2934 | clone_subtree_field(&new_node->data.bin_op_expr.op1, old_node->data.bin_op_expr.op1, next_node_index); |
| | 2935 | clone_subtree_field(&new_node->data.bin_op_expr.op2, old_node->data.bin_op_expr.op2, next_node_index); |
| | 2936 | break; |
| | 2937 | case NodeTypeUnwrapErrorExpr: |
| | 2938 | clone_subtree_field(&new_node->data.unwrap_err_expr.op1, old_node->data.unwrap_err_expr.op1, next_node_index); |
| | 2939 | clone_subtree_field(&new_node->data.unwrap_err_expr.symbol, old_node->data.unwrap_err_expr.symbol, next_node_index); |
| | 2940 | clone_subtree_field(&new_node->data.unwrap_err_expr.op2, old_node->data.unwrap_err_expr.op2, next_node_index); |
| | 2941 | break; |
| | 2942 | case NodeTypeNumberLiteral: |
| | 2943 | // none |
| | 2944 | break; |
| | 2945 | case NodeTypeStringLiteral: |
| | 2946 | // none |
| | 2947 | break; |
| | 2948 | case NodeTypeCharLiteral: |
| | 2949 | // none |
| | 2950 | break; |
| | 2951 | case NodeTypeSymbol: |
| | 2952 | // none |
| | 2953 | break; |
| | 2954 | case NodeTypePrefixOpExpr: |
| | 2955 | clone_subtree_field(&new_node->data.prefix_op_expr.primary_expr, old_node->data.prefix_op_expr.primary_expr, next_node_index); |
| | 2956 | break; |
| | 2957 | case NodeTypeFnCallExpr: |
| | 2958 | clone_subtree_field(&new_node->data.fn_call_expr.fn_ref_expr, old_node->data.fn_call_expr.fn_ref_expr, next_node_index); |
| | 2959 | clone_subtree_list(&new_node->data.fn_call_expr.params, &old_node->data.fn_call_expr.params, next_node_index); |
| | 2960 | break; |
| | 2961 | case NodeTypeArrayAccessExpr: |
| | 2962 | clone_subtree_field(&new_node->data.array_access_expr.array_ref_expr, old_node->data.array_access_expr.array_ref_expr, next_node_index); |
| | 2963 | clone_subtree_field(&new_node->data.array_access_expr.subscript, old_node->data.array_access_expr.subscript, next_node_index); |
| | 2964 | break; |
| | 2965 | case NodeTypeSliceExpr: |
| | 2966 | clone_subtree_field(&new_node->data.slice_expr.array_ref_expr, old_node->data.slice_expr.array_ref_expr, next_node_index); |
| | 2967 | clone_subtree_field(&new_node->data.slice_expr.start, old_node->data.slice_expr.start, next_node_index); |
| | 2968 | clone_subtree_field(&new_node->data.slice_expr.end, old_node->data.slice_expr.end, next_node_index); |
| | 2969 | break; |
| | 2970 | case NodeTypeFieldAccessExpr: |
| | 2971 | clone_subtree_field(&new_node->data.field_access_expr.struct_expr, old_node->data.field_access_expr.struct_expr, next_node_index); |
| | 2972 | break; |
| | 2973 | case NodeTypeUse: |
| | 2974 | clone_subtree_field(&new_node->data.use.expr, old_node->data.use.expr, next_node_index); |
| | 2975 | clone_subtree_list_ptr(&new_node->data.use.top_level_decl.directives, |
| | 2976 | old_node->data.use.top_level_decl.directives, next_node_index); |
| | 2977 | break; |
| | 2978 | case NodeTypeBoolLiteral: |
| | 2979 | // none |
| | 2980 | break; |
| | 2981 | case NodeTypeNullLiteral: |
| | 2982 | // none |
| | 2983 | break; |
| | 2984 | case NodeTypeUndefinedLiteral: |
| | 2985 | // none |
| | 2986 | break; |
| | 2987 | case NodeTypeIfBoolExpr: |
| | 2988 | clone_subtree_field(&new_node->data.if_bool_expr.condition, old_node->data.if_bool_expr.condition, next_node_index); |
| | 2989 | clone_subtree_field(&new_node->data.if_bool_expr.then_block, old_node->data.if_bool_expr.then_block, next_node_index); |
| | 2990 | clone_subtree_field(&new_node->data.if_bool_expr.else_node, old_node->data.if_bool_expr.else_node, next_node_index); |
| | 2991 | break; |
| | 2992 | case NodeTypeIfVarExpr: |
| | 2993 | clone_subtree_field(&new_node->data.if_var_expr.var_decl.type, old_node->data.if_var_expr.var_decl.type, next_node_index); |
| | 2994 | clone_subtree_field(&new_node->data.if_var_expr.var_decl.expr, old_node->data.if_var_expr.var_decl.expr, next_node_index); |
| | 2995 | clone_subtree_field(&new_node->data.if_var_expr.then_block, old_node->data.if_var_expr.then_block, next_node_index); |
| | 2996 | clone_subtree_field(&new_node->data.if_var_expr.else_node, old_node->data.if_var_expr.else_node, next_node_index); |
| | 2997 | break; |
| | 2998 | case NodeTypeWhileExpr: |
| | 2999 | clone_subtree_field(&new_node->data.while_expr.condition, old_node->data.while_expr.condition, next_node_index); |
| | 3000 | clone_subtree_field(&new_node->data.while_expr.body, old_node->data.while_expr.body, next_node_index); |
| | 3001 | break; |
| | 3002 | case NodeTypeForExpr: |
| | 3003 | clone_subtree_field(&new_node->data.for_expr.elem_node, old_node->data.for_expr.elem_node, next_node_index); |
| | 3004 | clone_subtree_field(&new_node->data.for_expr.array_expr, old_node->data.for_expr.array_expr, next_node_index); |
| | 3005 | clone_subtree_field(&new_node->data.for_expr.index_node, old_node->data.for_expr.index_node, next_node_index); |
| | 3006 | clone_subtree_field(&new_node->data.for_expr.body, old_node->data.for_expr.body, next_node_index); |
| | 3007 | break; |
| | 3008 | case NodeTypeSwitchExpr: |
| | 3009 | clone_subtree_field(&new_node->data.switch_expr.expr, old_node->data.switch_expr.expr, next_node_index); |
| | 3010 | clone_subtree_list(&new_node->data.switch_expr.prongs, &old_node->data.switch_expr.prongs, |
| | 3011 | next_node_index); |
| | 3012 | break; |
| | 3013 | case NodeTypeSwitchProng: |
| | 3014 | clone_subtree_list(&new_node->data.switch_prong.items, &old_node->data.switch_prong.items, |
| | 3015 | next_node_index); |
| | 3016 | clone_subtree_field(&new_node->data.switch_prong.var_symbol, old_node->data.switch_prong.var_symbol, next_node_index); |
| | 3017 | clone_subtree_field(&new_node->data.switch_prong.expr, old_node->data.switch_prong.expr, next_node_index); |
| | 3018 | break; |
| | 3019 | case NodeTypeSwitchRange: |
| | 3020 | clone_subtree_field(&new_node->data.switch_range.start, old_node->data.switch_range.start, next_node_index); |
| | 3021 | clone_subtree_field(&new_node->data.switch_range.end, old_node->data.switch_range.end, next_node_index); |
| | 3022 | break; |
| | 3023 | case NodeTypeLabel: |
| | 3024 | // none |
| | 3025 | break; |
| | 3026 | case NodeTypeGoto: |
| | 3027 | // none |
| | 3028 | break; |
| | 3029 | case NodeTypeBreak: |
| | 3030 | // none |
| | 3031 | break; |
| | 3032 | case NodeTypeContinue: |
| | 3033 | // none |
| | 3034 | break; |
| | 3035 | case NodeTypeAsmExpr: |
| | 3036 | zig_panic("TODO"); |
| | 3037 | break; |
| | 3038 | case NodeTypeStructDecl: |
| | 3039 | clone_subtree_list(&new_node->data.struct_decl.fields, &old_node->data.struct_decl.fields, |
| | 3040 | next_node_index); |
| | 3041 | clone_subtree_list(&new_node->data.struct_decl.fns, &old_node->data.struct_decl.fns, |
| | 3042 | next_node_index); |
| | 3043 | clone_subtree_list_ptr(&new_node->data.struct_decl.top_level_decl.directives, |
| | 3044 | old_node->data.struct_decl.top_level_decl.directives, next_node_index); |
| | 3045 | break; |
| | 3046 | case NodeTypeStructField: |
| | 3047 | clone_subtree_field(&new_node->data.struct_field.type, old_node->data.struct_field.type, next_node_index); |
| | 3048 | clone_subtree_list_ptr(&new_node->data.struct_field.top_level_decl.directives, |
| | 3049 | old_node->data.struct_field.top_level_decl.directives, next_node_index); |
| | 3050 | break; |
| | 3051 | case NodeTypeContainerInitExpr: |
| | 3052 | clone_subtree_field(&new_node->data.container_init_expr.type, old_node->data.container_init_expr.type, next_node_index); |
| | 3053 | clone_subtree_list(&new_node->data.container_init_expr.entries, |
| | 3054 | &old_node->data.container_init_expr.entries, next_node_index); |
| | 3055 | break; |
| | 3056 | case NodeTypeStructValueField: |
| | 3057 | clone_subtree_field(&new_node->data.struct_val_field.expr, old_node->data.struct_val_field.expr, next_node_index); |
| | 3058 | break; |
| | 3059 | case NodeTypeArrayType: |
| | 3060 | clone_subtree_field(&new_node->data.array_type.size, old_node->data.array_type.size, next_node_index); |
| | 3061 | clone_subtree_field(&new_node->data.array_type.child_type, old_node->data.array_type.child_type, next_node_index); |
| | 3062 | break; |
| | 3063 | case NodeTypeErrorType: |
| | 3064 | // none |
| | 3065 | break; |
| | 3066 | case NodeTypeTypeLiteral: |
| | 3067 | // none |
| | 3068 | break; |
| | 3069 | } |
| | 3070 | |
| 2860 | return new_node; | 3071 | return new_node; |
| 2861 | } | 3072 | } |