aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-12-26 16:34:18 -0500
committerAndrew Kelley <superjoe30@gmail.com>2016-12-26 16:34:18 -0500
commit66a83d87383cd8de62898171b6665cb1d70af231 (patch)
treeff09db18060a350166cd07a9fb039b43d1a63e37 /src/ir.cpp
parentc8a7ab7eff0f261c47926cf0637e919d42e41940 (diff)
downloadzig-66a83d87383cd8de62898171b6665cb1d70af231.tar.gz
zig-66a83d87383cd8de62898171b6665cb1d70af231.zip
IR: pass intToEnum test
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp51
1 files changed, 40 insertions, 11 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index c964f5536b..d58c813f3e 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -468,6 +468,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToPtr *) {
return IrInstructionIdIntToPtr;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToEnum *) {
+ return IrInstructionIdIntToEnum;
+}
+
template<typename T>
static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) {
T *special_instruction = allocate<T>(1);
@@ -1932,6 +1936,18 @@ static IrInstruction *ir_build_ptr_to_int(IrBuilder *irb, Scope *scope, AstNode
return &instruction->base;
}
+static IrInstruction *ir_build_int_to_enum(IrBuilder *irb, Scope *scope, AstNode *source_node,
+ IrInstruction *target)
+{
+ IrInstructionIntToEnum *instruction = ir_build_instruction<IrInstructionIntToEnum>(
+ irb, scope, source_node);
+ instruction->target = target;
+
+ ir_ref_instruction(target);
+
+ return &instruction->base;
+}
+
static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
results[ReturnKindUnconditional] = 0;
results[ReturnKindError] = 0;
@@ -4720,16 +4736,6 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
bignum_init_unsigned(&const_val->data.x_bignum, other_val->data.x_bool ? 1 : 0);
const_val->special = ConstValSpecialStatic;
break;
- case CastOpIntToEnum:
- {
- uint64_t value = other_val->data.x_bignum.data.x_uint;
- assert(new_type->id == TypeTableEntryIdEnum);
- assert(value < new_type->data.enumeration.src_field_count);
- const_val->data.x_enum.tag = value;
- const_val->data.x_enum.payload = NULL;
- const_val->special = ConstValSpecialStatic;
- break;
- }
}
}
static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
@@ -5311,6 +5317,27 @@ static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *sourc
return result;
}
+static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *source_instr,
+ IrInstruction *target, TypeTableEntry *wanted_type)
+{
+ assert(wanted_type->id == TypeTableEntryIdEnum);
+
+ if (instr_is_comptime(target)) {
+ ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
+ if (!val)
+ return ira->codegen->invalid_instruction;
+ IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, wanted_type, val->depends_on_compile_var);
+ result->value.data.x_enum.tag = val->data.x_bignum.data.x_uint;
+ return result;
+ }
+
+ IrInstruction *result = ir_build_int_to_enum(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, target);
+ result->value.type = wanted_type;
+ return result;
+}
+
static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
TypeTableEntry *wanted_type, IrInstruction *value)
{
@@ -5533,7 +5560,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
wanted_type->id == TypeTableEntryIdEnum &&
wanted_type->data.enumeration.gen_field_count == 0)
{
- return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpIntToEnum, false);
+ return ir_analyze_int_to_enum(ira, source_instr, value, wanted_type);
}
// explicit cast from enum type with no payload to integer
@@ -10016,6 +10043,7 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
case IrInstructionIdWidenOrShorten:
case IrInstructionIdIntToPtr:
case IrInstructionIdPtrToInt:
+ case IrInstructionIdIntToEnum:
case IrInstructionIdStructInit:
case IrInstructionIdStructFieldPtr:
case IrInstructionIdEnumFieldPtr:
@@ -10325,6 +10353,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdWidenOrShorten:
case IrInstructionIdPtrToInt:
case IrInstructionIdIntToPtr:
+ case IrInstructionIdIntToEnum:
return false;
case IrInstructionIdAsm:
{