| ... | ... | @@ -1309,7 +1309,6 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, AstNode *node) { |
| 1309 | 1309 | assert(node->type == NodeTypePrefixOpExpr); |
| 1310 | 1310 | |
| 1311 | 1311 | PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; |
| 1312 | | //AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 1313 | 1312 | |
| 1314 | 1313 | switch (prefix_op) { |
| 1315 | 1314 | case PrefixOpInvalid: |
| ... | ... | @@ -3013,6 +3012,68 @@ static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstruct |
| 3013 | 3012 | zig_unreachable(); |
| 3014 | 3013 | } |
| 3015 | 3014 | |
| 3015 | static TypeTableEntry *ir_analyze_unary_address_of(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { |
| 3016 | IrInstruction *value = un_op_instruction->value->other; |
| 3017 | if (value->type_entry->id == TypeTableEntryIdInvalid) |
| 3018 | return ira->codegen->builtin_types.entry_invalid; |
| 3019 | |
| 3020 | bool is_const; |
| 3021 | if (un_op_instruction->op_id == IrUnOpAddressOf) { |
| 3022 | is_const = false; |
| 3023 | } else if (un_op_instruction->op_id == IrUnOpConstAddressOf) { |
| 3024 | is_const = true; |
| 3025 | } else { |
| 3026 | zig_unreachable(); |
| 3027 | } |
| 3028 | |
| 3029 | TypeTableEntry *child_type = value->type_entry; |
| 3030 | TypeTableEntry *canon_child_type = get_underlying_type(child_type); |
| 3031 | switch (canon_child_type->id) { |
| 3032 | case TypeTableEntryIdTypeDecl: |
| 3033 | zig_unreachable(); |
| 3034 | case TypeTableEntryIdInvalid: |
| 3035 | return ira->codegen->builtin_types.entry_invalid; |
| 3036 | case TypeTableEntryIdNumLitFloat: |
| 3037 | case TypeTableEntryIdNumLitInt: |
| 3038 | case TypeTableEntryIdUndefLit: |
| 3039 | case TypeTableEntryIdNullLit: |
| 3040 | case TypeTableEntryIdNamespace: |
| 3041 | case TypeTableEntryIdBlock: |
| 3042 | case TypeTableEntryIdUnreachable: |
| 3043 | case TypeTableEntryIdVar: |
| 3044 | add_node_error(ira->codegen, un_op_instruction->base.source_node, |
| 3045 | buf_sprintf("unable to get address of type '%s'", buf_ptr(&child_type->name))); |
| 3046 | // TODO if type decl, add note pointing to type decl declaration |
| 3047 | return ira->codegen->builtin_types.entry_invalid; |
| 3048 | case TypeTableEntryIdMetaType: |
| 3049 | { |
| 3050 | ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base, |
| 3051 | value->static_value.depends_on_compile_var); |
| 3052 | out_val->data.x_type = get_pointer_to_type(ira->codegen, child_type, is_const); |
| 3053 | return ira->codegen->builtin_types.entry_type; |
| 3054 | } |
| 3055 | case TypeTableEntryIdVoid: |
| 3056 | case TypeTableEntryIdBool: |
| 3057 | case TypeTableEntryIdInt: |
| 3058 | case TypeTableEntryIdFloat: |
| 3059 | case TypeTableEntryIdPointer: |
| 3060 | case TypeTableEntryIdArray: |
| 3061 | case TypeTableEntryIdStruct: |
| 3062 | case TypeTableEntryIdMaybe: |
| 3063 | case TypeTableEntryIdErrorUnion: |
| 3064 | case TypeTableEntryIdPureError: |
| 3065 | case TypeTableEntryIdEnum: |
| 3066 | case TypeTableEntryIdUnion: |
| 3067 | case TypeTableEntryIdFn: |
| 3068 | case TypeTableEntryIdGenericFn: |
| 3069 | { |
| 3070 | zig_panic("TODO address of operation"); |
| 3071 | break; |
| 3072 | } |
| 3073 | } |
| 3074 | zig_unreachable(); |
| 3075 | } |
| 3076 | |
| 3016 | 3077 | static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { |
| 3017 | 3078 | IrUnOp op_id = un_op_instruction->op_id; |
| 3018 | 3079 | switch (op_id) { |
| ... | ... | @@ -3085,37 +3146,7 @@ static TypeTableEntry *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructio |
| 3085 | 3146 | //} |
| 3086 | 3147 | case IrUnOpAddressOf: |
| 3087 | 3148 | case IrUnOpConstAddressOf: |
| 3088 | | zig_panic("TODO analyze PrefixOpAddressOf and PrefixOpConstAddressOf"); |
| 3089 | | //{ |
| 3090 | | // bool is_const = (prefix_op == PrefixOpConstAddressOf); |
| 3091 | | |
| 3092 | | // TypeTableEntry *child_type = analyze_lvalue(g, import, context, |
| 3093 | | // *expr_node, LValPurposeAddressOf, is_const); |
| 3094 | | |
| 3095 | | // if (child_type->id == TypeTableEntryIdInvalid) { |
| 3096 | | // return g->builtin_types.entry_invalid; |
| 3097 | | // } else if (child_type->id == TypeTableEntryIdMetaType) { |
| 3098 | | // TypeTableEntry *meta_type = analyze_type_expr_pointer_only(g, import, context, |
| 3099 | | // *expr_node, true); |
| 3100 | | // if (meta_type->id == TypeTableEntryIdInvalid) { |
| 3101 | | // return g->builtin_types.entry_invalid; |
| 3102 | | // } else if (meta_type->id == TypeTableEntryIdUnreachable) { |
| 3103 | | // add_node_error(g, node, buf_create_from_str("pointer to unreachable not allowed")); |
| 3104 | | // return g->builtin_types.entry_invalid; |
| 3105 | | // } else { |
| 3106 | | // return resolve_expr_const_val_as_type(g, node, |
| 3107 | | // get_pointer_to_type(g, meta_type, is_const), false); |
| 3108 | | // } |
| 3109 | | // } else if (child_type->id == TypeTableEntryIdNumLitInt || |
| 3110 | | // child_type->id == TypeTableEntryIdNumLitFloat) |
| 3111 | | // { |
| 3112 | | // add_node_error(g, *expr_node, |
| 3113 | | // buf_sprintf("unable to get address of type '%s'", buf_ptr(&child_type->name))); |
| 3114 | | // return g->builtin_types.entry_invalid; |
| 3115 | | // } else { |
| 3116 | | // return get_pointer_to_type(g, child_type, is_const); |
| 3117 | | // } |
| 3118 | | //} |
| 3149 | return ir_analyze_unary_address_of(ira, un_op_instruction); |
| 3119 | 3150 | case IrUnOpDereference: |
| 3120 | 3151 | zig_panic("TODO remove this IrUnOp item"); |
| 3121 | 3152 | case IrUnOpMaybe: |