General refactoring and fix of compile time folding of pointers.

This commit is contained in:
Christoffer Lerno
2022-08-17 21:54:47 +02:00
parent fd642e333b
commit d95e0b4733
14 changed files with 167 additions and 192 deletions

View File

@@ -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,

View File

@@ -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)
{

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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))

View File

@@ -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

View File

@@ -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:

View File

@@ -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);

View File

@@ -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:

View File

@@ -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;

View File

@@ -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();

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.3.21"
#define COMPILER_VERSION "0.3.22"

View File

@@ -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

View File

@@ -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