mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Allow omitting = true for designated initializers of bitstruct bools.
This commit is contained in:
committed by
Christoffer Lerno
parent
0dc2f0e923
commit
41db9c43e5
@@ -441,6 +441,7 @@ param_path
|
||||
|
||||
arg
|
||||
: param_path '=' expr
|
||||
| param_path
|
||||
| type
|
||||
| param_path '=' type
|
||||
| expr
|
||||
|
||||
@@ -211,6 +211,7 @@ bool expr_is_constant_eval(Expr *expr, ConstantEvalKind eval_kind)
|
||||
return expr_list_is_constant_eval(expr->cond_expr, eval_kind);
|
||||
case EXPR_DESIGNATOR:
|
||||
expr = expr->designator_expr.value;
|
||||
if (!expr) return true;
|
||||
goto RETRY;
|
||||
case EXPR_EXPR_BLOCK:
|
||||
case EXPR_DECL:
|
||||
|
||||
@@ -465,7 +465,7 @@ Expr *parse_vasplat(ParseContext *c)
|
||||
/**
|
||||
* param_list ::= ('...' arg | arg (',' arg)*)?
|
||||
*
|
||||
* parameter ::= (param_path '=')? expr
|
||||
* parameter ::= ((param_path '=')? expr) | param_path
|
||||
*/
|
||||
bool parse_arg_list(ParseContext *c, Expr ***result, TokenType param_end, bool *splat, bool vasplat)
|
||||
{
|
||||
@@ -483,11 +483,9 @@ bool parse_arg_list(ParseContext *c, Expr ***result, TokenType param_end, bool *
|
||||
expr = expr_new(EXPR_DESIGNATOR, start_span);
|
||||
expr->designator_expr.path = path;
|
||||
|
||||
// Expect the '=' after.
|
||||
CONSUME_OR_RET(TOKEN_EQ, false);
|
||||
|
||||
// Now parse the rest
|
||||
ASSIGN_EXPR_OR_RET(expr->designator_expr.value, parse_expr(c), false);
|
||||
if (try_consume(c, TOKEN_EQ)) {
|
||||
ASSIGN_EXPR_OR_RET(expr->designator_expr.value, parse_expr(c), false);
|
||||
}
|
||||
|
||||
RANGE_EXTEND_PREV(expr);
|
||||
}
|
||||
|
||||
@@ -1331,6 +1331,10 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
|
||||
}
|
||||
|
||||
// 8g. Set the parameter
|
||||
if (!arg->designator_expr.value)
|
||||
{
|
||||
RETURN_SEMA_ERROR(arg, "Expected a value for this argument.");
|
||||
}
|
||||
actual_args[index] = arg->designator_expr.value;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -406,15 +406,24 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type
|
||||
bool optional = false;
|
||||
Type *inner_type = NULL;
|
||||
bool is_inferred = type_is_inferred(flattened);
|
||||
int bitmember_count_without_value = 0;
|
||||
VECEACH(init_expressions, i)
|
||||
{
|
||||
Expr *expr = init_expressions[i];
|
||||
Decl *member;
|
||||
Type *result = sema_expr_analyse_designator(context, original, expr, &max_index, &member);
|
||||
if (!result) return false;
|
||||
bool is_bitmember = member && member->decl_kind == DECL_VAR && member->var.kind == VARDECL_BITMEMBER;
|
||||
Expr *value = expr->designator_expr.value;
|
||||
if (!value && is_bitmember && member->var.start_bit == member->var.end_bit && type_flatten(result) == type_bool) {
|
||||
assert(is_bitstruct);
|
||||
value = expr_new_const_bool(INVALID_SPAN, type_bool, true);
|
||||
expr->designator_expr.value = value;
|
||||
bitmember_count_without_value += 1;
|
||||
}
|
||||
if (!value) RETURN_SEMA_ERROR(expr, "This initializer needs a value.");
|
||||
if (!sema_analyse_expr_rhs(context, result, value, true, NULL)) return false;
|
||||
if (member && member->decl_kind == DECL_VAR && member->var.kind == VARDECL_BITMEMBER)
|
||||
if (is_bitmember)
|
||||
{
|
||||
if (!sema_bit_assignment_check(context, value, member)) return false;
|
||||
}
|
||||
@@ -426,6 +435,9 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (bitmember_count_without_value != 0 && bitmember_count_without_value != vec_size(init_expressions)) {
|
||||
RETURN_SEMA_ERROR(initializer, "Mixing the omission of initializers is not permitted.");
|
||||
}
|
||||
Type *type;
|
||||
if (!is_structlike && is_inferred)
|
||||
{
|
||||
@@ -522,6 +534,7 @@ static void sema_create_const_initializer_from_designated_init(ConstInitializer
|
||||
Expr *expr = init_expressions[i];
|
||||
DesignatorElement **path = expr->designator_expr.path;
|
||||
Expr *value = expr->designator_expr.value;
|
||||
assert(value);
|
||||
sema_update_const_initializer_with_designator(const_init, path, path + vec_size(path), value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,4 +59,46 @@ fn void test2()
|
||||
fn void test3()
|
||||
{
|
||||
Foo abc = { .x = -4, .z = 0, .y = 8 }; // #error: would be truncated
|
||||
}
|
||||
}
|
||||
|
||||
bitstruct Flags1 : int
|
||||
{
|
||||
bool a;
|
||||
bool b;
|
||||
bool c;
|
||||
}
|
||||
|
||||
distinct Bool = bool;
|
||||
|
||||
bitstruct Flags2 : int
|
||||
{
|
||||
bool a : 0;
|
||||
Bool b : 1;
|
||||
int c : 2..3;
|
||||
bool d : 6;
|
||||
}
|
||||
|
||||
struct Flags2_Struct
|
||||
{
|
||||
bool a;
|
||||
bool b;
|
||||
int c;
|
||||
bool d;
|
||||
}
|
||||
|
||||
fn void test4()
|
||||
{
|
||||
Flags1 flags1 = {.a, .b, .c};
|
||||
flags1 = {.a};
|
||||
flags1 = {.a = true, .b = true, .c = false};
|
||||
flags1 = {.a, .b = true, .c = true}; // #error: Mixing the omission
|
||||
Foo foo = { .x = 0, .z }; // #error: needs a value
|
||||
|
||||
Flags2 flags2 = {.b, .d};
|
||||
flags2 = {.b, .c, .d}; // #error: needs a value
|
||||
flags2 = {.a, .c = 1, .d}; // #error: Mixing the omission
|
||||
|
||||
Flags2_Struct flags2s;
|
||||
flags2s = {.b, .c, .d}; // #error: needs a value
|
||||
flags2s = {.a, .c = 1, .d}; // #error: needs a value
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user