aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp26
1 files changed, 15 insertions, 11 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index ad014e9e19..28f1887c9b 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -2250,6 +2250,11 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
static LLVMValueRef ir_render_enum_field_ptr(CodeGen *g, IrExecutable *executable,
IrInstructionEnumFieldPtr *instruction)
{
+ TypeTableEntry *enum_ptr_type = instruction->enum_ptr->value.type;
+ assert(enum_ptr_type->id == TypeTableEntryIdPointer);
+ TypeTableEntry *enum_type = enum_ptr_type->data.pointer.child_type;
+ assert(enum_type->id == TypeTableEntryIdEnum);
+
TypeEnumField *field = instruction->field;
if (!type_has_bits(field->type_entry))
@@ -2257,7 +2262,7 @@ static LLVMValueRef ir_render_enum_field_ptr(CodeGen *g, IrExecutable *executabl
LLVMValueRef enum_ptr = ir_llvm_value(g, instruction->enum_ptr);
LLVMTypeRef field_type_ref = LLVMPointerType(field->type_entry->type_ref, 0);
- LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, enum_ptr, enum_gen_union_index, "");
+ LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, enum_ptr, enum_type->data.enumeration.gen_union_index, "");
LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, "");
return bitcasted_union_field_ptr;
@@ -3112,7 +3117,7 @@ static LLVMValueRef ir_render_enum_tag(CodeGen *g, IrExecutable *executable, IrI
if (enum_type->data.enumeration.gen_field_count == 0)
return enum_val;
- LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, enum_val, enum_gen_tag_index, "");
+ LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, enum_val, enum_type->data.enumeration.gen_tag_index, "");
return get_handle_value(g, tag_field_ptr, tag_type, false);
}
@@ -3127,13 +3132,13 @@ static LLVMValueRef ir_render_init_enum(CodeGen *g, IrExecutable *executable, Ir
LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;
- LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_gen_tag_index, "");
+ LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_type->data.enumeration.gen_tag_index, "");
LLVMBuildStore(g->builder, tag_value, tag_field_ptr);
TypeTableEntry *union_val_type = instruction->field->type_entry;
if (type_has_bits(union_val_type)) {
LLVMValueRef new_union_val = ir_llvm_value(g, instruction->init_value);
- LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_gen_union_index, "");
+ LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_type->data.enumeration.gen_union_index, "");
LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr,
LLVMPointerType(union_val_type->type_ref, 0), "");
@@ -3663,13 +3668,13 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
if (type_entry->data.enumeration.gen_field_count == 0) {
return tag_value;
} else {
- TypeTableEntry *union_type = type_entry->data.enumeration.union_type;
+ LLVMTypeRef union_type_ref = type_entry->data.enumeration.union_type_ref;
TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag];
assert(enum_field->value == const_val->data.x_enum.tag);
LLVMValueRef union_value;
if (type_has_bits(enum_field->type_entry)) {
uint64_t union_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,
- union_type->type_ref);
+ union_type_ref);
uint64_t field_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,
enum_field->type_entry->type_ref);
uint64_t pad_bytes = union_type_bytes - field_type_bytes;
@@ -3685,12 +3690,11 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
union_value = LLVMConstStruct(fields, 2, false);
}
} else {
- union_value = LLVMGetUndef(union_type->type_ref);
+ union_value = LLVMGetUndef(union_type_ref);
}
- LLVMValueRef fields[] = {
- tag_value,
- union_value,
- };
+ LLVMValueRef fields[2];
+ fields[type_entry->data.enumeration.gen_tag_index] = tag_value;
+ fields[type_entry->data.enumeration.gen_union_index] = union_value;
return LLVMConstStruct(fields, 2, false);
}
}