Adding min/max/elements to enums.

This commit is contained in:
Christoffer Lerno
2021-05-23 23:53:03 +02:00
committed by Christoffer Lerno
parent dbb067a005
commit cf82140a47
5 changed files with 77 additions and 19 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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");

View File

@@ -1 +1 @@
#define COMPILER_VERSION "A222"
#define COMPILER_VERSION "A223"

View 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