diff --git a/src/compiler/ast.c b/src/compiler/ast.c index 9dcbd07e9..0302d8560 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -436,6 +436,39 @@ Expr *expr_new(ExprKind kind, SourceSpan start) return expr; } +Expr *expr_new_const_int(SourceSpan span, Type *type, uint64_t v, bool narrowable) +{ + Expr *expr = expr_calloc(); + expr->expr_kind = EXPR_CONST; + expr->span = span; + expr->type = type; + TypeKind kind = type_flatten(type)->type_kind; + expr->const_expr.ixx.i.high = 0; + if (type_kind_is_signed(kind)) + { + if (v > (uint64_t)INT64_MAX) expr->const_expr.ixx.i.high = UINT64_MAX; + } + expr->const_expr.ixx.i.low = v; + expr->const_expr.ixx.type = kind; + expr->const_expr.const_kind = CONST_INTEGER; + expr->const_expr.narrowable = narrowable; + expr->resolve_status = RESOLVE_DONE; + return expr; +} + +Expr *expr_new_const_bool(SourceSpan span, Type *type, bool value) +{ + Expr *expr = expr_calloc(); + expr->expr_kind = EXPR_CONST; + expr->span = span; + expr->type = type; + assert(type_flatten(type)->type_kind == TYPE_BOOL); + expr->const_expr.b = value; + expr->const_expr.const_kind = CONST_BOOL; + expr->resolve_status = RESOLVE_DONE; + return expr; +} + BinaryOp binary_op[TOKEN_LAST + 1] = { [TOKEN_STAR] = BINARYOP_MULT, diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 91765bce6..6f0119ea6 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -522,17 +522,12 @@ static void setup_int_define(const char *id, uint64_t i, Type *type) { TokenType token_type = TOKEN_CONST_IDENT; id = symtab_add(id, (uint32_t) strlen(id), fnv1a(id, (uint32_t) strlen(id)), &token_type); - Expr *expr = expr_new(EXPR_CONST, INVALID_SPAN); assert(type_is_integer(type)); - expr_const_set_int(&expr->const_expr, i, type->type_kind); + Expr *expr = expr_new_const_int(INVALID_SPAN, type, i, true); if (expr_const_will_overflow(&expr->const_expr, type->type_kind)) { error_exit("Integer define %s overflow.", id); } - expr->type = type; - expr->const_expr.narrowable = true; - expr->span = INVALID_SPAN; - expr->resolve_status = RESOLVE_NOT_DONE; void *previous = htable_set(&global_context.compiler_defines, id, expr); if (previous) { @@ -544,11 +539,7 @@ static void setup_bool_define(const char *id, bool value) { TokenType token_type = TOKEN_CONST_IDENT; id = symtab_add(id, (uint32_t) strlen(id), fnv1a(id, (uint32_t) strlen(id)), &token_type); - Expr *expr = expr_new(EXPR_CONST, INVALID_SPAN); - expr_const_set_bool(&expr->const_expr, value); - expr->type = type_bool; - expr->span = INVALID_SPAN; - expr->resolve_status = RESOLVE_NOT_DONE; + Expr *expr = expr_new_const_bool(INVALID_SPAN, type_bool, value); void *previous = htable_set(&global_context.compiler_defines, id, expr); if (previous) { diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 5e5e876b0..fed00a9f2 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -1925,6 +1925,8 @@ static inline DeclKind decl_from_token(TokenType type); #define EXPR_NEW_TOKEN(kind_) expr_new(kind_, c->span) Expr *expr_new(ExprKind kind, SourceSpan start); +Expr *expr_new_const_int(SourceSpan span, Type *type, uint64_t v, bool narrowable); +Expr *expr_new_const_bool(SourceSpan span, Type *type, bool value); bool expr_is_simple(Expr *expr); bool expr_is_pure(Expr *expr); bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind); @@ -1945,10 +1947,11 @@ INLINE bool exprid_is_constant_eval(ExprId expr, ConstantEvalKind eval_kind); INLINE bool expr_is_init_list(Expr *expr); INLINE bool expr_is_deref(Expr *expr); -void expr_const_set_int(ExprConst *expr, uint64_t v, TypeKind kind); -void expr_const_set_float(ExprConst *expr, Real d, TypeKind kind); -void expr_const_set_bool(ExprConst *expr, bool b); -void expr_const_set_null(ExprConst *expr); +INLINE void expr_rewrite_const_null(Expr *expr, Type *type); +INLINE void expr_rewrite_const_bool(Expr *expr, Type *type, bool b); +INLINE void expr_rewrite_const_float(Expr *expr, Type *type, Real d); +INLINE void expr_rewrite_const_int(Expr *expr, Type *type, uint64_t v, bool narrowable); +INLINE void expr_rewrite_const_list(Expr *expr, Type *type, ConstInitializer *list); bool expr_const_in_range(const ExprConst *left, const ExprConst *right, const ExprConst *right_to); bool expr_const_compare(const ExprConst *left, const ExprConst *right, BinaryOp op); @@ -2695,3 +2698,65 @@ INLINE const char *decl_get_extname(Decl *decl) { return decl->extname; } + + +INLINE void expr_rewrite_const_bool(Expr *expr, Type *type, bool b) +{ + expr->expr_kind = EXPR_CONST; + expr->type = type; + expr->const_expr = (ExprConst) { .b = b, .const_kind = CONST_BOOL }; + expr->resolve_status = RESOLVE_DONE; +} + +INLINE void expr_rewrite_const_null(Expr *expr, Type *type) +{ + expr->expr_kind = EXPR_CONST; + expr->type = type; + expr->const_expr = (ExprConst) { .ptr = 0, .const_kind = CONST_POINTER }; + expr->resolve_status = RESOLVE_DONE; +} + +INLINE void expr_rewrite_const_list(Expr *expr, Type *type, ConstInitializer *list) +{ + expr->expr_kind = EXPR_CONST; + expr->type = type; + expr->const_expr = (ExprConst) { .list = list, .const_kind = CONST_LIST }; + expr->resolve_status = RESOLVE_DONE; +} + +INLINE void expr_rewrite_const_int(Expr *expr, Type *type, uint64_t v, bool narrowable) +{ + expr->expr_kind = EXPR_CONST; + expr->type = type; + TypeKind kind = type_flatten(type)->type_kind; + (&expr->const_expr)->ixx.i.high = 0; + if (type_kind_is_signed(kind)) + { + if (v > (uint64_t)INT64_MAX) (&expr->const_expr)->ixx.i.high = UINT64_MAX; + } + (&expr->const_expr)->ixx.i.low = v; + (&expr->const_expr)->ixx.type = kind; + (&expr->const_expr)->const_kind = CONST_INTEGER; + expr->const_expr.narrowable = narrowable; +} + +INLINE void expr_rewrite_const_float(Expr *expr, Type *type, Real d) +{ + expr->expr_kind = EXPR_CONST; + expr->type = type; + TypeKind kind = type_flatten(type)->type_kind; + switch (kind) + { + case TYPE_F32: + expr->const_expr.fxx = (Float){ (float)d, TYPE_F32 }; + break; + case TYPE_F64: + expr->const_expr.fxx = (Float){ (double)d, TYPE_F64 }; + break; + default: + expr->const_expr.fxx = (Float){ d, kind }; + break; + } + expr->const_expr.const_kind = CONST_FLOAT; + expr->resolve_status = RESOLVE_DONE; +} diff --git a/src/compiler/number.c b/src/compiler/number.c index cc001a077..6e9732726 100644 --- a/src/compiler/number.c +++ b/src/compiler/number.c @@ -8,29 +8,6 @@ #define FLOAT64_LIMIT 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0000000000000000 #define FLOAT16_LIMIT 65504 -void expr_const_set_int(ExprConst *expr, uint64_t v, TypeKind kind) -{ - expr->ixx.i.high = 0; - if (type_kind_is_signed(kind)) - { - if (v > (uint64_t)INT64_MAX) expr->ixx.i.high = UINT64_MAX; - } - expr->ixx.i.low = v; - expr->ixx.type = kind; - expr->const_kind = CONST_INTEGER; -} - -void expr_const_set_bool(ExprConst *expr, bool b) -{ - expr->b = b; - expr->const_kind = CONST_BOOL; -} - -void expr_const_set_null(ExprConst *expr) -{ - expr->ptr = 0; - expr->const_kind = CONST_POINTER; -} static inline bool compare_bool(bool left, bool right, BinaryOp op) { @@ -241,22 +218,6 @@ const char *expr_const_to_error_string(const ExprConst *expr) } -void expr_const_set_float(ExprConst *expr, Real d, TypeKind kind) -{ - switch (kind) - { - case TYPE_F32: - expr->fxx = (Float) { (float)d, TYPE_F32 }; - break; - case TYPE_F64: - expr->fxx = (Float) { (double)d, TYPE_F64 }; - break; - default: - expr->fxx = (Float) { d, kind }; - break; - } - expr->const_kind = CONST_FLOAT; -} diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index b128c62bd..a5315ecbd 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -765,10 +765,7 @@ static Expr *parse_subscript_expr(ParseContext *c, Expr *left) } else { - index = EXPR_NEW_TOKEN(EXPR_CONST); - index->type = type_uint; - index->resolve_status = RESOLVE_DONE; - expr_const_set_int(&index->const_expr, 0, type_uint->type_kind); + index = expr_new_const_int(c->span, type_uint, 0, true); } bool is_len_range = try_consume(c, TOKEN_COLON); if (is_len_range || try_consume(c, TOKEN_DOTDOT)) diff --git a/src/compiler/parse_stmt.c b/src/compiler/parse_stmt.c index 2a92f8a37..dc429861e 100644 --- a/src/compiler/parse_stmt.c +++ b/src/compiler/parse_stmt.c @@ -81,10 +81,7 @@ static inline Ast* parse_do_stmt(ParseContext *c) if (try_consume(c, TOKEN_EOS)) { - Expr *exit = expr_new(EXPR_CONST, c->prev_span); - expr_const_set_bool(&exit->const_expr, false); - exit->type = type_bool; - do_ast->for_stmt.cond = exprid(exit); + do_ast->for_stmt.cond = exprid(expr_new_const_bool(c->prev_span, type_bool, false)); } else { @@ -303,11 +300,7 @@ static inline Ast* parse_switch_stmt(ParseContext *c) if (!try_consume(c, TOKEN_LPAREN)) { Expr *cond = expr_new(EXPR_COND, switch_ast->span); - Expr *expr = expr_new(EXPR_CONST, switch_ast->span); - expr_const_set_bool(&expr->const_expr, true); - expr->resolve_status = RESOLVE_DONE; - expr->type = type_bool; - vec_add(cond->cond_expr, expr); + vec_add(cond->cond_expr, expr_new_const_bool(switch_ast->span, type_bool, true)); switch_ast->switch_stmt.cond = exprid(cond); } else diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index 3e8712e9a..b068bf613 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -43,10 +43,7 @@ bool pointer_to_integer(Expr *expr, Type *type) if (insert_runtime_cast_unless_const(expr, CAST_PTRXI, type)) return true; // Revisit this to support pointers > 64 bits. - expr_const_set_int(&expr->const_expr, expr->const_expr.ixx.i.low, TYPE_POINTER); - expr->type = type; - expr->const_expr.narrowable = false; - expr->const_expr.is_hex = false; + expr_rewrite_const_int(expr, type, expr->const_expr.ptr, false); return true; } @@ -107,10 +104,7 @@ static void const_int_to_fp_cast(Expr *expr, Type *canonical, Type *type) bool bool_to_int(Expr *expr, Type *canonical, Type *type) { if (insert_runtime_cast_unless_const(expr, CAST_BOOLINT, type)) return true; - expr_const_set_int(&expr->const_expr, expr->const_expr.b ? 1 : 0, canonical->type_kind); - expr->type = type; - expr->const_expr.narrowable = false; - expr->const_expr.is_hex = false; + expr_rewrite_const_int(expr, type, expr->const_expr.b ? 1 : 0, false); return true; } @@ -123,10 +117,7 @@ bool bool_to_float(Expr *expr, Type *canonical, Type *type) if (insert_runtime_cast_unless_const(expr, CAST_BOOLFP, type)) return true; assert(expr->const_expr.const_kind == CONST_BOOL); - expr_const_set_float(&expr->const_expr, expr->const_expr.b ? 1.0 : 0.0, canonical->type_kind); - expr->type = type; - expr->const_expr.narrowable = false; - expr->const_expr.is_hex = false; + expr_rewrite_const_float(expr, type, expr->const_expr.b ? 1.0 : 0.0); return true; } @@ -150,10 +141,7 @@ bool integer_to_bool(Expr *expr, Type *type) { if (insert_runtime_cast_unless_const(expr, CAST_INTBOOL, type)) return true; - expr_const_set_bool(&expr->const_expr, !int_is_zero(expr->const_expr.ixx)); - expr->type = type; - expr->const_expr.narrowable = false; - expr->const_expr.is_hex = false; + expr_rewrite_const_bool(expr, type, !int_is_zero(expr->const_expr.ixx)); return true; } @@ -164,10 +152,7 @@ bool float_to_bool(Expr *expr, Type *type) { if (insert_runtime_cast_unless_const(expr, CAST_FPBOOL, type)) return true; - expr_const_set_bool(&expr->const_expr, expr->const_expr.fxx.f != 0.0); - expr->type = type; - expr->const_expr.narrowable = false; - expr->const_expr.is_hex = false; + expr_rewrite_const_bool(expr, type, expr->const_expr.fxx.f != 0.0); return true; } @@ -178,11 +163,7 @@ bool float_to_bool(Expr *expr, Type *type) static bool float_to_float(Expr* expr, Type *canonical, Type *type) { if (insert_runtime_cast_unless_const(expr, CAST_FPFP, type)) return true; - - expr_const_set_float(&expr->const_expr, expr->const_expr.fxx.f, canonical->type_kind); - expr->type = type; - expr->const_expr.is_hex = false; - expr->const_expr.narrowable = false; + expr_rewrite_const_float(expr, type, expr->const_expr.fxx.f); return true; } @@ -299,10 +280,7 @@ static bool int_to_float(Expr *expr, CastKind kind, Type *canonical, Type *type) static bool int_literal_to_bool(Expr *expr, Type *type) { assert(expr->expr_kind == EXPR_CONST); - expr_const_set_bool(&expr->const_expr, !int_is_zero(expr->const_expr.ixx)); - expr->const_expr.narrowable = false; - expr->const_expr.is_hex = false; - expr->type = type; + expr_rewrite_const_bool(expr, type, !int_is_zero(expr->const_expr.ixx)); return true; } @@ -351,7 +329,7 @@ static Type *enum_to_int_cast(Expr* expr, Type *from) expr->type = original; if (expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_ENUM) { - expr_const_set_int(&expr->const_expr, expr->const_expr.enum_val->enum_constant.ordinal, type_flatten(original)->type_kind); + expr_rewrite_const_int(expr, original, expr->const_expr.enum_val->enum_constant.ordinal, false); return original; } insert_cast(expr, CAST_ENUMLOW, type_add_optional(original, IS_OPTIONAL(expr))); @@ -1232,7 +1210,7 @@ static bool err_to_bool(Expr *expr, Type *to_type) case CONST_INTEGER: return int_literal_to_bool(expr, to_type); case CONST_ERR: - expr_const_set_bool(&expr->const_expr, expr->const_expr.err_val != NULL); + expr_rewrite_const_bool(expr, type_bool, expr->const_expr.err_val != NULL); return true; default: UNREACHABLE @@ -1249,13 +1227,13 @@ static inline bool subarray_to_bool(Expr *expr) switch (list->kind) { case CONST_INIT_ZERO: - expr_const_set_bool(&expr->const_expr, false); + expr_rewrite_const_bool(expr, type_bool, false); return true; case CONST_INIT_ARRAY: - expr_const_set_bool(&expr->const_expr, vec_size(list->init_array.elements) > 0); + expr_rewrite_const_bool(expr, type_bool, vec_size(list->init_array.elements) > 0); return true; case CONST_INIT_ARRAY_FULL: - expr_const_set_bool(&expr->const_expr, vec_size(list->init_array_full) > 0); + expr_rewrite_const_bool(expr, type_bool, vec_size(list->init_array_full) > 0); return true; case CONST_INIT_STRUCT: case CONST_INIT_UNION: diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 9e64fc698..0adc3deef 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -1801,10 +1801,7 @@ static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl) stmt->expr_stmt = call; ast_append(&next, stmt); Expr *c = expr_new(EXPR_CONST, decl->span); - c->type = type_cint; - expr_const_set_int(&c->const_expr, 0, c->type->type_kind); - c->resolve_status = RESOLVE_DONE; - ret_stmt->expr_stmt = c; + ret_stmt->expr_stmt = expr_new_const_int(decl->span, type_cint, 0, true); } ast_append(&next, ret_stmt); assert(body); diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index adec59cf7..4fc4fb959 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -16,25 +16,16 @@ static bool sema_take_addr_of(Expr *inner); static inline bool sema_expr_analyse_binary(SemaContext *context, Expr *expr); static inline bool sema_cast_rvalue(SemaContext *context, Expr *expr); static Expr *expr_access_inline_member(Expr *parent, Decl *parent_decl); -static inline void expr_set_as_const_list(Expr *expr, ConstInitializer *list); static inline bool sema_expr_analyse_builtin(SemaContext *context, Expr *expr, bool throw_error); static bool sema_check_stmt_compile_time(SemaContext *context, Ast *ast); static bool binary_arithmetic_promotion(SemaContext *context, Expr *left, Expr *right, Type *left_type, Type *right_type, Expr *parent, const char *error_message); static inline bool expr_both_const(Expr *left, Expr *right); -static inline void expr_set_as_const_list(Expr *expr, ConstInitializer *list) -{ - expr->expr_kind = EXPR_CONST; - expr->const_expr.const_kind = CONST_LIST; - expr->const_expr.list = list; -} + static bool sema_decay_array_pointers(Expr *expr) { - CanonicalType *pointer_type = type_pointer_type(type_no_optional(expr->type)); - if (!pointer_type || !type_is_arraylike(pointer_type)) return true; - return cast_implicit(expr, type_add_optional(type_get_ptr(pointer_type->array.base), IS_OPTIONAL(expr))); } @@ -3022,28 +3013,27 @@ static inline void sema_expr_from_zero_const(Expr *expr, Type *type) { expr->expr_kind = EXPR_CONST; expr->const_expr.narrowable = true; - type = type->canonical; - switch (type->type_kind) + switch (type->canonical->type_kind) { case TYPE_POISONED: case TYPE_VOID: UNREACHABLE case ALL_INTS: - expr_const_set_int(&expr->const_expr, 0, type->type_kind); - break; + expr_rewrite_const_int(expr, type, 0, true); + return; case ALL_FLOATS: - expr_const_set_float(&expr->const_expr, 0, type->type_kind); + expr_rewrite_const_float(expr, type, 0); break; case TYPE_BOOL: - expr_const_set_bool(&expr->const_expr, false); - break; + expr_rewrite_const_bool(expr, type, false); + return; case TYPE_POINTER: case TYPE_FAULTTYPE: case TYPE_ANY: case TYPE_ANYERR: case TYPE_TYPEID: - expr_const_set_null(&expr->const_expr); - break; + expr_rewrite_const_null(expr, type); + return; case TYPE_ENUM: expr->const_expr.const_kind = CONST_ENUM; expr->const_expr.enum_val = type->decl->enums.values[0]; @@ -3067,8 +3057,8 @@ static inline void sema_expr_from_zero_const(Expr *expr, Type *type) ConstInitializer *init = CALLOCS(ConstInitializer); init->kind = CONST_INIT_ZERO; init->type = type; - expr_set_as_const_list(expr, init); - break; + expr_rewrite_const_list(expr, type, init); + return; } case TYPE_DISTINCT: sema_expr_from_zero_const(expr, type->decl->distinct_decl.base_type); @@ -3369,17 +3359,6 @@ static inline bool sema_expr_analyse_group(SemaContext *context, Expr *expr) } -void expr_rewrite_to_int_const(Expr *expr_to_rewrite, Type *type, uint64_t value, bool narrowable) -{ - expr_to_rewrite->expr_kind = EXPR_CONST; - expr_const_set_int(&expr_to_rewrite->const_expr, value, type->canonical->type_kind); - expr_to_rewrite->type = type; - expr_to_rewrite->const_expr.narrowable = narrowable; - expr_to_rewrite->const_expr.is_hex = false; - expr_to_rewrite->resolve_status = RESOLVE_DONE; -} - - void expr_rewrite_to_string(Expr *expr_to_rewrite, const char *string) { expr_to_rewrite->expr_kind = EXPR_CONST; @@ -3549,7 +3528,7 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp if (name == kw_sizeof) { - expr_rewrite_to_int_const(expr, type_usize, type_size(canonical), true); + expr_rewrite_const_int(expr, type_usize, type_size(canonical), true); return true; } @@ -3580,7 +3559,7 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp } if (name == kw_elements) { - expr_rewrite_to_int_const(expr, type_isize, vec_size(decl->enums.values), true); + expr_rewrite_const_int(expr, type_isize, vec_size(decl->enums.values), true); return true; } if (name == kw_names) @@ -3607,7 +3586,7 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp } if (name == kw_elements) { - expr_rewrite_to_int_const(expr, type_isize, vec_size(decl->enums.values), true); + expr_rewrite_const_int(expr, type_isize, vec_size(decl->enums.values), true); return true; } break; @@ -3676,7 +3655,7 @@ static inline bool sema_create_const_kind(SemaContext *context, Expr *expr, Type Type *type_for_kind = type_kind ? type_kind->type : type_char; unsigned val = type_get_introspection_kind(type->type_kind); assert(type_for_kind->type_kind == TYPE_ENUM); - expr_rewrite_to_int_const(expr, type_flatten(type_for_kind), val, false); + expr_rewrite_const_int(expr, type_flatten(type_for_kind), val, false); return cast(expr, type_for_kind); } @@ -3700,7 +3679,7 @@ static inline bool sema_create_const_len(SemaContext *context, Expr *expr, Type default: return false; } - expr_rewrite_to_int_const(expr, type_usize, len, true); + expr_rewrite_const_int(expr, type_usize, len, true); return true; } @@ -3960,7 +3939,7 @@ static bool sema_expr_apply_type_property(SemaContext *context, Expr *expr, Type assert(type == type->canonical); if (kw == kw_sizeof) { - expr_rewrite_to_int_const(expr, type_usize, type_size(type), true); + expr_rewrite_const_int(expr, type_usize, type_size(type), true); return true; } if (kw == kw_kind) return sema_create_const_kind(context, expr, type); @@ -4080,7 +4059,7 @@ CHECK_DEEPER: } if (flat_type->type_kind == TYPE_ARRAY || flat_type->type_kind == TYPE_VECTOR) { - expr_rewrite_to_int_const(expr, type_isize, flat_type->array.len, true); + expr_rewrite_const_int(expr, type_isize, flat_type->array.len, true); return true; } } @@ -4722,8 +4701,7 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type { ConstInitializer *const_init = MALLOCS(ConstInitializer); sema_create_const_initializer(const_init, initializer); - expr_set_as_const_list(initializer, const_init); - return true; + expr_rewrite_const_list(initializer, initializer->type, const_init); } return true; } @@ -4824,11 +4802,11 @@ static inline bool sema_expr_analyse_struct_plain_initializer(SemaContext *conte { initializer->initializer_list[j] = initializer->initializer_list[j - 1]; } - Expr *new_initializer = expr_new(EXPR_INITIALIZER_LIST, initializer->span); + Expr *new_initializer = expr_new(EXPR_CONST, initializer->span); ConstInitializer *empty = CALLOCS(ConstInitializer); empty->kind = CONST_INIT_ZERO; - empty->type = member->type; - expr_set_as_const_list(new_initializer, empty); + empty->type = type_flatten(member->type); + expr_rewrite_const_list(new_initializer, member->type, empty); initializer->initializer_list[i] = new_initializer; size += 1; continue; @@ -4847,7 +4825,7 @@ static inline bool sema_expr_analyse_struct_plain_initializer(SemaContext *conte int reduce_by = max_index_to_copy - i - 1; size -= reduce_by; elements_needed -= reduce_by; - max_loop = MAX(size, elements_needed); + max_loop = size > elements_needed ? size : elements_needed; assert(size <= vec_size(initializer->initializer_list)); vec_resize(initializer->initializer_list, (unsigned)size); elements = initializer->initializer_list; @@ -4894,7 +4872,7 @@ static inline bool sema_expr_analyse_struct_plain_initializer(SemaContext *conte sema_create_const_initializer_value(element_init, expr); const_init->init_union.element = element_init; } - expr_set_as_const_list(initializer, const_init); + expr_rewrite_const_list(initializer, initializer->type, const_init); return true; } ConstInitializer **inits = MALLOC(sizeof(ConstInitializer *) * vec_size(elements)); @@ -4911,7 +4889,7 @@ static inline bool sema_expr_analyse_struct_plain_initializer(SemaContext *conte inits[i] = element_init; } const_init->init_struct = inits; - expr_set_as_const_list(initializer, const_init); + expr_rewrite_const_list(initializer, initializer->type, const_init); } // 7. Done! @@ -4985,7 +4963,7 @@ static inline bool sema_expr_analyse_array_plain_initializer(SemaContext *contex vec_add(inits, element_init); } const_init->init_array_full = inits; - expr_set_as_const_list(initializer, const_init); + expr_rewrite_const_list(initializer, initializer->type, const_init); } // 7. Done! @@ -5063,7 +5041,7 @@ static inline bool sema_expr_analyse_initializer(SemaContext *context, Type *ext ConstInitializer *initializer = CALLOCS(ConstInitializer); initializer->kind = CONST_INIT_ZERO; initializer->type = type_flatten(expr->type); - expr_set_as_const_list(expr, initializer); + expr_rewrite_const_list(expr, expr->type, initializer); return true; } @@ -5655,7 +5633,7 @@ static bool sema_expr_analyse_sub(SemaContext *context, Expr *expr, Expr *left, if (expr_both_const(left, right)) { - expr_rewrite_to_int_const(expr, type_iptrdiff, (left->const_expr.ptr - right->const_expr.ptr) / + expr_rewrite_const_int(expr, type_iptrdiff, (left->const_expr.ptr - right->const_expr.ptr) / type_size(left_type->pointer), false); return true; } @@ -5688,7 +5666,6 @@ static bool sema_expr_analyse_sub(SemaContext *context, Expr *expr, Expr *left, if (expr_both_const(left, right)) { left->const_expr.ptr -= right->const_expr.ixx.i.low * type_size(left_type->pointer); - expr_replace(expr, left); } @@ -7162,18 +7139,18 @@ static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr * } if (string == kw_LINEREAL) { - expr_rewrite_to_int_const(expr, type_isize, expr->span.row, true); + expr_rewrite_const_int(expr, type_isize, expr->span.row, true); return true; } if (string == kw_LINE) { if (context->original_inline_line) { - expr_rewrite_to_int_const(expr, type_isize, context->original_inline_line, true); + expr_rewrite_const_int(expr, type_isize, context->original_inline_line, true); } else { - expr_rewrite_to_int_const(expr, type_isize, expr->span.row, true); + expr_rewrite_const_int(expr, type_isize, expr->span.row, true); } return true; } @@ -7370,7 +7347,7 @@ static inline bool sema_expr_analyse_ct_alignof(SemaContext *context, Expr *expr type = result_type; } - expr_rewrite_to_int_const(expr, type_isize, align, true); + expr_rewrite_const_int(expr, type_isize, align, true); return true; } @@ -7395,7 +7372,7 @@ static inline bool sema_expr_analyse_ct_sizeof(SemaContext *context, Expr *expr) type = result_type; } - expr_rewrite_to_int_const(expr, type_isize, type_size(type), true); + expr_rewrite_const_int(expr, type_isize, type_size(type), true); return true; } @@ -7638,17 +7615,11 @@ RETRY: type = ret_type; } - expr->type = type_bool; - expr->expr_kind = EXPR_CONST; - expr_const_set_bool(&expr->const_expr, true); + expr_rewrite_const_bool(expr, type_bool, true); return true; NOT_DEFINED: - { - expr->type = type_bool; - } - expr->expr_kind = EXPR_CONST; - expr_const_set_bool(&expr->const_expr, false); + expr_rewrite_const_bool(expr, type_bool, false); return true; } @@ -7745,7 +7716,7 @@ static inline bool sema_expr_analyse_ct_offsetof(SemaContext *context, Expr *exp type = result_type; } - expr_rewrite_to_int_const(expr, type_iptrdiff, offset, true); + expr_rewrite_const_int(expr, type_iptrdiff, offset, true); return true; } @@ -7801,9 +7772,7 @@ static inline bool sema_expr_analyse_ct_conv(SemaContext *c, Expr *expr) default: UNREACHABLE } - expr_const_set_bool(&expr->const_expr, result); - expr->type = type_bool; - expr->expr_kind = EXPR_CONST; + expr_rewrite_const_bool(expr, type_bool, result); return true; } @@ -8178,7 +8147,7 @@ MemberIndex sema_get_initializer_const_array_size(SemaContext *context, Expr *in *is_const_size = false; return -1; } - size = MAX(size, index + 1); + if (index + 1 > size) size = index + 1; break; } case DESIGNATOR_RANGE: @@ -8189,7 +8158,7 @@ MemberIndex sema_get_initializer_const_array_size(SemaContext *context, Expr *in *is_const_size = false; return -1; } - size = MAX(size, index + 1); + if (index + 1 > size) size = index + 1; break; } default: diff --git a/src/compiler/sema_internal.h b/src/compiler/sema_internal.h index 547b0536f..ff849c3cf 100644 --- a/src/compiler/sema_internal.h +++ b/src/compiler/sema_internal.h @@ -77,7 +77,6 @@ bool sema_analyse_expr_lvalue(SemaContext *context, Expr *expr); bool sema_analyse_expr_lvalue_fold_const(SemaContext *context, Expr *expr); bool sema_analyse_ct_expr(SemaContext *context, Expr *expr); bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *struct_var, Decl *decl, bool failable); -void expr_rewrite_to_int_const(Expr *expr_to_rewrite, Type *type, uint64_t value, bool narrowable); void expr_rewrite_to_string(Expr *expr_to_rewrite, const char *string); const char *ct_eval_expr(SemaContext *c, const char *expr_type, Expr *inner, TokenType *type, Path **path_ref, bool report_missing); extern const char *ct_eval_error; diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index d3fa566cb..79ae04c88 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -1155,8 +1155,7 @@ static inline bool sema_analyse_foreach_stmt(SemaContext *context, Ast *statemen if (!len_call) { // Create const len if missing. - len_call = expr_new(EXPR_CONST, enumerator->span); - expr_rewrite_to_int_const(len_call, type_isize, array_len, true); + len_call = expr_new_const_int(enumerator->span, type_isize, array_len, true); } if (!cast_implicit(len_call, index_type)) return false; // __idx$ = (IndexType)(@__enum$.len()) (or const) @@ -1170,8 +1169,7 @@ static inline bool sema_analyse_foreach_stmt(SemaContext *context, Ast *statemen if (!cast_implicit(len_call, index_type)) return false; vec_add(expressions, expr_generate_decl(len_decl, len_call)); } - Expr *idx_init = expr_new(EXPR_CONST, idx_decl->span); - expr_rewrite_to_int_const(idx_init, index_type, 0, true); + Expr *idx_init = expr_new_const_int(idx_decl->span, index_type, 0, true); vec_add(expressions, expr_generate_decl(idx_decl, idx_init)); } @@ -1187,8 +1185,7 @@ static inline bool sema_analyse_foreach_stmt(SemaContext *context, Ast *statemen cond = expr_new(EXPR_BINARY, idx_decl->span); cond->binary_expr.operator = BINARYOP_GT; cond->binary_expr.left = exprid(expr_variable(idx_decl)); - Expr *rhs = expr_new(EXPR_CONST, enumerator->span); - expr_rewrite_to_int_const(rhs, index_type, 0, true); + Expr *rhs = expr_new_const_int(enumerator->span, index_type, 0, true); cond->binary_expr.right = exprid(rhs); // Create --__idx$ @@ -1211,8 +1208,7 @@ static inline bool sema_analyse_foreach_stmt(SemaContext *context, Ast *statemen } else { - Expr *rhs = expr_new(EXPR_CONST, enumerator->span); - expr_rewrite_to_int_const(rhs, type_isize, array_len, true); + Expr *rhs = expr_new_const_int(enumerator->span, type_isize, array_len, true); cond->binary_expr.right = exprid(rhs); } @@ -2070,11 +2066,7 @@ static bool sema_analyse_ct_foreach_stmt(SemaContext *context, Ast *statement) value->var.init_expr = expression[i]; if (index) { - Expr *expr = expr_new(EXPR_CONST, index->span); - expr_const_set_int(&expr->const_expr, i, TYPE_I32); - expr->const_expr.narrowable = true; - expr->type = type_int; - index->var.init_expr = expr; + index->var.init_expr = expr_new_const_int(index->span, type_int, i, true); index->type = type_int; } if (!sema_analyse_compound_stmt(context, compound_stmt)) return SCOPE_POP_ERROR(); diff --git a/src/version.h b/src/version.h index ba4c3ca44..b8ad304ad 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.3.21" \ No newline at end of file +#define COMPILER_VERSION "0.3.22" \ No newline at end of file diff --git a/test/test_suite/compile_time/compile_time_pointers.c3t b/test/test_suite/compile_time/compile_time_pointers.c3t index 09511ecc7..85d798ef5 100644 --- a/test/test_suite/compile_time/compile_time_pointers.c3t +++ b/test/test_suite/compile_time/compile_time_pointers.c3t @@ -28,7 +28,7 @@ fn void test() @test_EXX = local_unnamed_addr constant i8* inttoptr (i64 155 to i8*), align 8 @test_KEX = local_unnamed_addr constant i64 -12, align 8 @test_CAB = local_unnamed_addr constant i8* inttoptr (i64 143 to i8*), align 8 -@test_ZAB = local_unnamed_addr constant i64 144, align 8 +@test_ZAB = local_unnamed_addr constant i64 143, align 8 @test_BOB = local_unnamed_addr constant i32* inttoptr (i64 12 to i32*), align 8 @test_BAB = local_unnamed_addr constant i32* inttoptr (i64 20 to i32*), align 8 @test_AO = local_unnamed_addr constant i64 2, align 8 diff --git a/test/test_suite2/compile_time/compile_time_pointers.c3t b/test/test_suite2/compile_time/compile_time_pointers.c3t index 3cf527e29..4c60c3372 100644 --- a/test/test_suite2/compile_time/compile_time_pointers.c3t +++ b/test/test_suite2/compile_time/compile_time_pointers.c3t @@ -28,7 +28,7 @@ fn void test() @test_EXX = local_unnamed_addr constant ptr inttoptr (i64 155 to ptr), align 8 @test_KEX = local_unnamed_addr constant i64 -12, align 8 @test_CAB = local_unnamed_addr constant ptr inttoptr (i64 143 to ptr), align 8 -@test_ZAB = local_unnamed_addr constant i64 144, align 8 +@test_ZAB = local_unnamed_addr constant i64 143, align 8 @test_BOB = local_unnamed_addr constant ptr inttoptr (i64 12 to ptr), align 8 @test_BAB = local_unnamed_addr constant ptr inttoptr (i64 20 to ptr), align 8 @test_AO = local_unnamed_addr constant i64 2, align 8