mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Adding min/max/elements to enums.
This commit is contained in:
committed by
Christoffer Lerno
parent
dbb067a005
commit
cf82140a47
@@ -1406,6 +1406,9 @@ extern Type *type_virtual, *type_virtual_generic;
|
||||
extern const char *attribute_list[NUMBER_OF_ATTRIBUTES];
|
||||
|
||||
extern const char *kw_std;
|
||||
extern const char *kw_max;
|
||||
extern const char *kw_min;
|
||||
extern const char *kw_elements;
|
||||
extern const char *kw_align;
|
||||
extern const char *kw_alignof;
|
||||
extern const char *kw_distinct;
|
||||
|
||||
@@ -1783,6 +1783,28 @@ static void add_members_to_context(Context *context, Decl *decl)
|
||||
}
|
||||
}
|
||||
|
||||
static Expr *enum_minmax_value(Decl *decl, BinaryOp comparison)
|
||||
{
|
||||
assert(decl->decl_kind == DECL_ENUM);
|
||||
bool is_signed = type_is_signed(decl->enums.type_info->type->canonical);
|
||||
Expr *expr = NULL;
|
||||
VECEACH(decl->enums.values, i)
|
||||
{
|
||||
Decl *enum_constant = decl->enums.values[i];
|
||||
Expr *candidate = enum_constant->enum_constant.expr;
|
||||
assert(candidate->expr_kind == EXPR_CONST);
|
||||
if (!expr)
|
||||
{
|
||||
expr = candidate;
|
||||
continue;
|
||||
}
|
||||
if (expr_const_compare(&candidate->const_expr, &expr->const_expr, comparison))
|
||||
{
|
||||
expr = candidate;
|
||||
}
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
static inline bool sema_expr_analyse_type_access(Expr *expr, TypeInfo *parent, bool was_group)
|
||||
{
|
||||
if (!was_group && type_kind_is_derived(parent->type->type_kind))
|
||||
@@ -1807,12 +1829,12 @@ static inline bool sema_expr_analyse_type_access(Expr *expr, TypeInfo *parent, b
|
||||
}
|
||||
if (name == kw_sizeof)
|
||||
{
|
||||
expr_rewrite_to_int_const(expr, type_usize, type_size(canonical));
|
||||
expr_rewrite_to_int_const(expr, type_compint, type_size(canonical));
|
||||
return true;
|
||||
}
|
||||
if (name == kw_alignof)
|
||||
{
|
||||
expr_rewrite_to_int_const(expr, type_usize, type_abi_alignment(canonical));
|
||||
expr_rewrite_to_int_const(expr, type_compint, type_abi_alignment(canonical));
|
||||
return true;
|
||||
}
|
||||
if (name == kw_nameof)
|
||||
@@ -1845,30 +1867,37 @@ static inline bool sema_expr_analyse_type_access(Expr *expr, TypeInfo *parent, b
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (name == kw_sizeof)
|
||||
if (name == kw_elements)
|
||||
{
|
||||
expr_rewrite_to_int_const(expr, type_usize, type_size(decl->enums.type_info->type));
|
||||
expr_rewrite_to_int_const(expr, type_compint, vec_size(decl->enums.values));
|
||||
return true;
|
||||
}
|
||||
if (name == kw_alignof)
|
||||
if (name == kw_max)
|
||||
{
|
||||
expr_rewrite_to_int_const(expr, type_usize, type_abi_alignment(decl->enums.type_info->type));
|
||||
Expr *max = enum_minmax_value(decl, BINARYOP_GT);
|
||||
if (!max)
|
||||
{
|
||||
expr_rewrite_to_int_const(expr, decl->enums.type_info->type->canonical, 0);
|
||||
return true;
|
||||
}
|
||||
expr_replace(expr, max);
|
||||
return true;
|
||||
}
|
||||
if (name == kw_min)
|
||||
{
|
||||
Expr *min = enum_minmax_value(decl, BINARYOP_LT);
|
||||
if (!min)
|
||||
{
|
||||
expr_rewrite_to_int_const(expr, decl->enums.type_info->type->canonical, 0);
|
||||
return true;
|
||||
}
|
||||
expr_replace(expr, min);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case DECL_ERR:
|
||||
case DECL_UNION:
|
||||
case DECL_STRUCT:
|
||||
if (name == kw_sizeof)
|
||||
{
|
||||
expr_rewrite_to_int_const(expr, type_usize, type_size(decl->type));
|
||||
return true;
|
||||
}
|
||||
if (name == kw_alignof)
|
||||
{
|
||||
expr_rewrite_to_int_const(expr, type_usize, type_abi_alignment(decl->type));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE
|
||||
|
||||
@@ -36,16 +36,18 @@ static SymTab symtab;
|
||||
|
||||
const char *attribute_list[NUMBER_OF_ATTRIBUTES];
|
||||
|
||||
const char *kw_std;
|
||||
const char *kw_align;
|
||||
const char *kw_alignof;
|
||||
const char *kw_distinct;
|
||||
const char *kw_ensure;
|
||||
const char *kw_elements;
|
||||
const char *kw_errors;
|
||||
const char *kw_inline;
|
||||
const char *kw_kindof;
|
||||
const char *kw_len;
|
||||
const char *kw_main;
|
||||
const char *kw_max;
|
||||
const char *kw_min;
|
||||
const char *kw_nameof;
|
||||
const char *kw_offsetof;
|
||||
const char *kw_ordinal;
|
||||
@@ -55,6 +57,7 @@ const char *kw_qnameof;
|
||||
const char *kw_reqparse;
|
||||
const char *kw_require;
|
||||
const char *kw_sizeof;
|
||||
const char *kw_std;
|
||||
const char *kw___ceil;
|
||||
const char *kw___round;
|
||||
const char *kw___sqrt;
|
||||
@@ -96,12 +99,15 @@ void symtab_init(uint32_t capacity)
|
||||
kw_align = KW_DEF("align");
|
||||
kw_alignof = KW_DEF("alignof");
|
||||
kw_distinct = KW_DEF("distinct");
|
||||
kw_elements = KW_DEF("elements");
|
||||
kw_ensure = KW_DEF("ensure");
|
||||
kw_errors = KW_DEF("errors");
|
||||
kw_inline = KW_DEF("inline");
|
||||
kw_kindof = KW_DEF("kindof");
|
||||
kw_len = KW_DEF("len");
|
||||
kw_main = KW_DEF("main");
|
||||
kw_max = KW_DEF("max");
|
||||
kw_min = KW_DEF("min");
|
||||
kw_nameof = KW_DEF("nameof");
|
||||
kw_offsetof = KW_DEF("offsetof");
|
||||
kw_ordinal = KW_DEF("ordinal");
|
||||
@@ -110,11 +116,11 @@ void symtab_init(uint32_t capacity)
|
||||
kw_qnameof = KW_DEF("qnameof");
|
||||
kw_require = KW_DEF("required");
|
||||
kw_sizeof = KW_DEF("sizeof");
|
||||
kw_std = KW_DEF("std");
|
||||
kw___ceil = KW_DEF("__ceil");
|
||||
kw___round = KW_DEF("__round");
|
||||
kw___sqrt = KW_DEF("__sqrt");
|
||||
kw___trunc = KW_DEF("__trunc");
|
||||
kw_std = KW_DEF("std");
|
||||
|
||||
attribute_list[ATTRIBUTE_INLINE] = kw_inline;
|
||||
attribute_list[ATTRIBUTE_NOINLINE] = KW_DEF("noinline");
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "A222"
|
||||
#define COMPILER_VERSION "A223"
|
||||
20
test/test_suite/enumerations/compile_time.c3t
Normal file
20
test/test_suite/enumerations/compile_time.c3t
Normal file
@@ -0,0 +1,20 @@
|
||||
enum MyEnum : short
|
||||
{
|
||||
HELO = 12,
|
||||
WORLD = 14,
|
||||
BYE = -5
|
||||
}
|
||||
|
||||
int myenum_max = MyEnum.max;
|
||||
int myenum_min = MyEnum.min;
|
||||
int myenum_elements = MyEnum.elements;
|
||||
int myenum_alignof = MyEnum.alignof;
|
||||
int myenum_sizeof = MyEnum.sizeof;
|
||||
|
||||
// #expect: compile_time.ll
|
||||
|
||||
@compile_time.myenum_max = protected global i32 14, align 4
|
||||
@compile_time.myenum_min = protected global i32 -5, align 4
|
||||
@compile_time.myenum_elements = protected global i32 3, align 4
|
||||
@compile_time.myenum_alignof = protected global i32 2, align 4
|
||||
@compile_time.myenum_sizeof = protected global i32 2, align 4
|
||||
Reference in New Issue
Block a user