authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-26 14:26:43-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-26 14:26:43-04:00
log95aed8c4575dc6f70e4368b9db527c6cec12acfa
treed7442193c336b49eb5a84a477a521ab85ad7d57f
parente726925e802eddab53cbfd9aacbc5eefe95c356f
parenta0ae575ff8aef87d2dc4134c625f3a479b484b0f

Merge branch 'align'


4 files changed, 94 insertions(+), 50 deletions(-)

src/all_types.hpp+5-5
...@@ -977,7 +977,7 @@ struct TypeTableEntryEnum {...@@ -977,7 +977,7 @@ struct TypeTableEntryEnum {
977 TypeEnumField *fields;977 TypeEnumField *fields;
978 bool is_invalid; // true if any fields are invalid978 bool is_invalid; // true if any fields are invalid
979 TypeTableEntry *tag_type;979 TypeTableEntry *tag_type;
980 TypeTableEntry *union_type;980 LLVMTypeRef union_type_ref;
981981
982 ScopeDecls *decls_scope;982 ScopeDecls *decls_scope;
983983
...@@ -989,6 +989,9 @@ struct TypeTableEntryEnum {...@@ -989,6 +989,9 @@ struct TypeTableEntryEnum {
989989
990 bool zero_bits_loop_flag;990 bool zero_bits_loop_flag;
991 bool zero_bits_known;991 bool zero_bits_known;
992
993 size_t gen_union_index;
994 size_t gen_tag_index;
992};995};
993996
994struct TypeTableEntryEnumTag {997struct TypeTableEntryEnumTag {
...@@ -1633,7 +1636,7 @@ struct ScopeDecls {...@@ -1633,7 +1636,7 @@ struct ScopeDecls {
1633struct ScopeBlock {1636struct ScopeBlock {
1634 Scope base;1637 Scope base;
16351638
1636 HashMap<Buf *, LabelTableEntry *, buf_hash, buf_eql_buf> label_table; 1639 HashMap<Buf *, LabelTableEntry *, buf_hash, buf_eql_buf> label_table;
1637 bool safety_off;1640 bool safety_off;
1638 AstNode *safety_set_node;1641 AstNode *safety_set_node;
1639 bool fast_math_off;1642 bool fast_math_off;
...@@ -2626,9 +2629,6 @@ static const size_t slice_len_index = 1;...@@ -2626,9 +2629,6 @@ static const size_t slice_len_index = 1;
2626static const size_t maybe_child_index = 0;2629static const size_t maybe_child_index = 0;
2627static const size_t maybe_null_index = 1;2630static const size_t maybe_null_index = 1;
26282631
2629static const size_t enum_gen_tag_index = 0;
2630static const size_t enum_gen_union_index = 1;
2631
2632static const size_t err_union_err_index = 0;2632static const size_t err_union_err_index = 0;
2633static const size_t err_union_payload_index = 1;2633static const size_t err_union_payload_index = 1;
26342634
src/analyze.cpp+61-34
...@@ -1245,9 +1245,10 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {...@@ -1245,9 +1245,10 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
1245 uint32_t gen_field_count = enum_type->data.enumeration.gen_field_count;1245 uint32_t gen_field_count = enum_type->data.enumeration.gen_field_count;
1246 ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count);1246 ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count);
12471247
1248 TypeTableEntry *biggest_union_member = nullptr;1248 TypeTableEntry *most_aligned_union_member = nullptr;
1249 uint64_t size_of_most_aligned_member_in_bits = 0;
1249 uint64_t biggest_align_in_bits = 0;1250 uint64_t biggest_align_in_bits = 0;
1250 uint64_t biggest_union_member_size_in_bits = 0;1251 uint64_t biggest_size_in_bits = 0;
12511252
1252 Scope *scope = &enum_type->data.enumeration.decls_scope->base;1253 Scope *scope = &enum_type->data.enumeration.decls_scope->base;
1253 ImportTableEntry *import = get_scope_import(scope);1254 ImportTableEntry *import = get_scope_import(scope);
...@@ -1271,27 +1272,28 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {...@@ -1271,27 +1272,28 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
1271 if (!type_has_bits(field_type))1272 if (!type_has_bits(field_type))
1272 continue;1273 continue;
12731274
1274 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);1275 uint64_t store_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);
1275 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref);1276 uint64_t preferred_align_in_bits = 8*LLVMPreferredAlignmentOfType(g->target_data_ref, field_type->type_ref);
12761277
1277 assert(debug_size_in_bits > 0);1278 assert(store_size_in_bits > 0);
1278 assert(debug_align_in_bits > 0);1279 assert(preferred_align_in_bits > 0);
12791280
1280 union_inner_di_types[type_enum_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,1281 union_inner_di_types[type_enum_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
1281 ZigLLVMTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name),1282 ZigLLVMTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name),
1282 import->di_file, (unsigned)(field_node->line + 1),1283 import->di_file, (unsigned)(field_node->line + 1),
1283 debug_size_in_bits,1284 store_size_in_bits,
1284 debug_align_in_bits,1285 preferred_align_in_bits,
1285 0,1286 0,
1286 0, field_type->di_type);1287 0, field_type->di_type);
12871288
1288 biggest_align_in_bits = max(biggest_align_in_bits, debug_align_in_bits);1289 biggest_size_in_bits = max(biggest_size_in_bits, store_size_in_bits);
12891290
1290 if (!biggest_union_member ||1291 if (!most_aligned_union_member ||
1291 debug_size_in_bits > biggest_union_member_size_in_bits)1292 preferred_align_in_bits > biggest_align_in_bits)
1292 {1293 {
1293 biggest_union_member = field_type;1294 most_aligned_union_member = field_type;
1294 biggest_union_member_size_in_bits = debug_size_in_bits;1295 biggest_align_in_bits = preferred_align_in_bits;
1296 size_of_most_aligned_member_in_bits = store_size_in_bits;
1295 }1297 }
1296 }1298 }
12971299
...@@ -1300,27 +1302,52 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {...@@ -1300,27 +1302,52 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
1300 enum_type->data.enumeration.complete = true;1302 enum_type->data.enumeration.complete = true;
13011303
1302 if (!enum_type->data.enumeration.is_invalid) {1304 if (!enum_type->data.enumeration.is_invalid) {
1303 enum_type->data.enumeration.union_type = biggest_union_member;
1304
1305 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count);1305 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count);
1306 TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type);1306 TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type);
1307 enum_type->data.enumeration.tag_type = tag_type_entry;1307 enum_type->data.enumeration.tag_type = tag_type_entry;
13081308
1309 if (biggest_union_member) {1309 uint64_t align_of_tag_in_bits = 8*LLVMPreferredAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);
1310
1311 if (most_aligned_union_member) {
1310 // create llvm type for union1312 // create llvm type for union
1311 LLVMTypeRef union_element_type = biggest_union_member->type_ref;1313 uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits;
1312 LLVMTypeRef union_type_ref = LLVMStructType(&union_element_type, 1, false);1314 LLVMTypeRef union_type_ref;
1315 if (padding_in_bits > 0) {
1316 TypeTableEntry *u8_type = get_int_type(g, false, 8);
1317 TypeTableEntry *padding_array = get_array_type(g, u8_type, padding_in_bits / 8);
1318 LLVMTypeRef union_element_types[] = {
1319 most_aligned_union_member->type_ref,
1320 padding_array->type_ref,
1321 };
1322 union_type_ref = LLVMStructType(union_element_types, 2, false);
1323 } else {
1324 LLVMTypeRef union_element_types[] = {
1325 most_aligned_union_member->type_ref,
1326 };
1327 union_type_ref = LLVMStructType(union_element_types, 1, false);
1328 }
1329 enum_type->data.enumeration.union_type_ref = union_type_ref;
1330
1331 assert(8*LLVMPreferredAlignmentOfType(g->target_data_ref, union_type_ref) >= biggest_align_in_bits);
1332 assert(8*LLVMStoreSizeOfType(g->target_data_ref, union_type_ref) >= biggest_size_in_bits);
1333
1334 if (align_of_tag_in_bits >= biggest_align_in_bits) {
1335 enum_type->data.enumeration.gen_tag_index = 0;
1336 enum_type->data.enumeration.gen_union_index = 1;
1337 } else {
1338 enum_type->data.enumeration.gen_union_index = 0;
1339 enum_type->data.enumeration.gen_tag_index = 1;
1340 }
13131341
1314 // create llvm type for root struct1342 // create llvm type for root struct
1315 LLVMTypeRef root_struct_element_types[] = {1343 LLVMTypeRef root_struct_element_types[2];
1316 tag_type_entry->type_ref,1344 root_struct_element_types[enum_type->data.enumeration.gen_tag_index] = tag_type_entry->type_ref;
1317 union_type_ref,1345 root_struct_element_types[enum_type->data.enumeration.gen_union_index] = union_type_ref;
1318 };
1319 LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false);1346 LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false);
13201347
1321 // create debug type for tag1348 // create debug type for tag
1322 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref);1349 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref);
1323 uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, tag_type_entry->type_ref);1350 uint64_t tag_debug_align_in_bits = 8*LLVMPreferredAlignmentOfType(g->target_data_ref, tag_type_entry->type_ref);
1324 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,1351 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
1325 ZigLLVMTypeToScope(enum_type->di_type), "AnonEnum",1352 ZigLLVMTypeToScope(enum_type->di_type), "AnonEnum",
1326 import->di_file, (unsigned)(decl_node->line + 1),1353 import->di_file, (unsigned)(decl_node->line + 1),
...@@ -1331,11 +1358,12 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {...@@ -1331,11 +1358,12 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
1331 ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,1358 ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
1332 ZigLLVMTypeToScope(enum_type->di_type), "AnonUnion",1359 ZigLLVMTypeToScope(enum_type->di_type), "AnonUnion",
1333 import->di_file, (unsigned)(decl_node->line + 1),1360 import->di_file, (unsigned)(decl_node->line + 1),
1334 biggest_union_member_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types,1361 biggest_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types,
1335 gen_field_count, 0, "");1362 gen_field_count, 0, "");
13361363
1337 // create debug types for members of root struct1364 // create debug types for members of root struct
1338 uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref, 0);1365 uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref,
1366 enum_type->data.enumeration.gen_tag_index);
1339 ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,1367 ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
1340 ZigLLVMTypeToScope(enum_type->di_type), "tag_field",1368 ZigLLVMTypeToScope(enum_type->di_type), "tag_field",
1341 import->di_file, (unsigned)(decl_node->line + 1),1369 import->di_file, (unsigned)(decl_node->line + 1),
...@@ -1344,21 +1372,20 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {...@@ -1344,21 +1372,20 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
1344 tag_offset_in_bits,1372 tag_offset_in_bits,
1345 0, tag_di_type);1373 0, tag_di_type);
13461374
1347 uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref, 1);1375 uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref,
1376 enum_type->data.enumeration.gen_union_index);
1348 ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,1377 ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
1349 ZigLLVMTypeToScope(enum_type->di_type), "union_field",1378 ZigLLVMTypeToScope(enum_type->di_type), "union_field",
1350 import->di_file, (unsigned)(decl_node->line + 1),1379 import->di_file, (unsigned)(decl_node->line + 1),
1351 biggest_union_member_size_in_bits,1380 biggest_size_in_bits,
1352 biggest_align_in_bits,1381 biggest_align_in_bits,
1353 union_offset_in_bits,1382 union_offset_in_bits,
1354 0, union_di_type);1383 0, union_di_type);
13551384
1356 // create debug type for root struct1385 // create debug type for root struct
1357 ZigLLVMDIType *di_root_members[] = {1386 ZigLLVMDIType *di_root_members[2];
1358 tag_member_di_type,1387 di_root_members[enum_type->data.enumeration.gen_tag_index] = tag_member_di_type;
1359 union_member_di_type,1388 di_root_members[enum_type->data.enumeration.gen_union_index] = union_member_di_type;
1360 };
1361
13621389
1363 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, enum_type->type_ref);1390 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, enum_type->type_ref);
1364 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, enum_type->type_ref);1391 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, enum_type->type_ref);
...@@ -1378,7 +1405,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {...@@ -1378,7 +1405,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
13781405
1379 // create debug type for tag1406 // create debug type for tag
1380 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref);1407 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref);
1381 uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, tag_type_entry->type_ref);1408 uint64_t tag_debug_align_in_bits = 8*LLVMPreferredAlignmentOfType(g->target_data_ref, tag_type_entry->type_ref);
1382 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,1409 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
1383 ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name),1410 ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name),
1384 import->di_file, (unsigned)(decl_node->line + 1),1411 import->di_file, (unsigned)(decl_node->line + 1),
...@@ -2541,7 +2568,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *...@@ -2541,7 +2568,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
2541 if (expected_type->data.fn.is_generic != actual_type->data.fn.is_generic) {2568 if (expected_type->data.fn.is_generic != actual_type->data.fn.is_generic) {
2542 return false;2569 return false;
2543 }2570 }
2544 if (!expected_type->data.fn.is_generic && 2571 if (!expected_type->data.fn.is_generic &&
2545 actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable &&2572 actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable &&
2546 !types_match_const_cast_only(2573 !types_match_const_cast_only(
2547 expected_type->data.fn.fn_type_id.return_type,2574 expected_type->data.fn.fn_type_id.return_type,
src/codegen.cpp+15-11
...@@ -2250,6 +2250,11 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa...@@ -2250,6 +2250,11 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
2250static LLVMValueRef ir_render_enum_field_ptr(CodeGen *g, IrExecutable *executable,2250static LLVMValueRef ir_render_enum_field_ptr(CodeGen *g, IrExecutable *executable,
2251 IrInstructionEnumFieldPtr *instruction)2251 IrInstructionEnumFieldPtr *instruction)
2252{2252{
2253 TypeTableEntry *enum_ptr_type = instruction->enum_ptr->value.type;
2254 assert(enum_ptr_type->id == TypeTableEntryIdPointer);
2255 TypeTableEntry *enum_type = enum_ptr_type->data.pointer.child_type;
2256 assert(enum_type->id == TypeTableEntryIdEnum);
2257
2253 TypeEnumField *field = instruction->field;2258 TypeEnumField *field = instruction->field;
22542259
2255 if (!type_has_bits(field->type_entry))2260 if (!type_has_bits(field->type_entry))
...@@ -2257,7 +2262,7 @@ static LLVMValueRef ir_render_enum_field_ptr(CodeGen *g, IrExecutable *executabl...@@ -2257,7 +2262,7 @@ static LLVMValueRef ir_render_enum_field_ptr(CodeGen *g, IrExecutable *executabl
22572262
2258 LLVMValueRef enum_ptr = ir_llvm_value(g, instruction->enum_ptr);2263 LLVMValueRef enum_ptr = ir_llvm_value(g, instruction->enum_ptr);
2259 LLVMTypeRef field_type_ref = LLVMPointerType(field->type_entry->type_ref, 0);2264 LLVMTypeRef field_type_ref = LLVMPointerType(field->type_entry->type_ref, 0);
2260 LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, enum_ptr, enum_gen_union_index, "");2265 LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, enum_ptr, enum_type->data.enumeration.gen_union_index, "");
2261 LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, "");2266 LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, "");
22622267
2263 return bitcasted_union_field_ptr;2268 return bitcasted_union_field_ptr;
...@@ -3112,7 +3117,7 @@ static LLVMValueRef ir_render_enum_tag(CodeGen *g, IrExecutable *executable, IrI...@@ -3112,7 +3117,7 @@ static LLVMValueRef ir_render_enum_tag(CodeGen *g, IrExecutable *executable, IrI
3112 if (enum_type->data.enumeration.gen_field_count == 0)3117 if (enum_type->data.enumeration.gen_field_count == 0)
3113 return enum_val;3118 return enum_val;
31143119
3115 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, enum_val, enum_gen_tag_index, "");3120 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, enum_val, enum_type->data.enumeration.gen_tag_index, "");
3116 return get_handle_value(g, tag_field_ptr, tag_type, false);3121 return get_handle_value(g, tag_field_ptr, tag_type, false);
3117}3122}
31183123
...@@ -3127,13 +3132,13 @@ static LLVMValueRef ir_render_init_enum(CodeGen *g, IrExecutable *executable, Ir...@@ -3127,13 +3132,13 @@ static LLVMValueRef ir_render_init_enum(CodeGen *g, IrExecutable *executable, Ir
31273132
3128 LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;3133 LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;
31293134
3130 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_gen_tag_index, "");3135 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_type->data.enumeration.gen_tag_index, "");
3131 LLVMBuildStore(g->builder, tag_value, tag_field_ptr);3136 LLVMBuildStore(g->builder, tag_value, tag_field_ptr);
31323137
3133 TypeTableEntry *union_val_type = instruction->field->type_entry;3138 TypeTableEntry *union_val_type = instruction->field->type_entry;
3134 if (type_has_bits(union_val_type)) {3139 if (type_has_bits(union_val_type)) {
3135 LLVMValueRef new_union_val = ir_llvm_value(g, instruction->init_value);3140 LLVMValueRef new_union_val = ir_llvm_value(g, instruction->init_value);
3136 LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_gen_union_index, "");3141 LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, enum_type->data.enumeration.gen_union_index, "");
3137 LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr,3142 LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr,
3138 LLVMPointerType(union_val_type->type_ref, 0), "");3143 LLVMPointerType(union_val_type->type_ref, 0), "");
31393144
...@@ -3663,13 +3668,13 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3663,13 +3668,13 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3663 if (type_entry->data.enumeration.gen_field_count == 0) {3668 if (type_entry->data.enumeration.gen_field_count == 0) {
3664 return tag_value;3669 return tag_value;
3665 } else {3670 } else {
3666 TypeTableEntry *union_type = type_entry->data.enumeration.union_type;3671 LLVMTypeRef union_type_ref = type_entry->data.enumeration.union_type_ref;
3667 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag];3672 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag];
3668 assert(enum_field->value == const_val->data.x_enum.tag);3673 assert(enum_field->value == const_val->data.x_enum.tag);
3669 LLVMValueRef union_value;3674 LLVMValueRef union_value;
3670 if (type_has_bits(enum_field->type_entry)) {3675 if (type_has_bits(enum_field->type_entry)) {
3671 uint64_t union_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,3676 uint64_t union_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,
3672 union_type->type_ref);3677 union_type_ref);
3673 uint64_t field_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,3678 uint64_t field_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,
3674 enum_field->type_entry->type_ref);3679 enum_field->type_entry->type_ref);
3675 uint64_t pad_bytes = union_type_bytes - field_type_bytes;3680 uint64_t pad_bytes = union_type_bytes - field_type_bytes;
...@@ -3685,12 +3690,11 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3685,12 +3690,11 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3685 union_value = LLVMConstStruct(fields, 2, false);3690 union_value = LLVMConstStruct(fields, 2, false);
3686 }3691 }
3687 } else {3692 } else {
3688 union_value = LLVMGetUndef(union_type->type_ref);3693 union_value = LLVMGetUndef(union_type_ref);
3689 }3694 }
3690 LLVMValueRef fields[] = {3695 LLVMValueRef fields[2];
3691 tag_value,3696 fields[type_entry->data.enumeration.gen_tag_index] = tag_value;
3692 union_value,3697 fields[type_entry->data.enumeration.gen_union_index] = union_value;
3693 };
3694 return LLVMConstStruct(fields, 2, false);3698 return LLVMConstStruct(fields, 2, false);
3695 }3699 }
3696 }3700 }
test/cases/enum.zig+13
...@@ -120,3 +120,16 @@ const BareNumber = enum {...@@ -120,3 +120,16 @@ const BareNumber = enum {
120 Two,120 Two,
121 Three,121 Three,
122};122};
123
124
125test "enum alignment" {
126 comptime {
127 assert(@cAbiAlignOf(AlignTestEnum) >= @cAbiAlignOf([9]u8));
128 assert(@cAbiAlignOf(AlignTestEnum) >= @cAbiAlignOf(u64));
129 }
130}
131
132const AlignTestEnum = enum {
133 A: [9]u8,
134 B: u64,
135};