From 6512a3e5f24a3aecb1451f921455a93231412104 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 29 Jul 2018 10:50:15 +0100 Subject: using Foo :: enum {A, B, C}; len(Foo) --- src/check_expr.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src/check_expr.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 03747a26f..5596eb106 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -2788,6 +2788,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 case BuiltinProc_offset_of: case BuiltinProc_type_info_of: case BuiltinProc_typeid_of: + case BuiltinProc_len: // NOTE(bill): The first arg may be a Type, this will be checked case by case break; default: @@ -2860,9 +2861,17 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 } case BuiltinProc_len: - case BuiltinProc_cap: { + check_expr_or_type(c, operand, ce->args[0]); + if (operand->mode == Addressing_Invalid) { + return false; + } + /* fallthrough */ + + case BuiltinProc_cap: + { // len :: proc(Type) -> int // cap :: proc(Type) -> int + Type *op_type = type_deref(operand->type); Type *type = t_int; AddressingMode mode = Addressing_Invalid; @@ -2890,6 +2899,11 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 mode = Addressing_Value; } else if (is_type_map(op_type)) { mode = Addressing_Value; + } else if (operand->mode == Addressing_Type && is_type_enum(op_type) && id == BuiltinProc_len) { + Type *bt = base_type(op_type); + mode = Addressing_Constant; + value = exact_value_i64(bt->Enum.fields.count); + type = t_untyped_integer; } if (mode == Addressing_Invalid) { -- cgit v1.2.3