mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Remove the last "cast" operations.
This commit is contained in:
@@ -411,8 +411,10 @@ static void c_emit_expr(GenContext *c, CValue *value, Expr *expr)
|
||||
case EXPR_ADDR_CONVERSION:
|
||||
case EXPR_EXT_TRUNC:
|
||||
case EXPR_MAKE_ANY:
|
||||
case EXPR_MAKE_SLICE:
|
||||
case EXPR_INT_TO_BOOL:
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
break;
|
||||
case EXPR_ACCESS:
|
||||
break;
|
||||
@@ -435,7 +437,7 @@ static void c_emit_expr(GenContext *c, CValue *value, Expr *expr)
|
||||
case EXPR_CALL:
|
||||
break;
|
||||
case EXPR_CAST:
|
||||
break;
|
||||
UNREACHABLE
|
||||
case EXPR_CATCH_UNWRAP:
|
||||
break;
|
||||
case EXPR_COMPILER_CONST:
|
||||
|
||||
@@ -968,7 +968,6 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CastKind kind : 8;
|
||||
ExprId expr;
|
||||
TypeInfoId type_info;
|
||||
} ExprCast;
|
||||
@@ -1134,6 +1133,13 @@ typedef struct
|
||||
Expr *inner;
|
||||
Expr *typeid;
|
||||
} ExprMakeAny;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Expr *ptr;
|
||||
ArraySize len;
|
||||
} ExprMakeSlice;
|
||||
|
||||
struct Expr_
|
||||
{
|
||||
Type *type;
|
||||
@@ -1179,6 +1185,7 @@ struct Expr_
|
||||
Expr** initializer_list; // 8
|
||||
Expr *inner_expr; // 8
|
||||
ExprMakeAny make_any_expr;
|
||||
ExprMakeSlice make_slice_expr;
|
||||
Decl *lambda_expr; // 8
|
||||
ExprMacroBlock macro_block; // 24
|
||||
ExprMacroBody macro_body_expr; // 16
|
||||
@@ -1322,7 +1329,6 @@ typedef struct
|
||||
bool value_by_ref : 1;
|
||||
bool iterator : 1;
|
||||
bool is_reverse : 1;
|
||||
CastKind cast : 8;
|
||||
ExprId enumeration;
|
||||
AstId body;
|
||||
DeclId index;
|
||||
@@ -2227,6 +2233,7 @@ Expr *expr_negate_expr(Expr *expr);
|
||||
bool expr_may_addr(Expr *expr);
|
||||
bool expr_in_int_range(Expr *expr, int64_t low, int64_t high);
|
||||
bool expr_is_unwrapped_ident(Expr *expr);
|
||||
bool expr_is_zero(Expr *expr);
|
||||
INLINE Expr *expr_new_expr(ExprKind kind, Expr *expr);
|
||||
INLINE bool expr_ok(Expr *expr);
|
||||
INLINE void expr_resolve_ident(Expr *expr, Decl *decl);
|
||||
@@ -3283,6 +3290,7 @@ ConstInitializer *const_init_new_struct(Type *type, Expr **elements);
|
||||
ConstInitializer *const_init_new_array_full(Type *type, ConstInitializer **elements);
|
||||
ConstInitializer *const_init_new_zero_array_value(Type *type, ArrayIndex index);
|
||||
ConstInitializer *const_init_new_array_value(Expr *expr, ArrayIndex index);
|
||||
bool const_init_is_zero(ConstInitializer *init);
|
||||
void const_init_rewrite_to_value(ConstInitializer *const_init, Expr *value);
|
||||
void const_init_rewrite_to_zero(ConstInitializer *init, Type *type);
|
||||
|
||||
@@ -3369,6 +3377,9 @@ static inline void expr_set_span(Expr *expr, SourceSpan loc)
|
||||
expr_set_span(expr->make_any_expr.inner, loc);
|
||||
expr_set_span(expr->make_any_expr.typeid, loc);
|
||||
return;
|
||||
case EXPR_MAKE_SLICE:
|
||||
if (expr->make_slice_expr.ptr) expr_set_span(expr->make_slice_expr.ptr, loc);
|
||||
return;
|
||||
case EXPR_SPLAT:
|
||||
case EXPR_PTR_ACCESS:
|
||||
case EXPR_VECTOR_TO_ARRAY:
|
||||
@@ -3384,6 +3395,7 @@ static inline void expr_set_span(Expr *expr, SourceSpan loc)
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
case EXPR_ADDR_CONVERSION:
|
||||
case EXPR_RECAST:
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
expr_set_span(expr->inner_expr, loc);
|
||||
return;
|
||||
case EXPR_EXPRESSION_LIST:
|
||||
@@ -3759,35 +3771,9 @@ INLINE void expr_rewrite_int_to_bool(Expr *expr, bool negate)
|
||||
{
|
||||
if (expr_is_const(expr))
|
||||
{
|
||||
switch (expr->const_expr.const_kind)
|
||||
{
|
||||
case CONST_FLOAT:
|
||||
case CONST_BOOL:
|
||||
case CONST_ENUM:
|
||||
case CONST_BYTES:
|
||||
case CONST_STRING:
|
||||
case CONST_SLICE:
|
||||
case CONST_INITIALIZER:
|
||||
case CONST_UNTYPED_LIST:
|
||||
case CONST_MEMBER:
|
||||
UNREACHABLE
|
||||
case CONST_ERR:
|
||||
expr_rewrite_const_bool(expr, type_bool, expr->const_expr.enum_err_val != NULL);
|
||||
return;
|
||||
case CONST_INTEGER:
|
||||
expr_rewrite_const_bool(expr, type_bool, !int_is_zero(expr->const_expr.ixx));
|
||||
return;
|
||||
case CONST_POINTER:
|
||||
expr_rewrite_const_bool(expr, type_bool, expr->const_expr.ptr != 0);
|
||||
return;
|
||||
case CONST_TYPEID:
|
||||
expr_rewrite_const_bool(expr, type_bool, expr->type != NULL);
|
||||
return;
|
||||
case CONST_REF:
|
||||
expr_rewrite_const_bool(expr, type_bool, true);
|
||||
return;
|
||||
}
|
||||
UNREACHABLE
|
||||
bool is_zero = expr_is_zero(expr);
|
||||
expr_rewrite_const_bool(expr, type_bool, negate ? is_zero : !is_zero);
|
||||
return;
|
||||
}
|
||||
Expr *inner = expr_copy(expr);
|
||||
expr->expr_kind = EXPR_INT_TO_BOOL;
|
||||
|
||||
@@ -486,6 +486,7 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr)
|
||||
case EXPR_FLOAT_TO_INT:
|
||||
case EXPR_SLICE_LEN:
|
||||
case EXPR_DISCARD:
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
case EXPR_RVALUE:
|
||||
case EXPR_RECAST:
|
||||
@@ -496,6 +497,9 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr)
|
||||
MACRO_COPY_EXPR(expr->make_any_expr.inner);
|
||||
MACRO_COPY_EXPR(expr->make_any_expr.typeid);
|
||||
return expr;
|
||||
case EXPR_MAKE_SLICE:
|
||||
MACRO_COPY_EXPR(expr->make_slice_expr.ptr);
|
||||
return expr;
|
||||
case EXPR_DEFAULT_ARG:
|
||||
MACRO_COPY_EXPR(expr->default_arg_expr.inner);
|
||||
return expr;
|
||||
|
||||
@@ -540,14 +540,6 @@ typedef enum
|
||||
CALL_ENV_ATTR,
|
||||
} CallEnvKind;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CAST_APTSA,
|
||||
CAST_BSBOOL,
|
||||
CAST_ERROR,
|
||||
CAST_EUER,
|
||||
} CastKind;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CMP_LT = -1,
|
||||
@@ -768,12 +760,14 @@ typedef enum
|
||||
EXPR_INT_TO_FLOAT,
|
||||
EXPR_INT_TO_PTR,
|
||||
EXPR_PTR_TO_INT,
|
||||
EXPR_ANYFAULT_TO_FAULT,
|
||||
EXPR_LAMBDA,
|
||||
EXPR_LAST_FAULT,
|
||||
EXPR_MACRO_BLOCK,
|
||||
EXPR_MACRO_BODY,
|
||||
EXPR_MACRO_BODY_EXPANSION,
|
||||
EXPR_MAKE_ANY,
|
||||
EXPR_MAKE_SLICE,
|
||||
EXPR_MEMBER_GET,
|
||||
EXPR_NAMED_ARGUMENT,
|
||||
EXPR_NOP,
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "compiler_internal.h"
|
||||
|
||||
static inline bool expr_cast_is_runtime_const(Expr *expr);
|
||||
static inline bool expr_list_is_constant_eval(Expr **exprs);
|
||||
static inline bool expr_unary_addr_is_constant_eval(Expr *expr);
|
||||
static inline ConstInitializer *initializer_for_index(ConstInitializer *initializer, ArraySize index, bool from_back);
|
||||
@@ -29,6 +28,53 @@ bool expr_in_int_range(Expr *expr, int64_t low, int64_t high)
|
||||
return value >= low && value <= high;
|
||||
}
|
||||
|
||||
bool expr_is_zero(Expr *expr)
|
||||
{
|
||||
if (!sema_cast_const(expr)) return false;
|
||||
switch (expr->const_expr.const_kind)
|
||||
{
|
||||
case CONST_FLOAT:
|
||||
return !expr->const_expr.fxx.f;
|
||||
case CONST_INTEGER:
|
||||
return int_is_zero(expr->const_expr.ixx);
|
||||
case CONST_BOOL:
|
||||
return !expr->const_expr.b;
|
||||
case CONST_ENUM:
|
||||
case CONST_ERR:
|
||||
return !expr->const_expr.enum_err_val->enum_constant.ordinal;
|
||||
case CONST_BYTES:
|
||||
case CONST_STRING:
|
||||
{
|
||||
size_t len = expr->const_expr.bytes.len;
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if (expr->const_expr.bytes.ptr[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case CONST_POINTER:
|
||||
return !expr->const_expr.ptr;
|
||||
case CONST_TYPEID:
|
||||
return !expr->const_expr.typeid;
|
||||
case CONST_SLICE:
|
||||
return const_init_is_zero(expr->const_expr.slice_init);
|
||||
case CONST_INITIALIZER:
|
||||
return const_init_is_zero(expr->const_expr.initializer);
|
||||
case CONST_UNTYPED_LIST:
|
||||
{
|
||||
FOREACH(Expr *, e, expr->const_expr.untyped_list)
|
||||
{
|
||||
if (!expr_is_zero(e)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case CONST_REF:
|
||||
return !expr->const_expr.global_ref;
|
||||
case CONST_MEMBER:
|
||||
return false;
|
||||
}
|
||||
UNREACHABLE
|
||||
}
|
||||
bool expr_is_unwrapped_ident(Expr *expr)
|
||||
{
|
||||
if (expr->expr_kind != EXPR_IDENTIFIER) return false;
|
||||
@@ -83,6 +129,7 @@ bool expr_may_addr(Expr *expr)
|
||||
case EXPR_BENCHMARK_HOOK:
|
||||
case EXPR_TEST_HOOK:
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
case EXPR_VECTOR_TO_ARRAY:
|
||||
case EXPR_SLICE_TO_VEC_ARRAY:
|
||||
case EXPR_SCALAR_TO_VECTOR:
|
||||
@@ -147,6 +194,7 @@ bool expr_may_addr(Expr *expr)
|
||||
case EXPR_VASPLAT:
|
||||
case EXPR_EXT_TRUNC:
|
||||
case EXPR_INT_TO_BOOL:
|
||||
case EXPR_MAKE_SLICE:
|
||||
return false;
|
||||
}
|
||||
UNREACHABLE
|
||||
@@ -208,6 +256,7 @@ bool expr_is_runtime_const(Expr *expr)
|
||||
case EXPR_SLICE_LEN:
|
||||
return false;
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
case EXPR_RVALUE:
|
||||
case EXPR_RECAST:
|
||||
case EXPR_ADDR_CONVERSION:
|
||||
@@ -219,6 +268,10 @@ bool expr_is_runtime_const(Expr *expr)
|
||||
case EXPR_SLICE_TO_VEC_ARRAY:
|
||||
case EXPR_SCALAR_TO_VECTOR:
|
||||
return expr_is_runtime_const(expr->inner_expr);
|
||||
case EXPR_MAKE_SLICE:
|
||||
expr = expr->make_slice_expr.ptr;
|
||||
if (!expr) return true;
|
||||
goto RETRY;
|
||||
case EXPR_MAKE_ANY:
|
||||
if (!expr_is_runtime_const(expr->make_any_expr.typeid)) return false;
|
||||
expr = expr->make_any_expr.inner;
|
||||
@@ -239,7 +292,7 @@ bool expr_is_runtime_const(Expr *expr)
|
||||
}
|
||||
return exprid_is_runtime_const(expr->builtin_access_expr.inner);
|
||||
case EXPR_CAST:
|
||||
return expr_cast_is_runtime_const(expr);
|
||||
return exprid_is_runtime_const(expr->cast_expr.expr);
|
||||
case EXPR_INT_TO_BOOL:
|
||||
return expr_is_runtime_const(expr->int_to_bool_expr.inner);
|
||||
case EXPR_EXT_TRUNC:
|
||||
@@ -365,20 +418,6 @@ bool expr_is_runtime_const(Expr *expr)
|
||||
UNREACHABLE
|
||||
}
|
||||
|
||||
static inline bool expr_cast_is_runtime_const(Expr *expr)
|
||||
{
|
||||
switch (expr->cast_expr.kind)
|
||||
{
|
||||
case CAST_ERROR:
|
||||
UNREACHABLE
|
||||
case CAST_EUER:
|
||||
case CAST_APTSA:
|
||||
case CAST_BSBOOL:
|
||||
return exprid_is_runtime_const(expr->cast_expr.expr);
|
||||
|
||||
}
|
||||
UNREACHABLE
|
||||
}
|
||||
|
||||
static inline bool expr_list_is_constant_eval(Expr **exprs)
|
||||
{
|
||||
@@ -605,6 +644,8 @@ bool expr_is_pure(Expr *expr)
|
||||
case EXPR_BENCHMARK_HOOK:
|
||||
case EXPR_TEST_HOOK:
|
||||
return false;
|
||||
case EXPR_MAKE_SLICE:
|
||||
return expr_is_pure(expr->make_slice_expr.ptr);
|
||||
case EXPR_MAKE_ANY:
|
||||
return expr_is_pure(expr->make_any_expr.inner) && expr_is_pure(expr->make_any_expr.typeid);
|
||||
case EXPR_PTR_ACCESS:
|
||||
@@ -619,6 +660,7 @@ bool expr_is_pure(Expr *expr)
|
||||
case EXPR_SLICE_LEN:
|
||||
case EXPR_DISCARD:
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
case EXPR_RVALUE:
|
||||
case EXPR_RECAST:
|
||||
case EXPR_ADDR_CONVERSION:
|
||||
|
||||
@@ -246,6 +246,8 @@ void print_var_expr(FILE *file, Expr *expr)
|
||||
case EXPR_ADDR_CONVERSION:
|
||||
print_var_expr(file, expr->inner_expr);
|
||||
break;
|
||||
case EXPR_MAKE_SLICE:
|
||||
TODO
|
||||
case EXPR_MAKE_ANY:
|
||||
fputs("TODO: MAKE_ANY", file);
|
||||
break;
|
||||
@@ -266,6 +268,7 @@ void print_var_expr(FILE *file, Expr *expr)
|
||||
print_var_expr(file, expr->access_expr.parent);
|
||||
fputs(")", file);
|
||||
break;
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
TODO
|
||||
case EXPR_SLICE_LEN:
|
||||
@@ -417,11 +420,7 @@ void print_var_expr(FILE *file, Expr *expr)
|
||||
}
|
||||
break;
|
||||
case EXPR_CAST:
|
||||
fputs("(", file);
|
||||
print_type(file, type_infoptr(expr->cast_expr.type_info));
|
||||
fputs(")", file);
|
||||
print_var_expr(file, exprptr(expr->cast_expr.expr));
|
||||
break;
|
||||
UNREACHABLE
|
||||
case EXPR_BUILTIN:
|
||||
case EXPR_COMPILER_CONST:
|
||||
PRINTF("$$%s", expr->builtin_expr.ident);
|
||||
|
||||
@@ -1257,34 +1257,6 @@ void llvm_new_phi(GenContext *c, BEValue *value, const char *name, Type *type, L
|
||||
|
||||
static inline void llvm_emit_initialize_reference(GenContext *c, BEValue *value, Expr *expr);
|
||||
|
||||
/**
|
||||
* Here we are converting an array to a slice.
|
||||
* int[] x = &the_array;
|
||||
* @param c
|
||||
* @param value
|
||||
* @param to_type
|
||||
* @param from_type
|
||||
*/
|
||||
static void llvm_emit_arr_to_slice_cast(GenContext *c, BEValue *value, Type *to_type)
|
||||
{
|
||||
ByteSize size = value->type->pointer->array.len;
|
||||
LLVMValueRef pointer;
|
||||
Type *array_type = value->type->pointer->array.base;
|
||||
if (size)
|
||||
{
|
||||
llvm_value_rvalue(c, value);
|
||||
pointer = value->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
pointer = llvm_get_zero(c, type_get_ptr(array_type));
|
||||
}
|
||||
LLVMValueRef len = llvm_const_int(c, type_usz, size);
|
||||
llvm_value_aggregate_two(c, value, to_type, pointer, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Prune the common occurrence where the optional is not used.
|
||||
static void llvm_prune_optional(GenContext *c, LLVMBasicBlockRef discard_fail)
|
||||
@@ -1399,28 +1371,6 @@ static void llvm_emit_bitstruct_to_bool(GenContext *c, BEValue *value, Type *to_
|
||||
llvm_value_set(value, llvm_emit_char_array_zero(c, value, false), to_type);
|
||||
}
|
||||
|
||||
void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *value, Type *to_type, Type *from_type)
|
||||
{
|
||||
Type *to_type_original = to_type;
|
||||
to_type = type_flatten(to_type);
|
||||
from_type = type_flatten(from_type);
|
||||
switch (cast_kind)
|
||||
{
|
||||
case CAST_BSBOOL:
|
||||
llvm_emit_bitstruct_to_bool(c, value, to_type, from_type);
|
||||
return;
|
||||
case CAST_ERROR:
|
||||
UNREACHABLE
|
||||
case CAST_APTSA:
|
||||
llvm_emit_arr_to_slice_cast(c, value, to_type);
|
||||
break;
|
||||
case CAST_EUER:
|
||||
REMINDER("Improve fault to err comparison");
|
||||
break;
|
||||
}
|
||||
value->type = type_lowering(to_type);
|
||||
}
|
||||
|
||||
void llvm_emit_bool_cast(GenContext *c, Expr *expr, BEValue *value)
|
||||
{
|
||||
switch (value->type->type_kind)
|
||||
@@ -1486,6 +1436,7 @@ void llvm_emit_bool_cast(GenContext *c, Expr *expr, BEValue *value)
|
||||
value->kind = BE_BOOLEAN;
|
||||
return;
|
||||
case TYPE_BITSTRUCT:
|
||||
|
||||
llvm_emit_bitstruct_to_bool(c, value, type_bool, value->type);
|
||||
return;
|
||||
case TYPE_INFERRED_ARRAY:
|
||||
@@ -7065,6 +7016,24 @@ void llvm_emit_expr_global_value(GenContext *c, BEValue *value, Expr *expr)
|
||||
static void llvm_emit_int_to_bool(GenContext *c, BEValue *value, Expr *expr)
|
||||
{
|
||||
llvm_emit_expr(c, value, expr->int_to_bool_expr.inner);
|
||||
Type *inner_type = value->type;
|
||||
if (inner_type->type_kind == TYPE_ARRAY)
|
||||
{
|
||||
assert(inner_type->array.base == type_char || inner_type->array.base == type_ichar);
|
||||
llvm_value_addr(c, value);
|
||||
unsigned len = type_size(value->type);
|
||||
ASSERT0(len > 0);
|
||||
LLVMValueRef total = NULL;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
LLVMValueRef ref = llvm_emit_const_ptradd_inbounds_raw(c, value->value, i);
|
||||
LLVMValueRef val = llvm_zext_trunc(c, llvm_load(c, c->byte_type, ref, 1, ""), llvm_get_type(c, type_cint));
|
||||
total = total ? LLVMBuildAdd(c->builder, total, val, "") : val;
|
||||
}
|
||||
LLVMValueRef val = LLVMBuildICmp(c->builder, expr->int_to_bool_expr.negate ? LLVMIntEQ : LLVMIntNE, total, llvm_get_zero(c, type_cint), "");
|
||||
llvm_value_set(value, val, expr->type);
|
||||
return;
|
||||
}
|
||||
llvm_value_rvalue(c, value);
|
||||
llvm_value_set(value,
|
||||
expr->int_to_bool_expr.negate
|
||||
@@ -7224,6 +7193,24 @@ void llvm_emit_slice_to_vec_array(GenContext *c, BEValue *value, Expr *expr)
|
||||
llvm_value_set_address(value, temp, to_type, alignment);
|
||||
}
|
||||
|
||||
static inline void llvm_emit_make_slice(GenContext *c, BEValue *value, Expr *expr)
|
||||
{
|
||||
ArraySize size = expr->make_slice_expr.len;
|
||||
LLVMValueRef pointer;
|
||||
if (size)
|
||||
{
|
||||
llvm_emit_expr(c, value, expr->make_slice_expr.ptr);
|
||||
llvm_value_rvalue(c, value);
|
||||
pointer = value->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!expr->make_slice_expr.ptr);
|
||||
pointer = llvm_get_zero(c, type_voidptr);
|
||||
}
|
||||
llvm_value_aggregate_two(c, value, expr->type, pointer, llvm_const_int(c, type_usz, size));
|
||||
}
|
||||
|
||||
void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
{
|
||||
EMIT_EXPR_LOC(c, expr);
|
||||
@@ -7251,6 +7238,9 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
case EXPR_SCALAR_TO_VECTOR:
|
||||
llvm_emit_scalar_to_vector(c, value, expr);
|
||||
return;
|
||||
case EXPR_MAKE_SLICE:
|
||||
llvm_emit_make_slice(c, value, expr);
|
||||
return;
|
||||
case EXPR_ENUM_FROM_ORD:
|
||||
llvm_emit_enum_from_ord(c, value, expr);
|
||||
return;
|
||||
@@ -7307,6 +7297,12 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
llvm_value_rvalue(c, value);
|
||||
value->type = type_lowering(expr->type);
|
||||
return;
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
REMINDER("Improve anyfault -> fault");
|
||||
llvm_emit_expr(c, value, expr->inner_expr);
|
||||
llvm_value_rvalue(c, value);
|
||||
value->type = type_lowering(expr->type);
|
||||
return;
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
llvm_emit_vector_from_array(c, value, expr);
|
||||
return;
|
||||
@@ -7446,14 +7442,7 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
llvm_emit_expression_list_expr(c, value, expr);
|
||||
return;
|
||||
case EXPR_CAST:
|
||||
llvm_emit_exprid(c, value, expr->cast_expr.expr);
|
||||
llvm_emit_cast(c,
|
||||
expr->cast_expr.kind,
|
||||
expr,
|
||||
value,
|
||||
expr->type,
|
||||
exprtype(expr->cast_expr.expr));
|
||||
return;
|
||||
UNREACHABLE
|
||||
case EXPR_BITACCESS:
|
||||
llvm_emit_bitaccess(c, value, expr);
|
||||
return;
|
||||
|
||||
@@ -544,7 +544,6 @@ void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref,
|
||||
|
||||
LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl);
|
||||
LLVMValueRef llvm_emit_call_intrinsic(GenContext *c, unsigned intrinsic, LLVMTypeRef *types, unsigned type_count, LLVMValueRef *values, unsigned arg_count);
|
||||
void llvm_emit_cast(GenContext *c, CastKind cast_kind, Expr *expr, BEValue *value, Type *to_type, Type *from_type);
|
||||
void llvm_emit_bool_cast(GenContext *c, Expr *expr, BEValue *value);
|
||||
void llvm_emit_local_var_alloca(GenContext *c, Decl *decl);
|
||||
void llvm_emit_local_decl(GenContext *c, Decl *decl, BEValue *value);
|
||||
|
||||
@@ -25,10 +25,8 @@ typedef struct
|
||||
static bool sema_error_const_int_out_of_range(CastContext *cc, Expr *expr, Expr *problem, Type *to_type);
|
||||
static Expr *recursive_may_narrow(Expr *expr, Type *type);
|
||||
static void expr_recursively_rewrite_untyped_list(Expr *expr, Expr **list);
|
||||
static inline bool insert_runtime_cast(Expr *expr, CastKind kind, Type *type);
|
||||
static void vector_const_initializer_convert_to_type(SemaContext *context, ConstInitializer *initializer, Type *to_type);
|
||||
static bool cast_is_allowed(CastContext *cc, bool is_explicit, bool is_silent);
|
||||
INLINE bool insert_runtime_cast_unless_const(Expr *expr, CastKind kind, Type *type);
|
||||
|
||||
static bool cast_if_valid(SemaContext *context, Expr *expr, Type *to_type, bool is_explicit, bool is_silent,
|
||||
bool is_binary_conversion);
|
||||
@@ -452,12 +450,7 @@ RETRY:
|
||||
expr = expr->ext_trunc_expr.inner;
|
||||
goto RETRY;
|
||||
case EXPR_CAST:
|
||||
switch (expr->cast_expr.kind)
|
||||
{
|
||||
default:
|
||||
// For all other casts we regard them as opaque.
|
||||
goto CHECK_SIZE;
|
||||
}
|
||||
UNREACHABLE
|
||||
case EXPR_CONST:
|
||||
// For constants, just check that they will fit.
|
||||
if (type_is_integer(type))
|
||||
@@ -1397,23 +1390,20 @@ static bool rule_bits_to_int(CastContext *cc, bool is_explicit, bool is_silent)
|
||||
|
||||
// CASTS ----
|
||||
|
||||
/**
|
||||
* Insert a cast. This will assume that the cast is valid. No typeinfo will be registered.
|
||||
*/
|
||||
static inline bool insert_runtime_cast(Expr *expr, CastKind kind, Type *type)
|
||||
|
||||
static void cast_vaptr_to_slice(SemaContext *context, Expr *expr, Type *type)
|
||||
{
|
||||
ASSERT0(expr->resolve_status == RESOLVE_DONE);
|
||||
ASSERT0(expr->type);
|
||||
Type *flat = type_flatten(expr->type);
|
||||
ASSERT0(flat->type_kind == TYPE_POINTER);
|
||||
flat = flat->pointer;
|
||||
ASSERT0(flat->array.len > 0);
|
||||
Expr *inner = expr_copy(expr);
|
||||
expr->expr_kind = EXPR_CAST;
|
||||
expr->cast_expr.kind = kind;
|
||||
expr->cast_expr.expr = exprid(inner);
|
||||
expr->cast_expr.type_info = 0;
|
||||
expr->make_slice_expr = (ExprMakeSlice) {.ptr = inner, .len = flat->array.len};
|
||||
expr->expr_kind = EXPR_MAKE_SLICE;
|
||||
expr->resolve_status = RESOLVE_DONE;
|
||||
expr->type = type;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void cast_vaptr_to_slice(SemaContext *context, Expr *expr, Type *type) { insert_runtime_cast(expr, CAST_APTSA, type); }
|
||||
static void cast_ptr_to_any(SemaContext *context, Expr *expr, Type *type)
|
||||
{
|
||||
Expr *inner = expr_copy(expr);
|
||||
@@ -1437,15 +1427,6 @@ static void cast_any_to_ptr(SemaContext *context, Expr *expr, Type *type) { expr
|
||||
static void cast_all_to_void(SemaContext *context, Expr *expr, Type *to_type) { expr_rewrite_discard(expr); }
|
||||
static void cast_retype(SemaContext *context, Expr *expr, Type *to_type) { expr->type = to_type; }
|
||||
|
||||
/**
|
||||
* Insert a cast on non-const only
|
||||
*/
|
||||
INLINE bool insert_runtime_cast_unless_const(Expr *expr, CastKind kind, Type *type)
|
||||
{
|
||||
if (sema_cast_const(expr) && expr->const_expr.const_kind != CONST_TYPEID) return false;
|
||||
return insert_runtime_cast(expr, kind, type);
|
||||
}
|
||||
|
||||
static void vector_const_initializer_convert_to_type(SemaContext *context, ConstInitializer *initializer, Type *to_type)
|
||||
{
|
||||
switch (initializer->kind)
|
||||
@@ -1635,36 +1616,8 @@ static void cast_int_arr_to_bitstruct(SemaContext *context, Expr *expr, Type *ty
|
||||
|
||||
static void cast_bitstruct_to_bool(SemaContext *context, Expr *expr, Type *type)
|
||||
{
|
||||
if (expr_is_const(expr))
|
||||
{
|
||||
if (!expr_is_const_initializer(expr) || expr->const_expr.initializer->kind == CONST_INIT_ZERO)
|
||||
{
|
||||
expr_rewrite_const_bool(expr, type, false);
|
||||
return;
|
||||
}
|
||||
ASSERT0(expr->const_expr.initializer->kind == CONST_INIT_STRUCT);
|
||||
FOREACH(ConstInitializer *, in, expr->const_expr.initializer->init_struct)
|
||||
{
|
||||
if (in->kind == CONST_INIT_ZERO) continue;
|
||||
Expr *e = in->init_value;
|
||||
if (expr_is_const_bool(e))
|
||||
{
|
||||
if (!e->const_expr.b) continue;
|
||||
expr_rewrite_const_bool(expr, type, true);
|
||||
return;
|
||||
}
|
||||
if (expr_is_const_int(e))
|
||||
{
|
||||
if (int_is_zero(e->const_expr.ixx)) continue;
|
||||
expr_rewrite_const_bool(expr, type, true);
|
||||
return;
|
||||
}
|
||||
UNREACHABLE
|
||||
}
|
||||
expr_rewrite_const_bool(expr, type, false);
|
||||
return;
|
||||
}
|
||||
insert_runtime_cast(expr, CAST_BSBOOL, type);
|
||||
expr_rewrite_int_to_bool(expr, false);
|
||||
expr->type = type;
|
||||
}
|
||||
|
||||
|
||||
@@ -1849,7 +1802,15 @@ static void cast_untyped_list_to_other(SemaContext *context, Expr *expr, Type *t
|
||||
|
||||
static void cast_anyfault_to_fault(SemaContext *context, Expr *expr, Type *type)
|
||||
{
|
||||
if (insert_runtime_cast_unless_const(expr, CAST_EUER, type) || !expr_is_const_fault(expr)) return;
|
||||
if (!sema_cast_const(expr))
|
||||
{
|
||||
expr->inner_expr = expr_copy(expr);
|
||||
expr->expr_kind = EXPR_ANYFAULT_TO_FAULT;
|
||||
expr->type = type;
|
||||
expr->resolve_status = RESOLVE_DONE;
|
||||
return;
|
||||
}
|
||||
assert(expr_is_const_fault(expr));
|
||||
Decl *value = expr->const_expr.enum_err_val;
|
||||
ASSERT0(value->type != type);
|
||||
expr->type = type;
|
||||
@@ -2072,13 +2033,6 @@ static void cast_slice_to_vecarr(SemaContext *context, Expr *expr, Type *to_type
|
||||
{
|
||||
switch (expr->expr_kind)
|
||||
{
|
||||
case EXPR_CAST:
|
||||
{
|
||||
Expr *inner = exprptr(expr->cast_expr.expr)->unary_expr.expr;
|
||||
expr_replace(expr, inner);
|
||||
cast_no_check(context, expr, to_type, false);
|
||||
return;
|
||||
}
|
||||
case EXPR_SLICE:
|
||||
{
|
||||
expr->inner_expr = expr_copy(expr);
|
||||
@@ -2090,8 +2044,6 @@ static void cast_slice_to_vecarr(SemaContext *context, Expr *expr, Type *to_type
|
||||
default:
|
||||
UNREACHABLE;
|
||||
}
|
||||
ASSERT0(expr->expr_kind == EXPR_CAST);
|
||||
return;
|
||||
}
|
||||
if (expr_is_const_slice(expr))
|
||||
{
|
||||
|
||||
@@ -17,13 +17,8 @@ ArrayIndex sema_len_from_const(Expr *expr)
|
||||
{
|
||||
return range_const_len(&expr->slice_expr.range);
|
||||
}
|
||||
if (expr->expr_kind != EXPR_CAST) return -1;
|
||||
if (expr->cast_expr.kind != CAST_APTSA) return -1;
|
||||
Expr *inner = exprptr(expr->cast_expr.expr);
|
||||
if (inner->expr_kind != EXPR_UNARY || inner->unary_expr.operator != UNARYOP_ADDR) return -1;
|
||||
inner = inner->unary_expr.expr;
|
||||
if (!sema_cast_const(inner)) return -1;
|
||||
expr = inner;
|
||||
if (expr->expr_kind != EXPR_MAKE_SLICE) return -1;
|
||||
return expr->make_slice_expr.len;
|
||||
}
|
||||
ConstInitializer *init;
|
||||
switch (expr->const_expr.const_kind)
|
||||
|
||||
@@ -551,6 +551,7 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp
|
||||
case EXPR_MACRO_BODY:
|
||||
case EXPR_MACRO_BODY_EXPANSION:
|
||||
case EXPR_MAKE_ANY:
|
||||
case EXPR_MAKE_SLICE:
|
||||
case EXPR_MEMBER_GET:
|
||||
case EXPR_NAMED_ARGUMENT:
|
||||
case EXPR_NOP:
|
||||
@@ -582,6 +583,7 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp
|
||||
case EXPR_TYPEID_INFO:
|
||||
case EXPR_TYPEINFO:
|
||||
case EXPR_VASPLAT:
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
case EXPR_VECTOR_TO_ARRAY:
|
||||
case EXPR_SLICE_TO_VEC_ARRAY:
|
||||
@@ -624,11 +626,13 @@ static bool expr_may_ref(Expr *expr)
|
||||
case EXPR_PTR_TO_INT:
|
||||
case EXPR_SLICE_LEN:
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
case EXPR_INT_TO_BOOL:
|
||||
case EXPR_RVALUE:
|
||||
case EXPR_RECAST:
|
||||
case EXPR_DISCARD:
|
||||
case EXPR_ADDR_CONVERSION:
|
||||
case EXPR_MAKE_SLICE:
|
||||
return false;
|
||||
case EXPR_OTHER_CONTEXT:
|
||||
return expr_may_ref(expr->expr_other_context.inner);
|
||||
@@ -9003,6 +9007,7 @@ static inline bool sema_expr_analyse_ct_defined(SemaContext *context, Expr *expr
|
||||
case EXPR_PTR_ACCESS:
|
||||
case EXPR_ENUM_FROM_ORD:
|
||||
case EXPR_SLICE_LEN:
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
case EXPR_RVALUE:
|
||||
case EXPR_RECAST:
|
||||
@@ -9013,6 +9018,7 @@ static inline bool sema_expr_analyse_ct_defined(SemaContext *context, Expr *expr
|
||||
case EXPR_INT_TO_FLOAT:
|
||||
case EXPR_INT_TO_PTR:
|
||||
case EXPR_PTR_TO_INT:
|
||||
case EXPR_MAKE_SLICE:
|
||||
if (!sema_analyse_expr(active_context, main_expr)) goto FAIL;
|
||||
break;
|
||||
}
|
||||
@@ -9402,6 +9408,7 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr,
|
||||
case EXPR_VECTOR_TO_ARRAY:
|
||||
case EXPR_SLICE_TO_VEC_ARRAY:
|
||||
case EXPR_SCALAR_TO_VECTOR:
|
||||
case EXPR_MAKE_SLICE:
|
||||
UNREACHABLE
|
||||
case EXPR_MAKE_ANY:
|
||||
if (!sema_analyse_expr(context, expr->make_any_expr.typeid)) return false;
|
||||
@@ -9413,6 +9420,7 @@ static inline bool sema_analyse_expr_dispatch(SemaContext *context, Expr *expr,
|
||||
return sema_analyse_expr(context, expr->inner_expr);
|
||||
case EXPR_PTR_ACCESS:
|
||||
case EXPR_SLICE_LEN:
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
return sema_analyse_expr(context, expr->inner_expr);
|
||||
case EXPR_INT_TO_BOOL:
|
||||
|
||||
@@ -886,6 +886,47 @@ void const_init_rewrite_to_value(ConstInitializer *const_init, Expr *value)
|
||||
const_init->kind = CONST_INIT_VALUE;
|
||||
}
|
||||
|
||||
bool const_init_is_zero(ConstInitializer *init)
|
||||
{
|
||||
RETRY:
|
||||
switch (init->kind)
|
||||
{
|
||||
case CONST_INIT_ZERO:
|
||||
return true;
|
||||
case CONST_INIT_STRUCT:
|
||||
{
|
||||
FOREACH(ConstInitializer *, i, init->init_struct)
|
||||
{
|
||||
if (!const_init_is_zero(i)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case CONST_INIT_UNION:
|
||||
init = init->init_union.element;
|
||||
goto RETRY;
|
||||
case CONST_INIT_VALUE:
|
||||
return expr_is_zero(init->init_value);
|
||||
case CONST_INIT_ARRAY:
|
||||
{
|
||||
FOREACH(ConstInitializer *, i, init->init_array.elements)
|
||||
{
|
||||
if (!const_init_is_zero(i)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case CONST_INIT_ARRAY_FULL:
|
||||
{
|
||||
FOREACH(ConstInitializer *, i, init->init_array_full)
|
||||
{
|
||||
if (!const_init_is_zero(i)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case CONST_INIT_ARRAY_VALUE:
|
||||
return const_init_is_zero(init->init_array_value.element);
|
||||
}
|
||||
UNREACHABLE
|
||||
}
|
||||
ConstInitializer *const_init_new_value(Expr *value)
|
||||
{
|
||||
ConstInitializer *init = CALLOCS(ConstInitializer);
|
||||
|
||||
@@ -271,6 +271,9 @@ RETRY:
|
||||
return;
|
||||
case EXPR_BUILTIN:
|
||||
return;
|
||||
case EXPR_MAKE_SLICE:
|
||||
expr = expr->make_slice_expr.ptr;
|
||||
goto RETRY;
|
||||
case EXPR_MAKE_ANY:
|
||||
sema_trace_expr_liveness(expr->make_any_expr.typeid);
|
||||
expr = expr->make_any_expr.inner;
|
||||
@@ -339,6 +342,7 @@ RETRY:
|
||||
case EXPR_INT_TO_PTR:
|
||||
case EXPR_PTR_TO_INT:
|
||||
case EXPR_SLICE_LEN:
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
case EXPR_RVALUE:
|
||||
case EXPR_RECAST:
|
||||
|
||||
@@ -285,6 +285,9 @@ static inline Expr *sema_dive_into_expression(Expr *expr)
|
||||
case EXPR_RECAST:
|
||||
expr = expr->inner_expr;
|
||||
continue;
|
||||
case EXPR_MAKE_SLICE:
|
||||
expr = expr->make_slice_expr.ptr;
|
||||
continue;
|
||||
case EXPR_MAKE_ANY:
|
||||
expr = expr->make_any_expr.inner;
|
||||
continue;
|
||||
@@ -766,6 +769,7 @@ static inline bool sema_expr_valid_try_expression(Expr *expr)
|
||||
case EXPR_INT_TO_BOOL:
|
||||
case EXPR_VECTOR_TO_ARRAY:
|
||||
case EXPR_SLICE_TO_VEC_ARRAY:
|
||||
case EXPR_MAKE_SLICE:
|
||||
case EXPR_SCALAR_TO_VECTOR:
|
||||
case EXPR_PTR_ACCESS:
|
||||
case EXPR_FLOAT_TO_INT:
|
||||
@@ -773,6 +777,7 @@ static inline bool sema_expr_valid_try_expression(Expr *expr)
|
||||
case EXPR_INT_TO_PTR:
|
||||
case EXPR_PTR_TO_INT:
|
||||
case EXPR_SLICE_LEN:
|
||||
case EXPR_ANYFAULT_TO_FAULT:
|
||||
case EXPR_VECTOR_FROM_ARRAY:
|
||||
case EXPR_RVALUE:
|
||||
case EXPR_RECAST:
|
||||
|
||||
@@ -37,8 +37,8 @@ fn void main()
|
||||
%1 = load i32, ptr %a, align 4
|
||||
%2 = load i32, ptr %b, align 4
|
||||
%and = and i32 %1, %2
|
||||
%neq = icmp ne i32 %and, 0
|
||||
br i1 %neq, label %if.then, label %if.exit
|
||||
%i2b = icmp ne i32 %and, 0
|
||||
br i1 %i2b, label %if.then, label %if.exit
|
||||
|
||||
if.then: ; preds = %entry
|
||||
ret void
|
||||
@@ -56,9 +56,8 @@ if.exit: ; preds = %entry
|
||||
%6 = load i8, ptr %ptradd, align 1
|
||||
%zext2 = zext i8 %6 to i32
|
||||
%7 = add i32 %zext, %zext2
|
||||
%8 = icmp ne i32 %7, 0
|
||||
%not = xor i1 %8, true
|
||||
br i1 %not, label %if.then3, label %if.exit4
|
||||
%8 = icmp eq i32 %7, 0
|
||||
br i1 %8, label %if.then3, label %if.exit4
|
||||
|
||||
if.then3: ; preds = %if.exit
|
||||
ret void
|
||||
|
||||
Reference in New Issue
Block a user