diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 2f475b91e..bdf4f486f 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -1027,7 +1027,6 @@ typedef struct const char *identifier; bool is_ref : 1; bool is_rvalue : 1; - Decl *decl; } ExprIdentifierRaw; typedef struct @@ -4600,6 +4599,34 @@ INLINE bool expr_is_const_float(Expr *expr) return expr->expr_kind == EXPR_CONST && expr->const_expr.const_kind == CONST_FLOAT; } +INLINE bool expr_is_ct_ident(Expr *expr) +{ + ASSERT(expr->resolve_status == RESOLVE_DONE); + if (expr->expr_kind != EXPR_IDENTIFIER) return false; + Decl *decl = expr->ident_expr; + if (decl->decl_kind != DECL_VAR) return false; + switch (decl->var.kind) + { + case VARDECL_CONST: + case VARDECL_GLOBAL: + case VARDECL_LOCAL: + case VARDECL_PARAM: + case VARDECL_MEMBER: + case VARDECL_BITMEMBER: + case VARDECL_PARAM_EXPR: + case VARDECL_UNWRAPPED: + case VARDECL_ERASE: + case VARDECL_REWRAPPED: + return false; + case VARDECL_PARAM_CT: + case VARDECL_PARAM_CT_TYPE: + case VARDECL_LOCAL_CT: + case VARDECL_LOCAL_CT_TYPE: + return true; + } + UNREACHABLE; +} + INLINE bool expr_is_const_typeid(Expr *expr) { ASSERT(expr->resolve_status == RESOLVE_DONE); diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 9d8cb366d..82573b066 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -1791,7 +1791,7 @@ typedef enum #define NON_RUNTIME_EXPR EXPR_POISONED: \ case EXPR_CT_DEFINED: \ case EXPR_CT_ASSIGNABLE: case EXPR_CT_IS_CONST: \ - case EXPR_CT_ARG: case EXPR_TYPEINFO: case EXPR_CT_IDENT: case EXPR_HASH_IDENT: \ + case EXPR_CT_ARG: case EXPR_TYPEINFO: case EXPR_HASH_IDENT: \ case EXPR_COMPILER_CONST: case EXPR_CT_CALL: \ case EXPR_SPLAT: case EXPR_STRINGIFY: case EXPR_TYPECALL: \ case EXPR_CT_EVAL: case EXPR_MAYBE_DEREF @@ -1842,5 +1842,5 @@ case TYPE_U8: case TYPE_U16: case TYPE_U32: case TYPE_U64: case TYPE_U128 #define UNRESOLVED_EXPRS EXPR_TRY_UNRESOLVED: case EXPR_ACCESS_UNRESOLVED: \ case EXPR_CATCH_UNRESOLVED: case EXPR_UNRESOLVED_IDENTIFIER: case EXPR_CAST: \ case EXPR_TYPEID: case EXPR_EMBED: case EXPR_VASPLAT: case EXPR_OTHER_CONTEXT: \ - case EXPR_IOTA_DECL: case EXPR_LENGTHOF: \ + case EXPR_IOTA_DECL: case EXPR_LENGTHOF: case EXPR_CT_IDENT: \ case EXPR_GENERIC_IDENT: case EXPR_COMPOUND_LITERAL: case EXPR_MACRO_BODY: case EXPR_CT_SUBSCRIPT diff --git a/src/compiler/expr.c b/src/compiler/expr.c index 000355f18..55f6d347b 100644 --- a/src/compiler/expr.c +++ b/src/compiler/expr.c @@ -200,8 +200,6 @@ bool expr_may_addr(Expr *expr) decl = decl_raw(decl); switch (decl->var.kind) { - case VARDECL_LOCAL_CT: - case VARDECL_LOCAL_CT_TYPE: case VARDECL_LOCAL: case VARDECL_GLOBAL: case VARDECL_PARAM: @@ -211,6 +209,8 @@ bool expr_may_addr(Expr *expr) case VARDECL_BITMEMBER: case VARDECL_PARAM_CT: case VARDECL_PARAM_CT_TYPE: + case VARDECL_LOCAL_CT: + case VARDECL_LOCAL_CT_TYPE: case VARDECL_PARAM_EXPR: return false; case VARDECL_UNWRAPPED: @@ -485,7 +485,6 @@ bool expr_is_runtime_const(Expr *expr) case EXPR_CT_CALL: case EXPR_TYPEINFO: case EXPR_HASH_IDENT: - case EXPR_CT_IDENT: case EXPR_POISONED: case EXPR_CT_ARG: case EXPR_ASM: @@ -846,7 +845,6 @@ bool expr_is_pure(Expr *expr) case EXPR_CT_DEFINED: case EXPR_CT_IS_CONST: case EXPR_CT_EVAL: - case EXPR_CT_IDENT: case EXPR_IDENTIFIER: case EXPR_LAMBDA: case EXPR_NOP: diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index a5e46ede9..072f1e4b3 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -645,8 +645,6 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp case EXPR_LAMBDA: if (failed_ref) goto FAILED_REF; RETURN_SEMA_ERROR(expr, "This expression is a value and cannot be assigned to."); - case EXPR_CT_IDENT: - return true; case EXPR_EXT_TRUNC: case EXPR_INT_TO_BOOL: case EXPR_DISCARD: @@ -799,7 +797,6 @@ static bool expr_may_ref(Expr *expr) { case EXPR_SWIZZLE: case EXPR_LAMBDA: - case EXPR_CT_IDENT: case EXPR_DEFAULT_ARG: case EXPR_TYPECALL: case EXPR_MEMBER_GET: @@ -835,18 +832,18 @@ static bool expr_may_ref(Expr *expr) decl = decl_raw(decl); switch (decl->var.kind) { - case VARDECL_LOCAL_CT: - case VARDECL_LOCAL_CT_TYPE: case VARDECL_LOCAL: case VARDECL_GLOBAL: case VARDECL_PARAM: - case VARDECL_PARAM_CT: - case VARDECL_PARAM_CT_TYPE: return true; case VARDECL_CONST: case VARDECL_PARAM_EXPR: case VARDECL_MEMBER: case VARDECL_BITMEMBER: + case VARDECL_LOCAL_CT: + case VARDECL_LOCAL_CT_TYPE: + case VARDECL_PARAM_CT: + case VARDECL_PARAM_CT_TYPE: return false; case VARDECL_UNWRAPPED: case VARDECL_ERASE: @@ -1035,15 +1032,14 @@ static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr) } return true; case VARDECL_PARAM_EXPR: + case VARDECL_ERASE: + case VARDECL_REWRAPPED: UNREACHABLE case VARDECL_PARAM_CT_TYPE: case VARDECL_PARAM_CT: case VARDECL_LOCAL_CT: case VARDECL_LOCAL_CT_TYPE: - case VARDECL_ERASE: - case VARDECL_REWRAPPED: - // Impossible to reach this, they are already unfolded - UNREACHABLE + return sema_cast_ct_ident_rvalue(context, expr); case VARDECL_LOCAL: if (decl->var.copy_const && decl->var.init_expr && expr_is_const(decl->var.init_expr)) { @@ -1393,9 +1389,9 @@ static inline bool sema_expr_resolve_ct_identifier(SemaContext *context, Expr *e ASSERT_SPAN(expr, decl->resolve_status == RESOLVE_DONE); decl->var.is_read = true; - expr->ct_ident_expr.decl = decl; expr->type = decl->type; - + expr->ident_expr = decl; + expr->expr_kind = EXPR_IDENTIFIER; return true; } @@ -4095,7 +4091,7 @@ static inline bool sema_expr_resolve_subscript_index(SemaContext *context, Expr } ArrayIndex size; bool check_len = !context->call_env.in_no_eval || current_type == type_untypedlist; - Expr *len_expr = current_expr->expr_kind == EXPR_CT_IDENT ? current_expr->ct_ident_expr.decl->var.init_expr : current_expr; + Expr *len_expr = expr_is_ct_ident(current_expr) ? current_expr->ident_expr->var.init_expr : current_expr; if (sema_cast_const(index) && expr_is_const_int(index) && (size = sema_len_from_expr(len_expr)) >= 0) { // 4c. And that it's in range. @@ -4219,7 +4215,7 @@ DEFAULT: } // 4. If we are indexing into a complist - if (current_expr->expr_kind == EXPR_CT_IDENT) + if (expr_is_ct_ident(current_expr)) { if (index_value == -1) { @@ -4227,7 +4223,7 @@ DEFAULT: RETURN_SEMA_ERROR(index, "Assigning to a compile time constant requires a constant index."); } expr->expr_kind = EXPR_CT_SUBSCRIPT; - expr->ct_subscript_expr = (ExprCtSubscript) { .var = current_expr->ct_ident_expr.decl, .index = (ArrayIndex)index_value }; + expr->ct_subscript_expr = (ExprCtSubscript) { .var = current_expr->ident_expr, .index = (ArrayIndex)index_value }; expr->type = NULL; return true; } @@ -4327,7 +4323,7 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr, RETURN_SEMA_ERROR(subscripted, "You need to use && to take the address of a temporary."); } // 4a. This may either be an initializer list or a CT value - while (current_expr->expr_kind == EXPR_CT_IDENT) current_expr = current_expr->ct_ident_expr.decl->var.init_expr; + while (expr_is_ct_ident(current_expr)) current_expr = current_expr->ident_expr->var.init_expr; // 4b. Now we need to check that we actually have a valid type. if (index_value < 0) @@ -7085,7 +7081,7 @@ static bool sema_expr_analyse_ct_identifier_assign(SemaContext *context, Expr *e if (failed_ref) return *failed_ref = true, false; RETURN_SEMA_ERROR(right, "You can only assign constants to a compile time variable."); } - Decl *ident = left->ct_ident_expr.decl; + Decl *ident = left->ident_expr; ident->var.init_expr = right; expr_replace(expr, right); @@ -7194,7 +7190,8 @@ static bool sema_expr_analyse_assign(SemaContext *context, Expr *expr, Expr *lef if (!sema_analyse_expr_lvalue(context, left, failed_ref)) return false; switch (left->expr_kind) { - case EXPR_CT_IDENT: + case EXPR_IDENTIFIER: + if (!expr_is_ct_ident(left)) break; // $foo = ... return sema_expr_analyse_ct_identifier_assign(context, expr, left, right, failed_ref); case EXPR_CT_SUBSCRIPT: @@ -7258,9 +7255,9 @@ static bool sema_expr_analyse_assign(SemaContext *context, Expr *expr, Expr *lef */ static bool sema_binary_analyse_ct_op_assign(SemaContext *context, Expr *expr, Expr *left) { - ASSERT_SPAN(left, left->expr_kind == EXPR_CT_IDENT); + ASSERT_SPAN(left, expr_is_ct_ident(left)); - Decl *left_var = left->ct_ident_expr.decl; + Decl *left_var = left->ident_expr; if (!sema_cast_ct_ident_rvalue(context, left)) return false; expr->binary_expr.operator = binaryop_assign_base_op(expr->binary_expr.operator); @@ -7508,7 +7505,8 @@ static bool sema_expr_analyse_op_assign(SemaContext *context, Expr *expr, Expr * switch (left->expr_kind) { - case EXPR_CT_IDENT: + case EXPR_IDENTIFIER: + if (!expr_is_ct_ident(left)) break; return sema_binary_analyse_ct_op_assign(context, expr, left); case EXPR_CT_SUBSCRIPT: return sema_binary_analyse_ct_subscript_op_assign(context, expr, left); @@ -9037,8 +9035,7 @@ static inline const char *sema_addr_may_take_of_var(Expr *expr, Decl *decl) case VARDECL_PARAM_CT_TYPE: case VARDECL_LOCAL_CT_TYPE: case VARDECL_LOCAL_CT: - // May not be reached due to EXPR_CT_IDENT being handled elsewhere. - UNREACHABLE + return "It's not possible to take the address of a compile time value."; case VARDECL_MEMBER: case VARDECL_BITMEMBER: case VARDECL_UNWRAPPED: @@ -9086,8 +9083,6 @@ static const char *sema_addr_check_may_take(Expr *inner) { case UNRESOLVED_EXPRS: UNREACHABLE - case EXPR_CT_IDENT: - return "It's not possible to take the address of a compile time value."; case EXPR_IDENTIFIER: return sema_addr_may_take_of_ident(inner); case EXPR_UNARY: @@ -9159,17 +9154,21 @@ RETRY:; case EXPR_ACCESS_UNRESOLVED: inner->access_unresolved_expr.is_ref = true; break; + case EXPR_CT_IDENT: + RETURN_SEMA_ERROR(expr, "It's not possible to take the address of a compile time value."); default: break; } -RESOLVED: - if (inner->expr_kind == EXPR_CT_IDENT) + + if (!sema_analyse_expr(context, inner)) return false; + + RESOLVED: + + if (expr_is_ct_ident(inner)) { RETURN_SEMA_ERROR(expr, "It's not possible to take the address of a compile time value."); } - if (!sema_analyse_expr(context, inner)) return false; - // 2. Take the address. const char *error = sema_addr_check_may_take(inner); if (error) @@ -9439,9 +9438,9 @@ static inline bool sema_expr_analyse_ct_subscript_incdec(SemaContext *context, E static inline bool sema_expr_analyse_ct_incdec(SemaContext *context, Expr *expr, Expr *inner) { - ASSERT_SPAN(expr, inner->expr_kind == EXPR_CT_IDENT); + ASSERT_SPAN(expr, expr_is_ct_ident(inner)); - Decl *var = inner->ct_ident_expr.decl; + Decl *var = inner->ident_expr; Expr *start_value = var->var.init_expr; if (!expr_is_const_int(start_value)) { @@ -9565,7 +9564,7 @@ static inline bool sema_expr_analyse_incdec(SemaContext *context, Expr *expr) if (!sema_expr_check_assign(context, inner, NULL)) return false; // 3. This might be a $foo, if to handle it. - if (inner->expr_kind == EXPR_CT_IDENT) + if (expr_is_ct_ident(inner)) { return sema_expr_analyse_ct_incdec(context, expr, inner); } @@ -12079,7 +12078,7 @@ NO_MATCH_REF: static inline bool sema_cast_ct_ident_rvalue(SemaContext *context, Expr *expr) { - Decl *decl = expr->ct_ident_expr.decl; + Decl *decl = expr->ident_expr; Expr *copy = copy_expr_single(decl->var.init_expr); if (!copy) { @@ -12137,8 +12136,7 @@ static inline bool sema_cast_rvalue(SemaContext *context, Expr *expr, bool mutat } UNREACHABLE case EXPR_CT_IDENT: - if (mutate && !sema_cast_ct_ident_rvalue(context, expr)) return false; - break; + UNREACHABLE case EXPR_IDENTIFIER: if (mutate && !sema_cast_ident_rvalue(context, expr)) return false; break; diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index e0956e140..afb1eb207 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -798,7 +798,6 @@ static inline bool sema_expr_valid_try_expression(Expr *expr) case EXPR_CT_IS_CONST: case EXPR_CT_DEFINED: case EXPR_CT_EVAL: - case EXPR_CT_IDENT: case EXPR_NAMED_ARGUMENT: UNREACHABLE case EXPR_BINARY: