From 73e9dbbf8c4a68dc6c512eb2de568d59df046494 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 13 Oct 2018 11:07:56 +0100 Subject: switch on typeid with type cases --- src/check_stmt.cpp | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) (limited to 'src/check_stmt.cpp') diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 94de84f86..0ae83f1ed 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -729,32 +729,46 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { add_constant_switch_case(ctx, &seen, rhs); } else { Operand y = {}; - check_expr(ctx, &y, expr); + if (is_type_typeid(x.type)) { + check_expr_or_type(ctx, &y, expr, x.type); + } else { + check_expr(ctx, &y, expr); + } if (x.mode == Addressing_Invalid || y.mode == Addressing_Invalid) { continue; } - convert_to_typed(ctx, &y, x.type); - if (y.mode == Addressing_Invalid) { - continue; - } + if (y.mode == Addressing_Type) { + Type *t = y.type; + if (t == nullptr || t == t_invalid || is_type_polymorphic(t)) { + error(y.expr, "Invalid type for case clause"); + continue; + } + t = default_type(t); + add_type_info_type(ctx, t); + } else { + convert_to_typed(ctx, &y, x.type); + if (y.mode == Addressing_Invalid) { + continue; + } - // NOTE(bill): the ordering here matters - Operand z = y; - check_comparison(ctx, &z, &x, Token_CmpEq); - if (z.mode == Addressing_Invalid) { - continue; - } - if (y.mode != Addressing_Constant) { - if (complete) { - error(y.expr, "#complete switch statement only allows constant case clauses"); + // NOTE(bill): the ordering here matters + Operand z = y; + check_comparison(ctx, &z, &x, Token_CmpEq); + if (z.mode == Addressing_Invalid) { + continue; + } + if (y.mode != Addressing_Constant) { + if (complete) { + error(y.expr, "#complete switch statement only allows constant case clauses"); + } + continue; } - continue; - } - add_constant_switch_case(ctx, &seen, y); + add_constant_switch_case(ctx, &seen, y); + } } } -- cgit v1.2.3