| ... | @@ -35,7 +35,9 @@ static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, F | ... | @@ -35,7 +35,9 @@ static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, F |
| 35 | static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type, | 35 | static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node, TypeTableEntry *type, |
| 36 | bool depends_on_compile_var); | 36 | bool depends_on_compile_var); |
| 37 | static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, AstNode *node, | 37 | static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, AstNode *node, |
| 38 | TypeTableEntry *expected_type, uint64_t x); | 38 | TypeTableEntry *expected_type, uint64_t x, bool depends_on_compile_var); |
| | 39 | static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node, bool value, |
| | 40 | bool depends_on_compile_var); |
| 39 | static AstNode *find_decl(BlockContext *context, Buf *name); | 41 | static AstNode *find_decl(BlockContext *context, Buf *name); |
| 40 | static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNode *decl_node, | 42 | static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNode *decl_node, |
| 41 | bool pointer_only, BlockContext *block_context, bool depends_on_compile_var); | 43 | bool pointer_only, BlockContext *block_context, bool depends_on_compile_var); |
| ... | @@ -2562,7 +2564,9 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -2562,7 +2564,9 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 2562 | | 2564 | |
| 2563 | bool wrapped_in_fn_call = node->data.field_access_expr.is_fn_call; | 2565 | bool wrapped_in_fn_call = node->data.field_access_expr.is_fn_call; |
| 2564 | | 2566 | |
| 2565 | if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer && | 2567 | if (struct_type->id == TypeTableEntryIdInvalid) { |
| | 2568 | return struct_type; |
| | 2569 | } else if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer && |
| 2566 | struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct)) | 2570 | struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct)) |
| 2567 | { | 2571 | { |
| 2568 | TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ? | 2572 | TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ? |
| ... | @@ -2603,7 +2607,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -2603,7 +2607,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 2603 | } else if (struct_type->id == TypeTableEntryIdArray) { | 2607 | } else if (struct_type->id == TypeTableEntryIdArray) { |
| 2604 | if (buf_eql_str(field_name, "len")) { | 2608 | if (buf_eql_str(field_name, "len")) { |
| 2605 | return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, | 2609 | return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, |
| 2606 | struct_type->data.array.len); | 2610 | struct_type->data.array.len, false); |
| 2607 | } else { | 2611 | } else { |
| 2608 | add_node_error(g, node, | 2612 | add_node_error(g, node, |
| 2609 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), | 2613 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), |
| ... | @@ -2653,6 +2657,24 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -2653,6 +2657,24 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 2653 | } | 2657 | } |
| 2654 | } else if (child_type->id == TypeTableEntryIdPureError) { | 2658 | } else if (child_type->id == TypeTableEntryIdPureError) { |
| 2655 | return analyze_error_literal_expr(g, import, context, node, field_name); | 2659 | return analyze_error_literal_expr(g, import, context, node, field_name); |
| | 2660 | } else if (child_type->id == TypeTableEntryIdInt) { |
| | 2661 | bool depends_on_compile_var = |
| | 2662 | get_resolved_expr(*struct_expr_node)->const_val.depends_on_compile_var; |
| | 2663 | if (buf_eql_str(field_name, "bit_count")) { |
| | 2664 | return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, |
| | 2665 | child_type->data.integral.bit_count, depends_on_compile_var); |
| | 2666 | } else if (buf_eql_str(field_name, "is_signed")) { |
| | 2667 | return resolve_expr_const_val_as_bool(g, node, child_type->data.integral.is_signed, |
| | 2668 | depends_on_compile_var); |
| | 2669 | } else if (buf_eql_str(field_name, "is_wrapping")) { |
| | 2670 | return resolve_expr_const_val_as_bool(g, node, child_type->data.integral.is_wrapping, |
| | 2671 | depends_on_compile_var); |
| | 2672 | } else { |
| | 2673 | add_node_error(g, node, |
| | 2674 | buf_sprintf("type '%s' has no member called '%s'", |
| | 2675 | buf_ptr(&child_type->name), buf_ptr(field_name))); |
| | 2676 | return g->builtin_types.entry_invalid; |
| | 2677 | } |
| 2656 | } else if (wrapped_in_fn_call) { // this branch should go last, before the error in the else case | 2678 | } else if (wrapped_in_fn_call) { // this branch should go last, before the error in the else case |
| 2657 | return resolve_expr_const_val_as_type(g, node, child_type, false); | 2679 | return resolve_expr_const_val_as_type(g, node, child_type, false); |
| 2658 | } else { | 2680 | } else { |
| ... | @@ -2682,10 +2704,8 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -2682,10 +2704,8 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 2682 | return g->builtin_types.entry_invalid; | 2704 | return g->builtin_types.entry_invalid; |
| 2683 | } | 2705 | } |
| 2684 | } else { | 2706 | } else { |
| 2685 | if (struct_type->id != TypeTableEntryIdInvalid) { | 2707 | add_node_error(g, node, |
| 2686 | add_node_error(g, node, | 2708 | buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name))); |
| 2687 | buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name))); | | |
| 2688 | } | | |
| 2689 | return g->builtin_types.entry_invalid; | 2709 | return g->builtin_types.entry_invalid; |
| 2690 | } | 2710 | } |
| 2691 | } | 2711 | } |
| ... | @@ -2891,10 +2911,11 @@ static TypeTableEntry *resolve_expr_const_val_as_string_lit(CodeGen *g, AstNode | ... | @@ -2891,10 +2911,11 @@ static TypeTableEntry *resolve_expr_const_val_as_string_lit(CodeGen *g, AstNode |
| 2891 | | 2911 | |
| 2892 | | 2912 | |
| 2893 | static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, AstNode *node, | 2913 | static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, AstNode *node, |
| 2894 | TypeTableEntry *expected_type, uint64_t x) | 2914 | TypeTableEntry *expected_type, uint64_t x, bool depends_on_compile_var) |
| 2895 | { | 2915 | { |
| 2896 | Expr *expr = get_resolved_expr(node); | 2916 | Expr *expr = get_resolved_expr(node); |
| 2897 | expr->const_val.ok = true; | 2917 | expr->const_val.ok = true; |
| | 2918 | expr->const_val.depends_on_compile_var = depends_on_compile_var; |
| 2898 | | 2919 | |
| 2899 | bignum_init_unsigned(&expr->const_val.data.x_bignum, x); | 2920 | bignum_init_unsigned(&expr->const_val.data.x_bignum, x); |
| 2900 | | 2921 | |
| ... | @@ -3797,7 +3818,7 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry | ... | @@ -3797,7 +3818,7 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry |
| 3797 | | 3818 | |
| 3798 | if (node->data.number_literal.kind == NumLitUInt) { | 3819 | if (node->data.number_literal.kind == NumLitUInt) { |
| 3799 | return resolve_expr_const_val_as_unsigned_num_lit(g, node, | 3820 | return resolve_expr_const_val_as_unsigned_num_lit(g, node, |
| 3800 | expected_type, node->data.number_literal.data.x_uint); | 3821 | expected_type, node->data.number_literal.data.x_uint, false); |
| 3801 | } else if (node->data.number_literal.kind == NumLitFloat) { | 3822 | } else if (node->data.number_literal.kind == NumLitFloat) { |
| 3802 | return resolve_expr_const_val_as_float_num_lit(g, node, | 3823 | return resolve_expr_const_val_as_float_num_lit(g, node, |
| 3803 | expected_type, node->data.number_literal.data.x_float); | 3824 | expected_type, node->data.number_literal.data.x_float); |
| ... | @@ -4964,7 +4985,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry | ... | @@ -4964,7 +4985,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 4964 | return g->builtin_types.entry_invalid; | 4985 | return g->builtin_types.entry_invalid; |
| 4965 | } else { | 4986 | } else { |
| 4966 | uint64_t size_in_bytes = type_size(g, type_entry); | 4987 | uint64_t size_in_bytes = type_size(g, type_entry); |
| 4967 | return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, size_in_bytes); | 4988 | return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, |
| | 4989 | size_in_bytes, false); |
| 4968 | } | 4990 | } |
| 4969 | } | 4991 | } |
| 4970 | case BuiltinFnIdAlignof: | 4992 | case BuiltinFnIdAlignof: |
| ... | @@ -4979,7 +5001,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry | ... | @@ -4979,7 +5001,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 4979 | return g->builtin_types.entry_invalid; | 5001 | return g->builtin_types.entry_invalid; |
| 4980 | } else { | 5002 | } else { |
| 4981 | uint64_t align_in_bytes = LLVMABISizeOfType(g->target_data_ref, type_entry->type_ref); | 5003 | uint64_t align_in_bytes = LLVMABISizeOfType(g->target_data_ref, type_entry->type_ref); |
| 4982 | return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, align_in_bytes); | 5004 | return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, |
| | 5005 | align_in_bytes, false); |
| 4983 | } | 5006 | } |
| 4984 | } | 5007 | } |
| 4985 | case BuiltinFnIdMaxValue: | 5008 | case BuiltinFnIdMaxValue: |
| ... | @@ -4997,7 +5020,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry | ... | @@ -4997,7 +5020,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 4997 | return type_entry; | 5020 | return type_entry; |
| 4998 | } else if (type_entry->id == TypeTableEntryIdEnum) { | 5021 | } else if (type_entry->id == TypeTableEntryIdEnum) { |
| 4999 | uint64_t value_count = type_entry->data.enumeration.field_count; | 5022 | uint64_t value_count = type_entry->data.enumeration.field_count; |
| 5000 | return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, value_count); | 5023 | return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, |
| | 5024 | value_count, false); |
| 5001 | } else { | 5025 | } else { |
| 5002 | add_node_error(g, node, | 5026 | add_node_error(g, node, |
| 5003 | buf_sprintf("no value count available for type '%s'", buf_ptr(&type_entry->name))); | 5027 | buf_sprintf("no value count available for type '%s'", buf_ptr(&type_entry->name))); |
| ... | @@ -6188,7 +6212,7 @@ static TypeTableEntry *analyze_expression_pointer_only(CodeGen *g, ImportTableEn | ... | @@ -6188,7 +6212,7 @@ static TypeTableEntry *analyze_expression_pointer_only(CodeGen *g, ImportTableEn |
| 6188 | break; | 6212 | break; |
| 6189 | case NodeTypeCharLiteral: | 6213 | case NodeTypeCharLiteral: |
| 6190 | return_type = resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, | 6214 | return_type = resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, |
| 6191 | node->data.char_literal.value); | 6215 | node->data.char_literal.value, false); |
| 6192 | break; | 6216 | break; |
| 6193 | case NodeTypeBoolLiteral: | 6217 | case NodeTypeBoolLiteral: |
| 6194 | return_type = resolve_expr_const_val_as_bool(g, node, node->data.bool_literal.value, false); | 6218 | return_type = resolve_expr_const_val_as_bool(g, node, node->data.bool_literal.value, false); |