authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-11 22:41:26-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-12 09:35:33-07:00
logaa89fd3b3e4522fe9199049a4fcc6bdc69f4bfde
treed93fec6d41037ce8c355f41a7798a2e87c984fd7
parentfa605485ea94ae9a59c8c1c0d66ee263e0bfa722

eval: ability to eval more things


7 files changed, 337 insertions(+), 114 deletions(-)

src/all_types.hpp+1-1
...@@ -65,7 +65,6 @@ struct ConstExprValue {...@@ -65,7 +65,6 @@ struct ConstExprValue {
65 bool ok; // true if constant expression evalution worked65 bool ok; // true if constant expression evalution worked
66 bool depends_on_compile_var;66 bool depends_on_compile_var;
67 bool undef;67 bool undef;
68 bool deep_const;
6968
70 union {69 union {
71 BigNum x_bignum;70 BigNum x_bignum;
...@@ -961,6 +960,7 @@ struct TypeTableEntry {...@@ -961,6 +960,7 @@ struct TypeTableEntry {
961 LLVMZigDIType *di_type;960 LLVMZigDIType *di_type;
962961
963 bool zero_bits;962 bool zero_bits;
963 bool deep_const;
964964
965 union {965 union {
966 TypeTableEntryPointer pointer;966 TypeTableEntryPointer pointer;
src/analyze.cpp+39-96
...@@ -207,6 +207,7 @@ TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {...@@ -207,6 +207,7 @@ TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
207static TypeTableEntry *get_generic_fn_type(CodeGen *g, AstNode *decl_node) {207static TypeTableEntry *get_generic_fn_type(CodeGen *g, AstNode *decl_node) {
208 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdGenericFn);208 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdGenericFn);
209 buf_init_from_str(&entry->name, "(generic function)");209 buf_init_from_str(&entry->name, "(generic function)");
210 entry->deep_const = true;
210 entry->zero_bits = true;211 entry->zero_bits = true;
211 entry->data.generic_fn.decl_node = decl_node;212 entry->data.generic_fn.decl_node = decl_node;
212 return entry;213 return entry;
...@@ -220,6 +221,8 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool...@@ -220,6 +221,8 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
220 } else {221 } else {
221 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer);222 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer);
222223
224 entry->deep_const = is_const && child_type->deep_const;
225
223 const char *const_str = is_const ? "const " : "";226 const char *const_str = is_const ? "const " : "";
224 buf_resize(&entry->name, 0);227 buf_resize(&entry->name, 0);
225 buf_appendf(&entry->name, "&%s%s", const_str, buf_ptr(&child_type->name));228 buf_appendf(&entry->name, "&%s%s", const_str, buf_ptr(&child_type->name));
...@@ -261,6 +264,8 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -261,6 +264,8 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
261 assert(child_type->type_ref);264 assert(child_type->type_ref);
262 assert(child_type->di_type);265 assert(child_type->di_type);
263266
267 entry->deep_const = child_type->deep_const;
268
264 buf_resize(&entry->name, 0);269 buf_resize(&entry->name, 0);
265 buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name));270 buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name));
266271
...@@ -344,6 +349,8 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -344,6 +349,8 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
344349
345 entry->data.error.child_type = child_type;350 entry->data.error.child_type = child_type;
346351
352 entry->deep_const = child_type->deep_const;
353
347 if (!type_has_bits(child_type)) {354 if (!type_has_bits(child_type)) {
348 entry->type_ref = g->err_tag_type->type_ref;355 entry->type_ref = g->err_tag_type->type_ref;
349 entry->di_type = g->err_tag_type->di_type;356 entry->di_type = g->err_tag_type->di_type;
...@@ -415,6 +422,7 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t...@@ -415,6 +422,7 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
415 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);422 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);
416 entry->type_ref = LLVMArrayType(child_type->type_ref, array_size);423 entry->type_ref = LLVMArrayType(child_type->type_ref, array_size);
417 entry->zero_bits = (array_size == 0) || child_type->zero_bits;424 entry->zero_bits = (array_size == 0) || child_type->zero_bits;
425 entry->deep_const = child_type->deep_const;
418426
419 buf_resize(&entry->name, 0);427 buf_resize(&entry->name, 0);
420 buf_appendf(&entry->name, "[%" PRIu64 "]%s", array_size, buf_ptr(&child_type->name));428 buf_appendf(&entry->name, "[%" PRIu64 "]%s", array_size, buf_ptr(&child_type->name));
...@@ -465,6 +473,8 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c...@@ -465,6 +473,8 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c
465 TypeTableEntry *var_peer = get_slice_type(g, child_type, false);473 TypeTableEntry *var_peer = get_slice_type(g, child_type, false);
466 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);474 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);
467475
476 entry->deep_const = child_type->deep_const;
477
468 buf_resize(&entry->name, 0);478 buf_resize(&entry->name, 0);
469 buf_appendf(&entry->name, "[]const %s", buf_ptr(&child_type->name));479 buf_appendf(&entry->name, "[]const %s", buf_ptr(&child_type->name));
470480
...@@ -550,6 +560,7 @@ TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *...@@ -550,6 +560,7 @@ TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *
550560
551 buf_init_from_str(&entry->name, name);561 buf_init_from_str(&entry->name, name);
552562
563 entry->deep_const = child_type->deep_const;
553 entry->type_ref = child_type->type_ref;564 entry->type_ref = child_type->type_ref;
554 entry->di_type = child_type->di_type;565 entry->di_type = child_type->di_type;
555 entry->zero_bits = child_type->zero_bits;566 entry->zero_bits = child_type->zero_bits;
...@@ -573,6 +584,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -573,6 +584,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
573 }584 }
574585
575 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn);586 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn);
587 fn_type->deep_const = true;
576 fn_type->data.fn.fn_type_id = *fn_type_id;588 fn_type->data.fn.fn_type_id = *fn_type_id;
577 if (fn_type_id->param_info == &fn_type_id->prealloc_param_info[0]) {589 if (fn_type_id->param_info == &fn_type_id->prealloc_param_info[0]) {
578 fn_type->data.fn.fn_type_id.param_info = &fn_type->data.fn.fn_type_id.prealloc_param_info[0];590 fn_type->data.fn.fn_type_id.param_info = &fn_type->data.fn.fn_type_id.prealloc_param_info[0];
...@@ -1038,6 +1050,8 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -1038,6 +1050,8 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
10381050
1039 assert(enum_type->di_type);1051 assert(enum_type->di_type);
10401052
1053 enum_type->deep_const = true;
1054
1041 uint32_t field_count = decl_node->data.struct_decl.fields.length;1055 uint32_t field_count = decl_node->data.struct_decl.fields.length;
10421056
1043 enum_type->data.enumeration.field_count = field_count;1057 enum_type->data.enumeration.field_count = field_count;
...@@ -1065,6 +1079,10 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -1065,6 +1079,10 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
1065 type_enum_field->type_entry = field_type;1079 type_enum_field->type_entry = field_type;
1066 type_enum_field->value = i;1080 type_enum_field->value = i;
10671081
1082 if (!field_type->deep_const) {
1083 enum_type->deep_const = false;
1084 }
1085
10681086
1069 di_enumerators[i] = LLVMZigCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);1087 di_enumerators[i] = LLVMZigCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);
10701088
...@@ -1225,6 +1243,8 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -1225,6 +1243,8 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
12251243
1226 assert(struct_type->di_type);1244 assert(struct_type->di_type);
12271245
1246 struct_type->deep_const = true;
1247
1228 int field_count = decl_node->data.struct_decl.fields.length;1248 int field_count = decl_node->data.struct_decl.fields.length;
12291249
1230 struct_type->data.structure.src_field_count = field_count;1250 struct_type->data.structure.src_field_count = field_count;
...@@ -1248,6 +1268,10 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -1248,6 +1268,10 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
1248 type_struct_field->src_index = i;1268 type_struct_field->src_index = i;
1249 type_struct_field->gen_index = -1;1269 type_struct_field->gen_index = -1;
12501270
1271 if (!field_type->deep_const) {
1272 struct_type->deep_const = false;
1273 }
1274
1251 if (field_type->id == TypeTableEntryIdStruct) {1275 if (field_type->id == TypeTableEntryIdStruct) {
1252 resolve_struct_type(g, import, field_type);1276 resolve_struct_type(g, import, field_type);
1253 } else if (field_type->id == TypeTableEntryIdEnum) {1277 } else if (field_type->id == TypeTableEntryIdEnum) {
...@@ -2486,7 +2510,6 @@ static TypeTableEntry *analyze_array_access_expr(CodeGen *g, ImportTableEntry *i...@@ -2486,7 +2510,6 @@ static TypeTableEntry *analyze_array_access_expr(CodeGen *g, ImportTableEntry *i
2486static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node) {2510static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node) {
2487 Expr *expr = get_resolved_expr(node);2511 Expr *expr = get_resolved_expr(node);
2488 expr->const_val.ok = true;2512 expr->const_val.ok = true;
2489 expr->const_val.deep_const = true;
2490 return g->builtin_types.entry_void;2513 return g->builtin_types.entry_void;
2491}2514}
24922515
...@@ -2494,7 +2517,6 @@ static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node,...@@ -2494,7 +2517,6 @@ static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node,
2494 Expr *expr = get_resolved_expr(node);2517 Expr *expr = get_resolved_expr(node);
2495 expr->const_val.ok = true;2518 expr->const_val.ok = true;
2496 expr->const_val.data.x_type = type;2519 expr->const_val.data.x_type = type;
2497 expr->const_val.deep_const = true;
2498 return g->builtin_types.entry_type;2520 return g->builtin_types.entry_type;
2499}2521}
25002522
...@@ -2509,7 +2531,6 @@ static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, F...@@ -2509,7 +2531,6 @@ static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, F
2509 Expr *expr = get_resolved_expr(node);2531 Expr *expr = get_resolved_expr(node);
2510 expr->const_val.ok = true;2532 expr->const_val.ok = true;
2511 expr->const_val.data.x_fn = fn;2533 expr->const_val.data.x_fn = fn;
2512 expr->const_val.deep_const = true;
2513 return fn->type_entry;2534 return fn->type_entry;
2514}2535}
25152536
...@@ -2519,7 +2540,6 @@ static TypeTableEntry *resolve_expr_const_val_as_generic_fn(CodeGen *g, AstNode...@@ -2519,7 +2540,6 @@ static TypeTableEntry *resolve_expr_const_val_as_generic_fn(CodeGen *g, AstNode
2519 Expr *expr = get_resolved_expr(node);2540 Expr *expr = get_resolved_expr(node);
2520 expr->const_val.ok = true;2541 expr->const_val.ok = true;
2521 expr->const_val.data.x_type = type_entry;2542 expr->const_val.data.x_type = type_entry;
2522 expr->const_val.deep_const = true;
2523 return type_entry;2543 return type_entry;
2524}2544}
25252545
...@@ -2527,7 +2547,6 @@ static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node,...@@ -2527,7 +2547,6 @@ static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node,
2527 Expr *expr = get_resolved_expr(node);2547 Expr *expr = get_resolved_expr(node);
2528 expr->const_val.ok = true;2548 expr->const_val.ok = true;
2529 expr->const_val.data.x_err.err = err;2549 expr->const_val.data.x_err.err = err;
2530 expr->const_val.deep_const = true;
2531 return g->builtin_types.entry_pure_error;2550 return g->builtin_types.entry_pure_error;
2532}2551}
25332552
...@@ -2538,7 +2557,6 @@ static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node,...@@ -2538,7 +2557,6 @@ static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node,
2538 expr->const_val.ok = true;2557 expr->const_val.ok = true;
2539 expr->const_val.depends_on_compile_var = depends_on_compile_var;2558 expr->const_val.depends_on_compile_var = depends_on_compile_var;
2540 expr->const_val.data.x_bool = value;2559 expr->const_val.data.x_bool = value;
2541 expr->const_val.deep_const = true;
2542 return g->builtin_types.entry_bool;2560 return g->builtin_types.entry_bool;
2543}2561}
25442562
...@@ -2546,7 +2564,6 @@ static TypeTableEntry *resolve_expr_const_val_as_null(CodeGen *g, AstNode *node,...@@ -2546,7 +2564,6 @@ static TypeTableEntry *resolve_expr_const_val_as_null(CodeGen *g, AstNode *node,
2546 Expr *expr = get_resolved_expr(node);2564 Expr *expr = get_resolved_expr(node);
2547 expr->const_val.ok = true;2565 expr->const_val.ok = true;
2548 expr->const_val.data.x_maybe = nullptr;2566 expr->const_val.data.x_maybe = nullptr;
2549 expr->const_val.deep_const = true;
2550 return type;2567 return type;
2551}2568}
25522569
...@@ -2557,14 +2574,12 @@ static TypeTableEntry *resolve_expr_const_val_as_non_null(CodeGen *g, AstNode *n...@@ -2557,14 +2574,12 @@ static TypeTableEntry *resolve_expr_const_val_as_non_null(CodeGen *g, AstNode *n
2557 Expr *expr = get_resolved_expr(node);2574 Expr *expr = get_resolved_expr(node);
2558 expr->const_val.ok = true;2575 expr->const_val.ok = true;
2559 expr->const_val.data.x_maybe = other_val;2576 expr->const_val.data.x_maybe = other_val;
2560 expr->const_val.deep_const = other_val->deep_const;
2561 return type;2577 return type;
2562}2578}
25632579
2564static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNode *node, Buf *str) {2580static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNode *node, Buf *str) {
2565 Expr *expr = get_resolved_expr(node);2581 Expr *expr = get_resolved_expr(node);
2566 expr->const_val.ok = true;2582 expr->const_val.ok = true;
2567 expr->const_val.deep_const = true;
25682583
2569 int len_with_null = buf_len(str) + 1;2584 int len_with_null = buf_len(str) + 1;
2570 expr->const_val.data.x_ptr.ptr = allocate<ConstExprValue*>(len_with_null);2585 expr->const_val.data.x_ptr.ptr = allocate<ConstExprValue*>(len_with_null);
...@@ -2574,14 +2589,12 @@ static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNod...@@ -2574,14 +2589,12 @@ static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNod
2574 for (int i = 0; i < buf_len(str); i += 1) {2589 for (int i = 0; i < buf_len(str); i += 1) {
2575 ConstExprValue *this_char = &all_chars[i];2590 ConstExprValue *this_char = &all_chars[i];
2576 this_char->ok = true;2591 this_char->ok = true;
2577 this_char->deep_const = true;
2578 bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]);2592 bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]);
2579 expr->const_val.data.x_ptr.ptr[i] = this_char;2593 expr->const_val.data.x_ptr.ptr[i] = this_char;
2580 }2594 }
25812595
2582 ConstExprValue *null_char = &all_chars[len_with_null - 1];2596 ConstExprValue *null_char = &all_chars[len_with_null - 1];
2583 null_char->ok = true;2597 null_char->ok = true;
2584 null_char->deep_const = true;
2585 bignum_init_unsigned(&null_char->data.x_bignum, 0);2598 bignum_init_unsigned(&null_char->data.x_bignum, 0);
2586 expr->const_val.data.x_ptr.ptr[len_with_null - 1] = null_char;2599 expr->const_val.data.x_ptr.ptr[len_with_null - 1] = null_char;
25872600
...@@ -2591,14 +2604,12 @@ static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNod...@@ -2591,14 +2604,12 @@ static TypeTableEntry *resolve_expr_const_val_as_c_string_lit(CodeGen *g, AstNod
2591static TypeTableEntry *resolve_expr_const_val_as_string_lit(CodeGen *g, AstNode *node, Buf *str) {2604static TypeTableEntry *resolve_expr_const_val_as_string_lit(CodeGen *g, AstNode *node, Buf *str) {
2592 Expr *expr = get_resolved_expr(node);2605 Expr *expr = get_resolved_expr(node);
2593 expr->const_val.ok = true;2606 expr->const_val.ok = true;
2594 expr->const_val.deep_const = true;
2595 expr->const_val.data.x_array.fields = allocate<ConstExprValue*>(buf_len(str));2607 expr->const_val.data.x_array.fields = allocate<ConstExprValue*>(buf_len(str));
25962608
2597 ConstExprValue *all_chars = allocate<ConstExprValue>(buf_len(str));2609 ConstExprValue *all_chars = allocate<ConstExprValue>(buf_len(str));
2598 for (int i = 0; i < buf_len(str); i += 1) {2610 for (int i = 0; i < buf_len(str); i += 1) {
2599 ConstExprValue *this_char = &all_chars[i];2611 ConstExprValue *this_char = &all_chars[i];
2600 this_char->ok = true;2612 this_char->ok = true;
2601 this_char->deep_const = true;
2602 bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]);2613 bignum_init_unsigned(&this_char->data.x_bignum, buf_ptr(str)[i]);
2603 expr->const_val.data.x_array.fields[i] = this_char;2614 expr->const_val.data.x_array.fields[i] = this_char;
2604 }2615 }
...@@ -2611,7 +2622,6 @@ static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, As...@@ -2611,7 +2622,6 @@ static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, As
2611{2622{
2612 Expr *expr = get_resolved_expr(node);2623 Expr *expr = get_resolved_expr(node);
2613 expr->const_val.ok = true;2624 expr->const_val.ok = true;
2614 expr->const_val.deep_const = true;
26152625
2616 bignum_init_unsigned(&expr->const_val.data.x_bignum, x);2626 bignum_init_unsigned(&expr->const_val.data.x_bignum, x);
26172627
...@@ -2623,7 +2633,6 @@ static TypeTableEntry *resolve_expr_const_val_as_float_num_lit(CodeGen *g, AstNo...@@ -2623,7 +2633,6 @@ static TypeTableEntry *resolve_expr_const_val_as_float_num_lit(CodeGen *g, AstNo
2623{2633{
2624 Expr *expr = get_resolved_expr(node);2634 Expr *expr = get_resolved_expr(node);
2625 expr->const_val.ok = true;2635 expr->const_val.ok = true;
2626 expr->const_val.deep_const = true;
26272636
2628 bignum_init_float(&expr->const_val.data.x_bignum, x);2637 bignum_init_float(&expr->const_val.data.x_bignum, x);
26292638
...@@ -2639,7 +2648,6 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode *...@@ -2639,7 +2648,6 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode *
2639 ConstExprValue *op2_val = &get_resolved_expr(op2)->const_val;2648 ConstExprValue *op2_val = &get_resolved_expr(op2)->const_val;
26402649
2641 const_val->ok = true;2650 const_val->ok = true;
2642 const_val->deep_const = true;
26432651
2644 if (bignum_fn(&const_val->data.x_bignum, &op1_val->data.x_bignum, &op2_val->data.x_bignum)) {2652 if (bignum_fn(&const_val->data.x_bignum, &op1_val->data.x_bignum, &op2_val->data.x_bignum)) {
2645 add_node_error(g, node,2653 add_node_error(g, node,
...@@ -2713,12 +2721,7 @@ static bool var_is_pure(VariableTableEntry *var, TypeTableEntry *var_type, Block...@@ -2713,12 +2721,7 @@ static bool var_is_pure(VariableTableEntry *var, TypeTableEntry *var_type, Block
2713 // variable was declared in the current function, so it's OK.2721 // variable was declared in the current function, so it's OK.
2714 return true;2722 return true;
2715 }2723 }
2716 if (!var->is_const) {2724 return var->is_const && var->type->deep_const;
2717 return false;
2718 }
2719
2720 ConstExprValue *const_val = &get_resolved_expr(var->val_node)->const_val;
2721 return const_val->deep_const;
2722}2725}
27232726
2724static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,2727static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
...@@ -3714,17 +3717,6 @@ static TypeTableEntry *analyze_if_var_expr(CodeGen *g, ImportTableEntry *import,...@@ -3714,17 +3717,6 @@ static TypeTableEntry *analyze_if_var_expr(CodeGen *g, ImportTableEntry *import,
3714 node, then_node, else_node, cond_is_const, cond_bool_val);3717 node, then_node, else_node, cond_is_const, cond_bool_val);
3715}3718}
37163719
3717static bool int_type_depends_on_compile_var(CodeGen *g, TypeTableEntry *int_type) {
3718 assert(int_type->id == TypeTableEntryIdInt);
3719
3720 for (int i = 0; i < CIntTypeCount; i += 1) {
3721 if (int_type == g->builtin_types.entry_c_int[i]) {
3722 return true;
3723 }
3724 }
3725 return false;
3726}
3727
3728static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *import, BlockContext *context,3720static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *import, BlockContext *context,
3729 AstNode *node, const char *err_format, bool is_max)3721 AstNode *node, const char *err_format, bool is_max)
3730{3722{
...@@ -3733,67 +3725,15 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor...@@ -3733,67 +3725,15 @@ static TypeTableEntry *analyze_min_max_value(CodeGen *g, ImportTableEntry *impor
37333725
3734 AstNode *type_node = node->data.fn_call_expr.params.at(0);3726 AstNode *type_node = node->data.fn_call_expr.params.at(0);
3735 TypeTableEntry *type_entry = analyze_type_expr(g, import, context, type_node);3727 TypeTableEntry *type_entry = analyze_type_expr(g, import, context, type_node);
3728
3736 if (type_entry->id == TypeTableEntryIdInvalid) {3729 if (type_entry->id == TypeTableEntryIdInvalid) {
3737 return g->builtin_types.entry_invalid;3730 return g->builtin_types.entry_invalid;
3738 } else if (type_entry->id == TypeTableEntryIdInt) {3731 } else if (type_entry->id == TypeTableEntryIdInt ||
3739 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;3732 type_entry->id == TypeTableEntryIdFloat ||
3740 const_val->ok = true;3733 type_entry->id == TypeTableEntryIdBool)
3741 const_val->depends_on_compile_var = int_type_depends_on_compile_var(g, type_entry);3734 {
3742 if (is_max) {3735 eval_min_max_value(g, type_entry, &get_resolved_expr(node)->const_val, is_max);
3743 if (type_entry->data.integral.is_signed) {
3744 int64_t val;
3745 if (type_entry->data.integral.bit_count == 64) {
3746 val = INT64_MAX;
3747 } else if (type_entry->data.integral.bit_count == 32) {
3748 val = INT32_MAX;
3749 } else if (type_entry->data.integral.bit_count == 16) {
3750 val = INT16_MAX;
3751 } else if (type_entry->data.integral.bit_count == 8) {
3752 val = INT8_MAX;
3753 } else {
3754 zig_unreachable();
3755 }
3756 bignum_init_signed(&const_val->data.x_bignum, val);
3757 } else {
3758 uint64_t val;
3759 if (type_entry->data.integral.bit_count == 64) {
3760 val = UINT64_MAX;
3761 } else if (type_entry->data.integral.bit_count == 32) {
3762 val = UINT32_MAX;
3763 } else if (type_entry->data.integral.bit_count == 16) {
3764 val = UINT16_MAX;
3765 } else if (type_entry->data.integral.bit_count == 8) {
3766 val = UINT8_MAX;
3767 } else {
3768 zig_unreachable();
3769 }
3770 bignum_init_unsigned(&const_val->data.x_bignum, val);
3771 }
3772 } else {
3773 if (type_entry->data.integral.is_signed) {
3774 int64_t val;
3775 if (type_entry->data.integral.bit_count == 64) {
3776 val = INT64_MIN;
3777 } else if (type_entry->data.integral.bit_count == 32) {
3778 val = INT32_MIN;
3779 } else if (type_entry->data.integral.bit_count == 16) {
3780 val = INT16_MIN;
3781 } else if (type_entry->data.integral.bit_count == 8) {
3782 val = INT8_MIN;
3783 } else {
3784 zig_unreachable();
3785 }
3786 bignum_init_signed(&const_val->data.x_bignum, val);
3787 } else {
3788 bignum_init_unsigned(&const_val->data.x_bignum, 0);
3789 }
3790 }
3791 return type_entry;
3792 } else if (type_entry->id == TypeTableEntryIdFloat) {
3793 zig_panic("TODO analyze_min_max_value float");
3794 return type_entry;3736 return type_entry;
3795 } else if (type_entry->id == TypeTableEntryIdBool) {
3796 return resolve_expr_const_val_as_bool(g, node, is_max, false);
3797 } else {3737 } else {
3798 add_node_error(g, node,3738 add_node_error(g, node,
3799 buf_sprintf(err_format, buf_ptr(&type_entry->name)));3739 buf_sprintf(err_format, buf_ptr(&type_entry->name)));
...@@ -3810,7 +3750,8 @@ static TypeTableEntry *resolve_cast(CodeGen *g, BlockContext *context, AstNode *...@@ -3810,7 +3750,8 @@ static TypeTableEntry *resolve_cast(CodeGen *g, BlockContext *context, AstNode *
3810 TypeTableEntry *other_type = get_resolved_expr(expr_node)->type_entry;3750 TypeTableEntry *other_type = get_resolved_expr(expr_node)->type_entry;
3811 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;3751 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
3812 if (other_val->ok) {3752 if (other_val->ok) {
3813 eval_const_expr_implicit_cast(node->data.fn_call_expr.cast_op, other_val, other_type, const_val);3753 eval_const_expr_implicit_cast(node->data.fn_call_expr.cast_op, other_val, other_type,
3754 const_val, wanted_type);
3814 }3755 }
38153756
3816 if (need_alloca) {3757 if (need_alloca) {
...@@ -4238,8 +4179,6 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -4238,8 +4179,6 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
4238 }4179 }
4239 case BuiltinFnIdMemcpy:4180 case BuiltinFnIdMemcpy:
4240 {4181 {
4241 mark_impure_fn(context);
4242
4243 AstNode *dest_node = node->data.fn_call_expr.params.at(0);4182 AstNode *dest_node = node->data.fn_call_expr.params.at(0);
4244 AstNode *src_node = node->data.fn_call_expr.params.at(1);4183 AstNode *src_node = node->data.fn_call_expr.params.at(1);
4245 AstNode *len_node = node->data.fn_call_expr.params.at(2);4184 AstNode *len_node = node->data.fn_call_expr.params.at(2);
...@@ -4278,8 +4217,6 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -4278,8 +4217,6 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
4278 }4217 }
4279 case BuiltinFnIdMemset:4218 case BuiltinFnIdMemset:
4280 {4219 {
4281 mark_impure_fn(context);
4282
4283 AstNode *dest_node = node->data.fn_call_expr.params.at(0);4220 AstNode *dest_node = node->data.fn_call_expr.params.at(0);
4284 AstNode *char_node = node->data.fn_call_expr.params.at(1);4221 AstNode *char_node = node->data.fn_call_expr.params.at(1);
4285 AstNode *len_node = node->data.fn_call_expr.params.at(2);4222 AstNode *len_node = node->data.fn_call_expr.params.at(2);
...@@ -4601,6 +4538,8 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import,...@@ -4601,6 +4538,8 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import,
4601 // calling an impure fn is impure4538 // calling an impure fn is impure
4602 mark_impure_fn(context);4539 mark_impure_fn(context);
4603 }4540 }
4541 } else {
4542 mark_impure_fn(context);
4604 }4543 }
46054544
4606 if (handle_is_ptr(return_type)) {4545 if (handle_is_ptr(return_type)) {
...@@ -5602,6 +5541,10 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -5602,6 +5541,10 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
5602 param_decl_node->data.param_decl.variable = var;5541 param_decl_node->data.param_decl.variable = var;
56035542
5604 var->gen_arg_index = fn_type->data.fn.gen_param_info[i].gen_index;5543 var->gen_arg_index = fn_type->data.fn.gen_param_info[i].gen_index;
5544
5545 if (!type->deep_const) {
5546 fn_table_entry->is_pure = false;
5547 }
5605 }5548 }
56065549
5607 TypeTableEntry *expected_type = fn_type->data.fn.fn_type_id.return_type;5550 TypeTableEntry *expected_type = fn_type->data.fn.fn_type_id.return_type;
src/bignum.cpp+5
...@@ -71,6 +71,11 @@ bool bignum_fits_in_bits(BigNum *bn, int bit_count, bool is_signed) {...@@ -71,6 +71,11 @@ bool bignum_fits_in_bits(BigNum *bn, int bit_count, bool is_signed) {
71 }71 }
72}72}
7373
74void bignum_truncate(BigNum *bn, int bit_count) {
75 assert(bn->kind == BigNumKindInt);
76 bn->data.x_uint &= (1LL << bit_count) - 1;
77}
78
74uint64_t bignum_to_twos_complement(BigNum *bn) {79uint64_t bignum_to_twos_complement(BigNum *bn) {
75 assert(bn->kind == BigNumKindInt);80 assert(bn->kind == BigNumKindInt);
7681
src/bignum.hpp+2
...@@ -47,6 +47,8 @@ void bignum_negate(BigNum *dest, BigNum *op);...@@ -47,6 +47,8 @@ void bignum_negate(BigNum *dest, BigNum *op);
47void bignum_cast_to_float(BigNum *dest, BigNum *op);47void bignum_cast_to_float(BigNum *dest, BigNum *op);
48void bignum_cast_to_int(BigNum *dest, BigNum *op);48void bignum_cast_to_int(BigNum *dest, BigNum *op);
4949
50void bignum_truncate(BigNum *dest, int bit_count);
51
50// returns the result of the comparison52// returns the result of the comparison
51bool bignum_cmp_eq(BigNum *op1, BigNum *op2);53bool bignum_cmp_eq(BigNum *op1, BigNum *op2);
52bool bignum_cmp_neq(BigNum *op1, BigNum *op2);54bool bignum_cmp_neq(BigNum *op1, BigNum *op2);
src/codegen.cpp+19
...@@ -3463,23 +3463,27 @@ static void define_builtin_types(CodeGen *g) {...@@ -3463,23 +3463,27 @@ static void define_builtin_types(CodeGen *g) {
3463 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNamespace);3463 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNamespace);
3464 buf_init_from_str(&entry->name, "(namespace)");3464 buf_init_from_str(&entry->name, "(namespace)");
3465 entry->zero_bits = true;3465 entry->zero_bits = true;
3466 entry->deep_const = true;
3466 g->builtin_types.entry_namespace = entry;3467 g->builtin_types.entry_namespace = entry;
3467 }3468 }
3468 {3469 {
3469 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);3470 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);
3470 buf_init_from_str(&entry->name, "(float literal)");3471 buf_init_from_str(&entry->name, "(float literal)");
3471 entry->zero_bits = true;3472 entry->zero_bits = true;
3473 entry->deep_const = true;
3472 g->builtin_types.entry_num_lit_float = entry;3474 g->builtin_types.entry_num_lit_float = entry;
3473 }3475 }
3474 {3476 {
3475 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitInt);3477 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitInt);
3476 buf_init_from_str(&entry->name, "(integer literal)");3478 buf_init_from_str(&entry->name, "(integer literal)");
3477 entry->zero_bits = true;3479 entry->zero_bits = true;
3480 entry->deep_const = true;
3478 g->builtin_types.entry_num_lit_int = entry;3481 g->builtin_types.entry_num_lit_int = entry;
3479 }3482 }
3480 {3483 {
3481 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUndefLit);3484 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUndefLit);
3482 buf_init_from_str(&entry->name, "(undefined)");3485 buf_init_from_str(&entry->name, "(undefined)");
3486 entry->deep_const = true;
3483 g->builtin_types.entry_undef = entry;3487 g->builtin_types.entry_undef = entry;
3484 }3488 }
34853489
...@@ -3489,6 +3493,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3489,6 +3493,7 @@ static void define_builtin_types(CodeGen *g) {
3489 for (;;) {3493 for (;;) {
3490 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);3494 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3491 entry->type_ref = LLVMIntType(size_in_bits);3495 entry->type_ref = LLVMIntType(size_in_bits);
3496 entry->deep_const = true;
34923497
3493 const char u_or_i = is_signed ? 'i' : 'u';3498 const char u_or_i = is_signed ? 'i' : 'u';
3494 buf_resize(&entry->name, 0);3499 buf_resize(&entry->name, 0);
...@@ -3534,6 +3539,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3534,6 +3539,7 @@ static void define_builtin_types(CodeGen *g) {
35343539
3535 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);3540 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3536 entry->type_ref = LLVMIntType(size_in_bits);3541 entry->type_ref = LLVMIntType(size_in_bits);
3542 entry->deep_const = true;
35373543
3538 buf_init_from_str(&entry->name, info->name);3544 buf_init_from_str(&entry->name, info->name);
35393545
...@@ -3553,6 +3559,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3553,6 +3559,7 @@ static void define_builtin_types(CodeGen *g) {
3553 {3559 {
3554 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBool);3560 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBool);
3555 entry->type_ref = LLVMInt1Type();3561 entry->type_ref = LLVMInt1Type();
3562 entry->deep_const = true;
3556 buf_init_from_str(&entry->name, "bool");3563 buf_init_from_str(&entry->name, "bool");
3557 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);3564 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
3558 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);3565 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
...@@ -3565,6 +3572,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3565,6 +3572,7 @@ static void define_builtin_types(CodeGen *g) {
3565 }3572 }
3566 {3573 {
3567 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);3574 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3575 entry->deep_const = true;
3568 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);3576 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
3569 buf_init_from_str(&entry->name, "isize");3577 buf_init_from_str(&entry->name, "isize");
3570 entry->data.integral.is_signed = true;3578 entry->data.integral.is_signed = true;
...@@ -3581,6 +3589,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3581,6 +3589,7 @@ static void define_builtin_types(CodeGen *g) {
3581 }3589 }
3582 {3590 {
3583 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);3591 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3592 entry->deep_const = true;
3584 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);3593 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
3585 buf_init_from_str(&entry->name, "usize");3594 buf_init_from_str(&entry->name, "usize");
3586 entry->data.integral.is_signed = false;3595 entry->data.integral.is_signed = false;
...@@ -3597,6 +3606,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3597,6 +3606,7 @@ static void define_builtin_types(CodeGen *g) {
3597 }3606 }
3598 {3607 {
3599 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);3608 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
3609 entry->deep_const = true;
3600 entry->type_ref = LLVMFloatType();3610 entry->type_ref = LLVMFloatType();
3601 buf_init_from_str(&entry->name, "f32");3611 buf_init_from_str(&entry->name, "f32");
3602 entry->data.floating.bit_count = 32;3612 entry->data.floating.bit_count = 32;
...@@ -3612,6 +3622,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3612,6 +3622,7 @@ static void define_builtin_types(CodeGen *g) {
3612 }3622 }
3613 {3623 {
3614 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);3624 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
3625 entry->deep_const = true;
3615 entry->type_ref = LLVMDoubleType();3626 entry->type_ref = LLVMDoubleType();
3616 buf_init_from_str(&entry->name, "f64");3627 buf_init_from_str(&entry->name, "f64");
3617 entry->data.floating.bit_count = 64;3628 entry->data.floating.bit_count = 64;
...@@ -3627,6 +3638,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3627,6 +3638,7 @@ static void define_builtin_types(CodeGen *g) {
3627 }3638 }
3628 {3639 {
3629 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);3640 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
3641 entry->deep_const = true;
3630 entry->type_ref = LLVMX86FP80Type();3642 entry->type_ref = LLVMX86FP80Type();
3631 buf_init_from_str(&entry->name, "c_long_double");3643 buf_init_from_str(&entry->name, "c_long_double");
3632 entry->data.floating.bit_count = 80;3644 entry->data.floating.bit_count = 80;
...@@ -3642,6 +3654,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3642,6 +3654,7 @@ static void define_builtin_types(CodeGen *g) {
3642 }3654 }
3643 {3655 {
3644 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);3656 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
3657 entry->deep_const = true;
3645 entry->type_ref = LLVMVoidType();3658 entry->type_ref = LLVMVoidType();
3646 entry->zero_bits = true;3659 entry->zero_bits = true;
3647 buf_init_from_str(&entry->name, "void");3660 buf_init_from_str(&entry->name, "void");
...@@ -3654,6 +3667,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3654,6 +3667,7 @@ static void define_builtin_types(CodeGen *g) {
3654 }3667 }
3655 {3668 {
3656 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable);3669 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable);
3670 entry->deep_const = true;
3657 entry->type_ref = LLVMVoidType();3671 entry->type_ref = LLVMVoidType();
3658 entry->zero_bits = true;3672 entry->zero_bits = true;
3659 buf_init_from_str(&entry->name, "unreachable");3673 buf_init_from_str(&entry->name, "unreachable");
...@@ -3663,6 +3677,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3663,6 +3677,7 @@ static void define_builtin_types(CodeGen *g) {
3663 }3677 }
3664 {3678 {
3665 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType);3679 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType);
3680 entry->deep_const = true;
3666 buf_init_from_str(&entry->name, "type");3681 buf_init_from_str(&entry->name, "type");
3667 entry->zero_bits = true;3682 entry->zero_bits = true;
3668 g->builtin_types.entry_type = entry;3683 g->builtin_types.entry_type = entry;
...@@ -3685,6 +3700,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3685,6 +3700,7 @@ static void define_builtin_types(CodeGen *g) {
36853700
3686 {3701 {
3687 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPureError);3702 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPureError);
3703 entry->deep_const = true;
3688 buf_init_from_str(&entry->name, "error");3704 buf_init_from_str(&entry->name, "error");
36893705
3690 // TODO allow overriding this type and keep track of max value and emit an3706 // TODO allow overriding this type and keep track of max value and emit an
...@@ -3700,6 +3716,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3700,6 +3716,7 @@ static void define_builtin_types(CodeGen *g) {
37003716
3701 {3717 {
3702 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);3718 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
3719 entry->deep_const = true;
3703 entry->zero_bits = true; // only allowed at compile time3720 entry->zero_bits = true; // only allowed at compile time
3704 buf_init_from_str(&entry->name, "@OS");3721 buf_init_from_str(&entry->name, "@OS");
3705 uint32_t field_count = target_os_count();3722 uint32_t field_count = target_os_count();
...@@ -3725,6 +3742,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3725,6 +3742,7 @@ static void define_builtin_types(CodeGen *g) {
37253742
3726 {3743 {
3727 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);3744 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
3745 entry->deep_const = true;
3728 entry->zero_bits = true; // only allowed at compile time3746 entry->zero_bits = true; // only allowed at compile time
3729 buf_init_from_str(&entry->name, "@Arch");3747 buf_init_from_str(&entry->name, "@Arch");
3730 uint32_t field_count = target_arch_count();3748 uint32_t field_count = target_arch_count();
...@@ -3756,6 +3774,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3756,6 +3774,7 @@ static void define_builtin_types(CodeGen *g) {
37563774
3757 {3775 {
3758 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);3776 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
3777 entry->deep_const = true;
3759 entry->zero_bits = true; // only allowed at compile time3778 entry->zero_bits = true; // only allowed at compile time
3760 buf_init_from_str(&entry->name, "@Environ");3779 buf_init_from_str(&entry->name, "@Environ");
3761 uint32_t field_count = target_environ_count();3780 uint32_t field_count = target_environ_count();
src/eval.cpp+268-16
...@@ -360,7 +360,7 @@ static bool eval_if_bool_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val...@@ -360,7 +360,7 @@ static bool eval_if_bool_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val
360360
361void eval_const_expr_implicit_cast(CastOp cast_op,361void eval_const_expr_implicit_cast(CastOp cast_op,
362 ConstExprValue *other_val, TypeTableEntry *other_type,362 ConstExprValue *other_val, TypeTableEntry *other_type,
363 ConstExprValue *const_val)363 ConstExprValue *const_val, TypeTableEntry *new_type)
364{364{
365 const_val->depends_on_compile_var = other_val->depends_on_compile_var;365 const_val->depends_on_compile_var = other_val->depends_on_compile_var;
366 const_val->undef = other_val->undef;366 const_val->undef = other_val->undef;
...@@ -371,9 +371,30 @@ void eval_const_expr_implicit_cast(CastOp cast_op,...@@ -371,9 +371,30 @@ void eval_const_expr_implicit_cast(CastOp cast_op,
371 zig_unreachable();371 zig_unreachable();
372 case CastOpNoop:372 case CastOpNoop:
373 case CastOpWidenOrShorten:373 case CastOpWidenOrShorten:
374 case CastOpPointerReinterpret:
375 *const_val = *other_val;374 *const_val = *other_val;
376 break;375 break;
376 case CastOpPointerReinterpret:
377 {
378 TypeTableEntry *other_child_type = other_type->data.pointer.child_type;
379 TypeTableEntry *new_child_type = new_type->data.pointer.child_type;
380
381 if ((other_child_type->id == TypeTableEntryIdInt ||
382 other_child_type->id == TypeTableEntryIdFloat) &&
383 (new_child_type->id == TypeTableEntryIdInt ||
384 new_child_type->id == TypeTableEntryIdFloat))
385 {
386 ConstExprValue **ptr_val = allocate<ConstExprValue*>(1);
387 *ptr_val = other_val->data.x_ptr.ptr[0];
388 const_val->data.x_ptr.ptr = ptr_val;
389 const_val->data.x_ptr.len = 1;
390 const_val->ok = true;
391 const_val->undef = other_val->undef;
392 const_val->depends_on_compile_var = other_val->depends_on_compile_var;
393 } else {
394 zig_panic("TODO");
395 }
396 break;
397 }
377 case CastOpPtrToInt:398 case CastOpPtrToInt:
378 case CastOpIntToPtr:399 case CastOpIntToPtr:
379 // can't do it400 // can't do it
...@@ -435,20 +456,184 @@ void eval_const_expr_implicit_cast(CastOp cast_op,...@@ -435,20 +456,184 @@ void eval_const_expr_implicit_cast(CastOp cast_op,
435 }456 }
436}457}
437458
459static bool int_type_depends_on_compile_var(CodeGen *g, TypeTableEntry *int_type) {
460 assert(int_type->id == TypeTableEntryIdInt);
461
462 for (int i = 0; i < CIntTypeCount; i += 1) {
463 if (int_type == g->builtin_types.entry_c_int[i]) {
464 return true;
465 }
466 }
467 return false;
468}
469
470void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val, bool is_max) {
471 if (type_entry->id == TypeTableEntryIdInt) {
472 const_val->ok = true;
473 const_val->depends_on_compile_var = int_type_depends_on_compile_var(g, type_entry);
474 if (is_max) {
475 if (type_entry->data.integral.is_signed) {
476 int64_t val;
477 if (type_entry->data.integral.bit_count == 64) {
478 val = INT64_MAX;
479 } else if (type_entry->data.integral.bit_count == 32) {
480 val = INT32_MAX;
481 } else if (type_entry->data.integral.bit_count == 16) {
482 val = INT16_MAX;
483 } else if (type_entry->data.integral.bit_count == 8) {
484 val = INT8_MAX;
485 } else {
486 zig_unreachable();
487 }
488 bignum_init_signed(&const_val->data.x_bignum, val);
489 } else {
490 uint64_t val;
491 if (type_entry->data.integral.bit_count == 64) {
492 val = UINT64_MAX;
493 } else if (type_entry->data.integral.bit_count == 32) {
494 val = UINT32_MAX;
495 } else if (type_entry->data.integral.bit_count == 16) {
496 val = UINT16_MAX;
497 } else if (type_entry->data.integral.bit_count == 8) {
498 val = UINT8_MAX;
499 } else {
500 zig_unreachable();
501 }
502 bignum_init_unsigned(&const_val->data.x_bignum, val);
503 }
504 } else {
505 if (type_entry->data.integral.is_signed) {
506 int64_t val;
507 if (type_entry->data.integral.bit_count == 64) {
508 val = INT64_MIN;
509 } else if (type_entry->data.integral.bit_count == 32) {
510 val = INT32_MIN;
511 } else if (type_entry->data.integral.bit_count == 16) {
512 val = INT16_MIN;
513 } else if (type_entry->data.integral.bit_count == 8) {
514 val = INT8_MIN;
515 } else {
516 zig_unreachable();
517 }
518 bignum_init_signed(&const_val->data.x_bignum, val);
519 } else {
520 bignum_init_unsigned(&const_val->data.x_bignum, 0);
521 }
522 }
523 } else if (type_entry->id == TypeTableEntryIdFloat) {
524 zig_panic("TODO analyze_min_max_value float");
525 } else if (type_entry->id == TypeTableEntryIdBool) {
526 const_val->ok = true;
527 const_val->data.x_bool = is_max;
528 } else {
529 zig_unreachable();
530 }
531}
532
533static bool eval_min_max(EvalFn *ef, AstNode *node, ConstExprValue *out_val, bool is_max) {
534 assert(node->type == NodeTypeFnCallExpr);
535 AstNode *type_node = node->data.fn_call_expr.params.at(0);
536 TypeTableEntry *type_entry = resolve_expr_type(type_node);
537 eval_min_max_value(ef->root->codegen, type_entry, out_val, is_max);
538 return false;
539}
540
541static bool eval_fn_with_overflow(EvalFn *ef, AstNode *node, ConstExprValue *out_val,
542 bool (*bignum_fn)(BigNum *dest, BigNum *op1, BigNum *op2))
543{
544 assert(node->type == NodeTypeFnCallExpr);
545
546 AstNode *type_node = node->data.fn_call_expr.params.at(0);
547 TypeTableEntry *int_type = resolve_expr_type(type_node);
548 assert(int_type->id == TypeTableEntryIdInt);
549
550 AstNode *op1_node = node->data.fn_call_expr.params.at(1);
551 AstNode *op2_node = node->data.fn_call_expr.params.at(2);
552 AstNode *result_node = node->data.fn_call_expr.params.at(3);
553
554 ConstExprValue op1_val = {0};
555 if (eval_expr(ef, op1_node, &op1_val)) return true;
556
557 ConstExprValue op2_val = {0};
558 if (eval_expr(ef, op2_node, &op2_val)) return true;
559
560 ConstExprValue result_ptr_val = {0};
561 if (eval_expr(ef, result_node, &result_ptr_val)) return true;
562
563 ConstExprValue *result_val = result_ptr_val.data.x_ptr.ptr[0];
564
565 out_val->ok = true;
566 bool overflow = bignum_fn(&result_val->data.x_bignum, &op1_val.data.x_bignum, &op2_val.data.x_bignum);
567
568 overflow = overflow || !bignum_fits_in_bits(&result_val->data.x_bignum,
569 int_type->data.integral.bit_count, int_type->data.integral.is_signed);
570
571 out_val->data.x_bool = overflow;
572
573 if (overflow) {
574 bignum_truncate(&result_val->data.x_bignum, int_type->data.integral.bit_count);
575 }
576
577 return false;
578}
579
580static bool eval_fn_call_builtin(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
581 assert(node->type == NodeTypeFnCallExpr);
582
583 BuiltinFnEntry *builtin_fn = node->data.fn_call_expr.builtin_fn;
584 switch (builtin_fn->id) {
585 case BuiltinFnIdMaxValue:
586 return eval_min_max(ef, node, out_val, true);
587 case BuiltinFnIdMinValue:
588 return eval_min_max(ef, node, out_val, false);
589 case BuiltinFnIdMulWithOverflow:
590 return eval_fn_with_overflow(ef, node, out_val, bignum_mul);
591 case BuiltinFnIdAddWithOverflow:
592 return eval_fn_with_overflow(ef, node, out_val, bignum_add);
593 case BuiltinFnIdSubWithOverflow:
594 return eval_fn_with_overflow(ef, node, out_val, bignum_sub);
595 case BuiltinFnIdMemcpy:
596 case BuiltinFnIdMemset:
597 case BuiltinFnIdSizeof:
598 case BuiltinFnIdAlignof:
599 case BuiltinFnIdMemberCount:
600 case BuiltinFnIdTypeof:
601 case BuiltinFnIdCInclude:
602 case BuiltinFnIdCDefine:
603 case BuiltinFnIdCUndef:
604 case BuiltinFnIdCompileVar:
605 case BuiltinFnIdConstEval:
606 case BuiltinFnIdCtz:
607 case BuiltinFnIdClz:
608 case BuiltinFnIdImport:
609 case BuiltinFnIdCImport:
610 case BuiltinFnIdErrName:
611 zig_panic("TODO");
612 case BuiltinFnIdBreakpoint:
613 case BuiltinFnIdInvalid:
614 zig_unreachable();
615 }
616
617 return false;
618}
619
438static bool eval_fn_call_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {620static bool eval_fn_call_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
439 assert(node->type == NodeTypeFnCallExpr);621 assert(node->type == NodeTypeFnCallExpr);
440622
623 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
441 CastOp cast_op = node->data.fn_call_expr.cast_op;624 CastOp cast_op = node->data.fn_call_expr.cast_op;
442 if (node->data.fn_call_expr.is_builtin) {625 if (node->data.fn_call_expr.is_builtin) {
443 zig_panic("TODO");626 return eval_fn_call_builtin(ef, node, out_val);
444 } else if (cast_op != CastOpNoCast) {627 } else if (cast_op != CastOpNoCast) {
445 AstNode *expr_node = node->data.fn_call_expr.params.at(0);628 TypeTableEntry *new_type = resolve_expr_type(fn_ref_expr);
446 Expr *expr = get_resolved_expr(expr_node);629 AstNode *param_node = node->data.fn_call_expr.params.at(0);
447 eval_const_expr_implicit_cast(cast_op, &expr->const_val, expr->type_entry, out_val);630 TypeTableEntry *old_type = get_resolved_expr(param_node)->type_entry;
631 ConstExprValue param_val = {0};
632 if (eval_expr(ef, param_node, &param_val)) return true;
633 eval_const_expr_implicit_cast(cast_op, &param_val, old_type, out_val, new_type);
448 return false;634 return false;
449 }635 }
450636
451 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
452 if (node->data.fn_call_expr.enum_type) {637 if (node->data.fn_call_expr.enum_type) {
453 zig_panic("TODO");638 zig_panic("TODO");
454 }639 }
...@@ -503,7 +688,12 @@ static bool eval_field_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou...@@ -503,7 +688,12 @@ static bool eval_field_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou
503 zig_panic("TODO");688 zig_panic("TODO");
504 }689 }
505 } else if (struct_type->id == TypeTableEntryIdMetaType) {690 } else if (struct_type->id == TypeTableEntryIdMetaType) {
506 zig_panic("TODO");691 TypeTableEntry *child_type = resolve_expr_type(struct_expr);
692 if (child_type->id == TypeTableEntryIdPureError) {
693 *out_val = get_resolved_expr(node)->const_val;
694 } else {
695 zig_panic("TODO");
696 }
507 } else if (struct_type->id == TypeTableEntryIdNamespace) {697 } else if (struct_type->id == TypeTableEntryIdNamespace) {
508 zig_panic("TODO");698 zig_panic("TODO");
509 } else {699 } else {
...@@ -630,7 +820,6 @@ static bool eval_bool_literal_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou...@@ -630,7 +820,6 @@ static bool eval_bool_literal_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou
630 assert(node->type == NodeTypeBoolLiteral);820 assert(node->type == NodeTypeBoolLiteral);
631821
632 out_val->ok = true;822 out_val->ok = true;
633 out_val->deep_const = true;
634 out_val->data.x_bool = node->data.bool_literal.value;823 out_val->data.x_bool = node->data.bool_literal.value;
635824
636 return false;825 return false;
...@@ -640,20 +829,38 @@ static bool eval_prefix_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_v...@@ -640,20 +829,38 @@ static bool eval_prefix_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_v
640 assert(node->type == NodeTypePrefixOpExpr);829 assert(node->type == NodeTypePrefixOpExpr);
641830
642 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op;831 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op;
832 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
643833
644 ConstExprValue expr_val = {0};834 ConstExprValue expr_val = {0};
645 if (eval_expr(ef, node->data.prefix_op_expr.primary_expr, &expr_val)) return true;835 if (eval_expr(ef, expr_node, &expr_val)) return true;
836
837 TypeTableEntry *expr_type = get_resolved_expr(expr_node)->type_entry;
646838
647 switch (prefix_op) {839 switch (prefix_op) {
648 case PrefixOpBoolNot:840 case PrefixOpBoolNot:
649 *out_val = expr_val;841 *out_val = expr_val;
650 out_val->data.x_bool = !out_val->data.x_bool;842 out_val->data.x_bool = !out_val->data.x_bool;
651 break;843 break;
652 case PrefixOpBinNot:844 case PrefixOpDereference:
653 case PrefixOpNegation:845 assert(expr_type->id == TypeTableEntryIdPointer);
846 *out_val = *expr_val.data.x_ptr.ptr[0];
847 break;
654 case PrefixOpAddressOf:848 case PrefixOpAddressOf:
655 case PrefixOpConstAddressOf:849 case PrefixOpConstAddressOf:
656 case PrefixOpDereference:850 {
851 ConstExprValue *child_val = allocate<ConstExprValue>(1);
852 *child_val = expr_val;
853
854 ConstExprValue **ptr_val = allocate<ConstExprValue*>(1);
855 *ptr_val = child_val;
856
857 out_val->data.x_ptr.ptr = ptr_val;
858 out_val->data.x_ptr.len = 1;
859 out_val->ok = true;
860 break;
861 }
862 case PrefixOpBinNot:
863 case PrefixOpNegation:
657 case PrefixOpMaybe:864 case PrefixOpMaybe:
658 case PrefixOpError:865 case PrefixOpError:
659 case PrefixOpUnwrapError:866 case PrefixOpUnwrapError:
...@@ -666,6 +873,48 @@ static bool eval_prefix_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_v...@@ -666,6 +873,48 @@ static bool eval_prefix_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_v
666 return false;873 return false;
667}874}
668875
876static bool eval_var_decl_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
877 assert(node->type == NodeTypeVariableDeclaration);
878
879 assert(node->data.variable_declaration.expr);
880
881 EvalScope *my_scope = ef->scope_stack.at(ef->scope_stack.length - 1);
882
883 my_scope->vars.add_one();
884 EvalVar *var = &my_scope->vars.last();
885 var->name = &node->data.variable_declaration.symbol;
886
887 if (eval_expr(ef, node->data.variable_declaration.expr, &var->value)) return true;
888
889 out_val->ok = true;
890
891 return false;
892}
893
894static bool eval_number_literal_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
895 assert(node->type == NodeTypeNumberLiteral);
896 assert(!node->data.number_literal.overflow);
897
898 out_val->ok = true;
899 if (node->data.number_literal.kind == NumLitUInt) {
900 bignum_init_unsigned(&out_val->data.x_bignum, node->data.number_literal.data.x_uint);
901 } else if (node->data.number_literal.kind == NumLitFloat) {
902 bignum_init_float(&out_val->data.x_bignum, node->data.number_literal.data.x_float);
903 } else {
904 zig_unreachable();
905 }
906
907 return false;
908}
909
910static bool eval_char_literal_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
911 assert(node->type == NodeTypeCharLiteral);
912
913 out_val->ok = true;
914 bignum_init_unsigned(&out_val->data.x_bignum, node->data.char_literal.value);
915
916 return false;
917}
669918
670static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {919static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {
671 if (ef->root->branches_used > ef->root->branch_quota) {920 if (ef->root->branches_used > ef->root->branch_quota) {
...@@ -697,6 +946,12 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {...@@ -697,6 +946,12 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {
697 return eval_bool_literal_expr(ef, node, out);946 return eval_bool_literal_expr(ef, node, out);
698 case NodeTypePrefixOpExpr:947 case NodeTypePrefixOpExpr:
699 return eval_prefix_op_expr(ef, node, out);948 return eval_prefix_op_expr(ef, node, out);
949 case NodeTypeVariableDeclaration:
950 return eval_var_decl_expr(ef, node, out);
951 case NodeTypeNumberLiteral:
952 return eval_number_literal_expr(ef, node, out);
953 case NodeTypeCharLiteral:
954 return eval_char_literal_expr(ef, node, out);
700 case NodeTypeRoot:955 case NodeTypeRoot:
701 case NodeTypeFnProto:956 case NodeTypeFnProto:
702 case NodeTypeFnDef:957 case NodeTypeFnDef:
...@@ -704,13 +959,10 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {...@@ -704,13 +959,10 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {
704 case NodeTypeParamDecl:959 case NodeTypeParamDecl:
705 case NodeTypeDirective:960 case NodeTypeDirective:
706 case NodeTypeDefer:961 case NodeTypeDefer:
707 case NodeTypeVariableDeclaration:
708 case NodeTypeTypeDecl:962 case NodeTypeTypeDecl:
709 case NodeTypeErrorValueDecl:963 case NodeTypeErrorValueDecl:
710 case NodeTypeUnwrapErrorExpr:964 case NodeTypeUnwrapErrorExpr:
711 case NodeTypeNumberLiteral:
712 case NodeTypeStringLiteral:965 case NodeTypeStringLiteral:
713 case NodeTypeCharLiteral:
714 case NodeTypeSliceExpr:966 case NodeTypeSliceExpr:
715 case NodeTypeUse:967 case NodeTypeUse:
716 case NodeTypeNullLiteral:968 case NodeTypeNullLiteral:
src/eval.hpp+3-1
...@@ -19,6 +19,8 @@ void eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type,...@@ -19,6 +19,8 @@ void eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type,
1919
20void eval_const_expr_implicit_cast(CastOp cast_op,20void eval_const_expr_implicit_cast(CastOp cast_op,
21 ConstExprValue *other_val, TypeTableEntry *other_type,21 ConstExprValue *other_val, TypeTableEntry *other_type,
22 ConstExprValue *const_val);22 ConstExprValue *const_val, TypeTableEntry *new_type);
23
24void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val, bool is_max);
2325
24#endif26#endif