mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
General refactoring and fix of compile time folding of pointers.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.3.21"
|
||||
#define COMPILER_VERSION "0.3.22"
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user