authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-29 07:30:22-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-29 07:51:34-04:00
logc5c9d98065890eaeb9070cba20e5a1ed48b392af
tree46ad520853066174a22ad5eb6e3ac81e51f11d16
parentb8ed0cb3741533e036ee05faa165d2f0c49064f4

introduce align keyword

* remove `@setGlobalAlign` * add align keyword for setting alignment on functions and variables. * loads and stores use alignment from pointer * memcpy, memset use alignment from pointer * add syntax for pointer alignment * slices can have volatile * add u2, i2 primitives * ignore preferred align and use abi align everywhere * back to only having alignOf builtin. preferredAlignOf is too tricky to be useful. See #432. Partial revert of e726925e802eddab53cbfd9aacbc5eefe95c356f. See #37

20 files changed, 931 insertions(+), 715 deletions(-)

src/all_types.hpp+51-36
......@@ -303,8 +303,6 @@ struct TldVar {
303303 Tld base;
304304
305305 VariableTableEntry *var;
306 AstNode *set_global_align_node;
307 uint32_t alignment;
308306 AstNode *set_global_section_node;
309307 Buf *section_name;
310308 AstNode *set_global_linkage_node;
......@@ -358,6 +356,7 @@ enum NodeType {
358356 NodeTypeCharLiteral,
359357 NodeTypeSymbol,
360358 NodeTypePrefixOpExpr,
359 NodeTypeAddrOfExpr,
361360 NodeTypeFnCallExpr,
362361 NodeTypeArrayAccessExpr,
363362 NodeTypeSliceExpr,
......@@ -415,6 +414,8 @@ struct AstNodeFnProto {
415414 AstNode *fn_def_node;
416415 // populated if this is an extern declaration
417416 Buf *lib_name;
417 // populated if the "align A" is present
418 AstNode *align_expr;
418419};
419420
420421struct AstNodeFnDef {
......@@ -470,6 +471,8 @@ struct AstNodeVariableDeclaration {
470471 AstNode *expr;
471472 // populated if this is an extern declaration
472473 Buf *lib_name;
474 // populated if the "align A" is present
475 AstNode *align_expr;
473476};
474477
475478struct AstNodeErrorValueDecl {
......@@ -579,10 +582,6 @@ enum PrefixOp {
579582 PrefixOpBinNot,
580583 PrefixOpNegation,
581584 PrefixOpNegationWrap,
582 PrefixOpAddressOf,
583 PrefixOpConstAddressOf,
584 PrefixOpVolatileAddressOf,
585 PrefixOpConstVolatileAddressOf,
586585 PrefixOpDereference,
587586 PrefixOpMaybe,
588587 PrefixOpError,
......@@ -595,6 +594,23 @@ struct AstNodePrefixOpExpr {
595594 AstNode *primary_expr;
596595};
597596
597struct AstNodeAddrOfExpr {
598 AstNode *align_expr;
599 BigInt *bit_offset_start;
600 BigInt *bit_offset_end;
601 bool is_const;
602 bool is_volatile;
603 AstNode *op_expr;
604};
605
606struct AstNodeArrayType {
607 AstNode *size;
608 AstNode *child_type;
609 AstNode *align_expr;
610 bool is_const;
611 bool is_volatile;
612};
613
598614struct AstNodeUse {
599615 VisibMod visib_mod;
600616 AstNode *expr;
......@@ -807,12 +823,6 @@ struct AstNodeUnreachableExpr {
807823};
808824
809825
810struct AstNodeArrayType {
811 AstNode *size;
812 AstNode *child_type;
813 bool is_const;
814};
815
816826struct AstNodeErrorType {
817827};
818828
......@@ -841,6 +851,7 @@ struct AstNode {
841851 AstNodeBinOpExpr bin_op_expr;
842852 AstNodeUnwrapErrorExpr unwrap_err_expr;
843853 AstNodePrefixOpExpr prefix_op_expr;
854 AstNodeAddrOfExpr addr_of_expr;
844855 AstNodeFnCallExpr fn_call_expr;
845856 AstNodeArrayAccessExpr array_access_expr;
846857 AstNodeSliceExpr slice_expr;
......@@ -911,8 +922,10 @@ struct TypeTableEntryPointer {
911922 TypeTableEntry *child_type;
912923 bool is_const;
913924 bool is_volatile;
925 uint32_t alignment;
914926 uint32_t bit_offset;
915927 uint32_t unaligned_bit_count;
928 TypeTableEntry *slice_parent;
916929};
917930
918931struct TypeTableEntryInt {
......@@ -958,6 +971,7 @@ struct TypeTableEntryStruct {
958971
959972 bool zero_bits_loop_flag;
960973 bool zero_bits_known;
974 uint32_t abi_alignment; // also figured out with zero_bits pass
961975};
962976
963977struct TypeTableEntryMaybe {
......@@ -989,6 +1003,7 @@ struct TypeTableEntryEnum {
9891003
9901004 bool zero_bits_loop_flag;
9911005 bool zero_bits_known;
1006 uint32_t abi_alignment; // also figured out with zero_bits pass
9921007
9931008 size_t gen_union_index;
9941009 size_t gen_tag_index;
......@@ -1101,7 +1116,6 @@ struct TypeTableEntry {
11011116
11021117 // use these fields to make sure we don't duplicate type table entries for the same type
11031118 TypeTableEntry *pointer_parent[2]; // [0 - mut, 1 - const]
1104 TypeTableEntry *slice_parent[2]; // [0 - mut, 1 - const]
11051119 TypeTableEntry *maybe_parent;
11061120 TypeTableEntry *error_parent;
11071121 // If we generate a constant name value for this type, we memoize it here.
......@@ -1164,6 +1178,7 @@ struct FnTableEntry {
11641178 size_t prealloc_bbc;
11651179 AstNode **param_source_nodes;
11661180 Buf **param_names;
1181 uint32_t align_bytes;
11671182
11681183 AstNode *fn_no_inline_set_node;
11691184 AstNode *fn_static_eval_set_node;
......@@ -1171,8 +1186,6 @@ struct FnTableEntry {
11711186 ZigList<IrInstruction *> alloca_list;
11721187 ZigList<VariableTableEntry *> variable_list;
11731188
1174 AstNode *set_global_align_node;
1175 uint32_t alignment;
11761189 AstNode *set_global_section_node;
11771190 Buf *section_name;
11781191 AstNode *set_global_linkage_node;
......@@ -1187,8 +1200,7 @@ enum BuiltinFnId {
11871200 BuiltinFnIdMemcpy,
11881201 BuiltinFnIdMemset,
11891202 BuiltinFnIdSizeof,
1190 BuiltinFnIdPreferredAlignOf,
1191 BuiltinFnIdAbiAlignOf,
1203 BuiltinFnIdAlignOf,
11921204 BuiltinFnIdMaxValue,
11931205 BuiltinFnIdMinValue,
11941206 BuiltinFnIdMemberCount,
......@@ -1224,7 +1236,6 @@ enum BuiltinFnId {
12241236 BuiltinFnIdSetFloatMode,
12251237 BuiltinFnIdTypeName,
12261238 BuiltinFnIdCanImplicitCast,
1227 BuiltinFnIdSetGlobalAlign,
12281239 BuiltinFnIdSetGlobalSection,
12291240 BuiltinFnIdSetGlobalLinkage,
12301241 BuiltinFnIdPanic,
......@@ -1277,6 +1288,7 @@ struct TypeId {
12771288 TypeTableEntry *child_type;
12781289 bool is_const;
12791290 bool is_volatile;
1291 uint32_t alignment;
12801292 uint32_t bit_offset;
12811293 uint32_t unaligned_bit_count;
12821294 } pointer;
......@@ -1392,7 +1404,7 @@ struct CodeGen {
13921404
13931405 struct {
13941406 TypeTableEntry *entry_bool;
1395 TypeTableEntry *entry_int[2][10]; // [signed,unsigned][3,4,5,6,7,8,16,32,64,128]
1407 TypeTableEntry *entry_int[2][11]; // [signed,unsigned][2,3,4,5,6,7,8,16,32,64,128]
13961408 TypeTableEntry *entry_c_int[CIntTypeCount];
13971409 TypeTableEntry *entry_c_longdouble;
13981410 TypeTableEntry *entry_c_void;
......@@ -1547,6 +1559,8 @@ struct CodeGen {
15471559
15481560 ZigList<FnTableEntry *> inline_fns;
15491561 ZigList<AstNode *> tld_ref_source_node_stack;
1562
1563 TypeTableEntry *align_amt_type;
15501564};
15511565
15521566enum VarLinkage {
......@@ -1575,6 +1589,7 @@ struct VariableTableEntry {
15751589 size_t ref_count;
15761590 VarLinkage linkage;
15771591 IrInstruction *decl_instruction;
1592 uint32_t align_bytes;
15781593};
15791594
15801595struct ErrorTableEntry {
......@@ -1808,8 +1823,7 @@ enum IrInstructionId {
18081823 IrInstructionIdBreakpoint,
18091824 IrInstructionIdReturnAddress,
18101825 IrInstructionIdFrameAddress,
1811 IrInstructionIdPreferredAlignOf,
1812 IrInstructionIdAbiAlignOf,
1826 IrInstructionIdAlignOf,
18131827 IrInstructionIdOverflowOp,
18141828 IrInstructionIdTestErr,
18151829 IrInstructionIdUnwrapErrCode,
......@@ -1831,7 +1845,6 @@ enum IrInstructionId {
18311845 IrInstructionIdCheckStatementIsVoid,
18321846 IrInstructionIdTypeName,
18331847 IrInstructionIdCanImplicitCast,
1834 IrInstructionIdSetGlobalAlign,
18351848 IrInstructionIdSetGlobalSection,
18361849 IrInstructionIdSetGlobalLinkage,
18371850 IrInstructionIdDeclRef,
......@@ -1841,6 +1854,7 @@ enum IrInstructionId {
18411854 IrInstructionIdOffsetOf,
18421855 IrInstructionIdTypeId,
18431856 IrInstructionIdSetEvalBranchQuota,
1857 IrInstructionIdPtrTypeOf,
18441858};
18451859
18461860struct IrInstruction {
......@@ -1976,6 +1990,7 @@ struct IrInstructionDeclVar {
19761990
19771991 VariableTableEntry *var;
19781992 IrInstruction *var_type;
1993 IrInstruction *align_value;
19791994 IrInstruction *init_value;
19801995};
19811996
......@@ -2152,7 +2167,9 @@ struct IrInstructionArrayType {
21522167struct IrInstructionSliceType {
21532168 IrInstruction base;
21542169
2170 IrInstruction *align_value;
21552171 bool is_const;
2172 bool is_volatile;
21562173 IrInstruction *child_type;
21572174};
21582175
......@@ -2393,13 +2410,7 @@ struct IrInstructionOverflowOp {
23932410 TypeTableEntry *result_ptr_type;
23942411};
23952412
2396struct IrInstructionPreferredAlignOf {
2397 IrInstruction base;
2398
2399 IrInstruction *type_value;
2400};
2401
2402struct IrInstructionAbiAlignOf {
2413struct IrInstructionAlignOf {
24032414 IrInstruction base;
24042415
24052416 IrInstruction *type_value;
......@@ -2554,13 +2565,6 @@ struct IrInstructionCanImplicitCast {
25542565 IrInstruction *target_value;
25552566};
25562567
2557struct IrInstructionSetGlobalAlign {
2558 IrInstruction base;
2559
2560 Tld *tld;
2561 IrInstruction *value;
2562};
2563
25642568struct IrInstructionSetGlobalSection {
25652569 IrInstruction base;
25662570
......@@ -2622,6 +2626,17 @@ struct IrInstructionSetEvalBranchQuota {
26222626 IrInstruction *new_quota;
26232627};
26242628
2629struct IrInstructionPtrTypeOf {
2630 IrInstruction base;
2631
2632 IrInstruction *align_value;
2633 IrInstruction *child_type;
2634 uint32_t bit_offset_start;
2635 uint32_t bit_offset_end;
2636 bool is_const;
2637 bool is_volatile;
2638};
2639
26252640static const size_t slice_ptr_index = 0;
26262641static const size_t slice_len_index = 1;
26272642
src/analyze.cpp+302-170
......@@ -320,17 +320,21 @@ TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
320320}
321321
322322TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type, bool is_const,
323 bool is_volatile, uint32_t bit_offset, uint32_t unaligned_bit_count)
323 bool is_volatile, uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count)
324324{
325325 assert(child_type->id != TypeTableEntryIdInvalid);
326326
327327 TypeId type_id = {};
328328 TypeTableEntry **parent_pointer = nullptr;
329 if (unaligned_bit_count != 0 || is_volatile) {
329 uint32_t abi_alignment;
330 if (unaligned_bit_count != 0 || is_volatile ||
331 byte_alignment != (abi_alignment = get_abi_alignment(g, child_type)))
332 {
330333 type_id.id = TypeTableEntryIdPointer;
331334 type_id.data.pointer.child_type = child_type;
332335 type_id.data.pointer.is_const = is_const;
333336 type_id.data.pointer.is_volatile = is_volatile;
337 type_id.data.pointer.alignment = byte_alignment;
334338 type_id.data.pointer.bit_offset = bit_offset;
335339 type_id.data.pointer.unaligned_bit_count = unaligned_bit_count;
336340
......@@ -352,11 +356,14 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
352356 const char *const_str = is_const ? "const " : "";
353357 const char *volatile_str = is_volatile ? "volatile " : "";
354358 buf_resize(&entry->name, 0);
355 if (unaligned_bit_count == 0) {
359 if (unaligned_bit_count == 0 && byte_alignment == abi_alignment) {
356360 buf_appendf(&entry->name, "&%s%s%s", const_str, volatile_str, buf_ptr(&child_type->name));
361 } else if (unaligned_bit_count == 0) {
362 buf_appendf(&entry->name, "&align %" PRIu32 " %s%s%s", byte_alignment,
363 const_str, volatile_str, buf_ptr(&child_type->name));
357364 } else {
358 buf_appendf(&entry->name, "&:%" PRIu32 ":%" PRIu32 " %s%s%s", bit_offset,
359 bit_offset + unaligned_bit_count, const_str, volatile_str, buf_ptr(&child_type->name));
365 buf_appendf(&entry->name, "&align %" PRIu32 ":%" PRIu32 ":%" PRIu32 " %s%s%s", byte_alignment,
366 bit_offset, bit_offset + unaligned_bit_count, const_str, volatile_str, buf_ptr(&child_type->name));
360367 }
361368
362369 assert(child_type->id != TypeTableEntryIdInvalid);
......@@ -364,20 +371,29 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
364371 entry->zero_bits = !type_has_bits(child_type);
365372
366373 if (!entry->zero_bits) {
367 entry->type_ref = LLVMPointerType(child_type->type_ref, 0);
374 assert(byte_alignment > 0);
375 if (is_const || is_volatile || unaligned_bit_count != 0 || byte_alignment != abi_alignment) {
376 TypeTableEntry *peer_type = get_pointer_to_type(g, child_type, false);
377 entry->type_ref = peer_type->type_ref;
378 entry->di_type = peer_type->di_type;
379 } else {
380 entry->type_ref = LLVMPointerType(child_type->type_ref, 0);
368381
369 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
370 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
371 assert(child_type->di_type);
372 entry->di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, child_type->di_type,
373 debug_size_in_bits, debug_align_in_bits, buf_ptr(&entry->name));
382 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
383 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref);
384 assert(child_type->di_type);
385 entry->di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, child_type->di_type,
386 debug_size_in_bits, debug_align_in_bits, buf_ptr(&entry->name));
387 }
374388 } else {
389 assert(byte_alignment == 0);
375390 entry->di_type = g->builtin_types.entry_void->di_type;
376391 }
377392
378393 entry->data.pointer.child_type = child_type;
379394 entry->data.pointer.is_const = is_const;
380395 entry->data.pointer.is_volatile = is_volatile;
396 entry->data.pointer.alignment = byte_alignment;
381397 entry->data.pointer.bit_offset = bit_offset;
382398 entry->data.pointer.unaligned_bit_count = unaligned_bit_count;
383399
......@@ -390,7 +406,7 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type
390406}
391407
392408TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) {
393 return get_pointer_to_type_extra(g, child_type, is_const, false, 0, 0);
409 return get_pointer_to_type_extra(g, child_type, is_const, false, get_abi_alignment(g, child_type), 0, 0);
394410}
395411
396412TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
......@@ -592,11 +608,7 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
592608 return entry;
593609}
594610
595static void slice_type_common_init(CodeGen *g, TypeTableEntry *child_type,
596 bool is_const, TypeTableEntry *entry)
597{
598 TypeTableEntry *pointer_type = get_pointer_to_type(g, child_type, is_const);
599
611static void slice_type_common_init(CodeGen *g, TypeTableEntry *pointer_type, TypeTableEntry *entry) {
600612 unsigned element_count = 2;
601613 entry->data.structure.layout = ContainerLayoutAuto;
602614 entry->data.structure.is_slice = true;
......@@ -612,156 +624,167 @@ static void slice_type_common_init(CodeGen *g, TypeTableEntry *child_type,
612624 entry->data.structure.fields[slice_len_index].src_index = slice_len_index;
613625 entry->data.structure.fields[slice_len_index].gen_index = 1;
614626
615 assert(type_has_zero_bits_known(child_type));
616 if (child_type->zero_bits) {
627 assert(type_has_zero_bits_known(pointer_type->data.pointer.child_type));
628 if (pointer_type->data.pointer.child_type->zero_bits) {
617629 entry->data.structure.gen_field_count = 1;
618630 entry->data.structure.fields[slice_ptr_index].gen_index = SIZE_MAX;
619631 entry->data.structure.fields[slice_len_index].gen_index = 0;
620632 }
621633}
622634
623TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) {
624 assert(child_type->id != TypeTableEntryIdInvalid);
625 TypeTableEntry **parent_pointer = &child_type->slice_parent[(is_const ? 1 : 0)];
635TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *ptr_type) {
636 assert(ptr_type->id == TypeTableEntryIdPointer);
626637
638 TypeTableEntry **parent_pointer = &ptr_type->data.pointer.slice_parent;
627639 if (*parent_pointer) {
628640 return *parent_pointer;
629 } else if (is_const) {
630 TypeTableEntry *var_peer = get_slice_type(g, child_type, false);
631 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);
632 entry->is_copyable = true;
641 }
633642
634 buf_resize(&entry->name, 0);
635 buf_appendf(&entry->name, "[]const %s", buf_ptr(&child_type->name));
643 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);
644 entry->is_copyable = true;
636645
637 slice_type_common_init(g, child_type, is_const, entry);
646 // replace the & with [] to go from a ptr type name to a slice type name
647 buf_resize(&entry->name, 0);
648 buf_appendf(&entry->name, "[]%s", buf_ptr(&ptr_type->name) + 1);
638649
639 entry->type_ref = var_peer->type_ref;
640 entry->di_type = var_peer->di_type;
650 TypeTableEntry *child_type = ptr_type->data.pointer.child_type;
651 uint32_t abi_alignment;
652 if (ptr_type->data.pointer.is_const || ptr_type->data.pointer.is_volatile ||
653 ptr_type->data.pointer.alignment != (abi_alignment = get_abi_alignment(g, child_type)))
654 {
655 TypeTableEntry *peer_ptr_type = get_pointer_to_type(g, child_type, false);
656 TypeTableEntry *peer_slice_type = get_slice_type(g, peer_ptr_type);
657
658 slice_type_common_init(g, ptr_type, entry);
659
660 entry->type_ref = peer_slice_type->type_ref;
661 entry->di_type = peer_slice_type->di_type;
641662 entry->data.structure.complete = true;
642663 entry->data.structure.zero_bits_known = true;
664 entry->data.structure.abi_alignment = peer_slice_type->data.structure.abi_alignment;
643665
644666 *parent_pointer = entry;
645667 return entry;
646 } else {
647 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);
648 entry->is_copyable = true;
649
650 // If the child type is []const T then we need to make sure the type ref
651 // and debug info is the same as if the child type were []T.
652 if (is_slice(child_type)) {
653 TypeTableEntry *ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry;
654 assert(ptr_type->id == TypeTableEntryIdPointer);
655 if (ptr_type->data.pointer.is_const) {
656 TypeTableEntry *non_const_child_type = get_slice_type(g,
657 ptr_type->data.pointer.child_type, false);
658 TypeTableEntry *var_peer = get_slice_type(g, non_const_child_type, false);
659
660 entry->type_ref = var_peer->type_ref;
661 entry->di_type = var_peer->di_type;
662 }
668 }
669
670 // If the child type is []const T then we need to make sure the type ref
671 // and debug info is the same as if the child type were []T.
672 if (is_slice(child_type)) {
673 TypeTableEntry *child_ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry;
674 assert(child_ptr_type->id == TypeTableEntryIdPointer);
675 TypeTableEntry *grand_child_type = child_ptr_type->data.pointer.child_type;
676 if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile ||
677 child_ptr_type->data.pointer.alignment != get_abi_alignment(g, grand_child_type))
678 {
679 TypeTableEntry *bland_child_ptr_type = get_pointer_to_type(g, grand_child_type, false);
680 TypeTableEntry *bland_child_slice = get_slice_type(g, bland_child_ptr_type);
681 TypeTableEntry *peer_ptr_type = get_pointer_to_type(g, bland_child_slice, false);
682 TypeTableEntry *peer_slice_type = get_slice_type(g, peer_ptr_type);
683
684 entry->type_ref = peer_slice_type->type_ref;
685 entry->di_type = peer_slice_type->di_type;
686 entry->data.structure.abi_alignment = peer_slice_type->data.structure.abi_alignment;
663687 }
688 }
664689
665 buf_resize(&entry->name, 0);
666 buf_appendf(&entry->name, "[]%s", buf_ptr(&child_type->name));
690 slice_type_common_init(g, ptr_type, entry);
667691
668 slice_type_common_init(g, child_type, is_const, entry);
692 if (!entry->type_ref) {
693 entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&entry->name));
669694
670 if (!entry->type_ref) {
671 entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&entry->name));
695 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
696 ZigLLVMDIFile *di_file = nullptr;
697 unsigned line = 0;
698 entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
699 ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name),
700 compile_unit_scope, di_file, line);
672701
673 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
674 ZigLLVMDIFile *di_file = nullptr;
675 unsigned line = 0;
676 entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
677 ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name),
678 compile_unit_scope, di_file, line);
702 if (child_type->zero_bits) {
703 LLVMTypeRef element_types[] = {
704 g->builtin_types.entry_usize->type_ref,
705 };
706 LLVMStructSetBody(entry->type_ref, element_types, 1, false);
679707
680 if (child_type->zero_bits) {
681 LLVMTypeRef element_types[] = {
682 g->builtin_types.entry_usize->type_ref,
683 };
684 LLVMStructSetBody(entry->type_ref, element_types, 1, false);
685
686 TypeTableEntry *usize_type = g->builtin_types.entry_usize;
687 uint64_t len_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, usize_type->type_ref);
688 uint64_t len_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, usize_type->type_ref);
689 uint64_t len_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 0);
690
691 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
692 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
693
694 ZigLLVMDIType *di_element_types[] = {
695 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type),
696 "len", di_file, line,
697 len_debug_size_in_bits,
698 len_debug_align_in_bits,
699 len_offset_in_bits,
700 0, usize_type->di_type),
701 };
702 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
703 compile_unit_scope,
704 buf_ptr(&entry->name),
705 di_file, line, debug_size_in_bits, debug_align_in_bits, 0,
706 nullptr, di_element_types, 1, 0, nullptr, "");
707
708 ZigLLVMReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type);
709 entry->di_type = replacement_di_type;
710 } else {
711 TypeTableEntry *pointer_type = get_pointer_to_type(g, child_type, is_const);
708 TypeTableEntry *usize_type = g->builtin_types.entry_usize;
709 uint64_t len_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, usize_type->type_ref);
710 uint64_t len_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, usize_type->type_ref);
711 uint64_t len_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 0);
712712
713 unsigned element_count = 2;
714 LLVMTypeRef element_types[] = {
715 pointer_type->type_ref,
716 g->builtin_types.entry_usize->type_ref,
717 };
718 LLVMStructSetBody(entry->type_ref, element_types, element_count, false);
719
720
721 uint64_t ptr_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, pointer_type->type_ref);
722 uint64_t ptr_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, pointer_type->type_ref);
723 uint64_t ptr_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 0);
724
725 TypeTableEntry *usize_type = g->builtin_types.entry_usize;
726 uint64_t len_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, usize_type->type_ref);
727 uint64_t len_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, usize_type->type_ref);
728 uint64_t len_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 1);
729
730 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
731 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
732
733 ZigLLVMDIType *di_element_types[] = {
734 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type),
735 "ptr", di_file, line,
736 ptr_debug_size_in_bits,
737 ptr_debug_align_in_bits,
738 ptr_offset_in_bits,
739 0, pointer_type->di_type),
740 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type),
741 "len", di_file, line,
742 len_debug_size_in_bits,
743 len_debug_align_in_bits,
744 len_offset_in_bits,
745 0, usize_type->di_type),
746 };
747 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
748 compile_unit_scope,
749 buf_ptr(&entry->name),
750 di_file, line, debug_size_in_bits, debug_align_in_bits, 0,
751 nullptr, di_element_types, 2, 0, nullptr, "");
752
753 ZigLLVMReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type);
754 entry->di_type = replacement_di_type;
755 }
756 }
713 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
714 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref);
757715
716 ZigLLVMDIType *di_element_types[] = {
717 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type),
718 "len", di_file, line,
719 len_debug_size_in_bits,
720 len_debug_align_in_bits,
721 len_offset_in_bits,
722 0, usize_type->di_type),
723 };
724 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
725 compile_unit_scope,
726 buf_ptr(&entry->name),
727 di_file, line, debug_size_in_bits, debug_align_in_bits, 0,
728 nullptr, di_element_types, 1, 0, nullptr, "");
758729
759 entry->data.structure.complete = true;
760 entry->data.structure.zero_bits_known = true;
730 ZigLLVMReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type);
731 entry->di_type = replacement_di_type;
761732
762 *parent_pointer = entry;
763 return entry;
733 entry->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref, usize_type->type_ref);
734 } else {
735 unsigned element_count = 2;
736 LLVMTypeRef element_types[] = {
737 ptr_type->type_ref,
738 g->builtin_types.entry_usize->type_ref,
739 };
740 LLVMStructSetBody(entry->type_ref, element_types, element_count, false);
741
742
743 uint64_t ptr_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, ptr_type->type_ref);
744 uint64_t ptr_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, ptr_type->type_ref);
745 uint64_t ptr_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 0);
746
747 TypeTableEntry *usize_type = g->builtin_types.entry_usize;
748 uint64_t len_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, usize_type->type_ref);
749 uint64_t len_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, usize_type->type_ref);
750 uint64_t len_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 1);
751
752 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
753 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref);
754
755 ZigLLVMDIType *di_element_types[] = {
756 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type),
757 "ptr", di_file, line,
758 ptr_debug_size_in_bits,
759 ptr_debug_align_in_bits,
760 ptr_offset_in_bits,
761 0, ptr_type->di_type),
762 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type),
763 "len", di_file, line,
764 len_debug_size_in_bits,
765 len_debug_align_in_bits,
766 len_offset_in_bits,
767 0, usize_type->di_type),
768 };
769 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
770 compile_unit_scope,
771 buf_ptr(&entry->name),
772 di_file, line, debug_size_in_bits, debug_align_in_bits, 0,
773 nullptr, di_element_types, 2, 0, nullptr, "");
774
775 ZigLLVMReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type);
776 entry->di_type = replacement_di_type;
777
778 entry->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref);
779 }
764780 }
781
782
783 entry->data.structure.complete = true;
784 entry->data.structure.zero_bits_known = true;
785
786 *parent_pointer = entry;
787 return entry;
765788}
766789
767790TypeTableEntry *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *name) {
......@@ -1273,26 +1296,24 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
12731296 continue;
12741297
12751298 uint64_t store_size_in_bits = 8*LLVMStoreSizeOfType(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);
1299 uint64_t abi_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref);
12771300
12781301 assert(store_size_in_bits > 0);
1279 assert(preferred_align_in_bits > 0);
1302 assert(abi_align_in_bits > 0);
12801303
12811304 union_inner_di_types[type_enum_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
12821305 ZigLLVMTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name),
12831306 import->di_file, (unsigned)(field_node->line + 1),
12841307 store_size_in_bits,
1285 preferred_align_in_bits,
1308 abi_align_in_bits,
12861309 0,
12871310 0, field_type->di_type);
12881311
12891312 biggest_size_in_bits = max(biggest_size_in_bits, store_size_in_bits);
12901313
1291 if (!most_aligned_union_member ||
1292 preferred_align_in_bits > biggest_align_in_bits)
1293 {
1314 if (!most_aligned_union_member || abi_align_in_bits > biggest_align_in_bits) {
12941315 most_aligned_union_member = field_type;
1295 biggest_align_in_bits = preferred_align_in_bits;
1316 biggest_align_in_bits = abi_align_in_bits;
12961317 size_of_most_aligned_member_in_bits = store_size_in_bits;
12971318 }
12981319 }
......@@ -1306,7 +1327,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
13061327 TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type);
13071328 enum_type->data.enumeration.tag_type = tag_type_entry;
13081329
1309 uint64_t align_of_tag_in_bits = 8*LLVMPreferredAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);
1330 uint64_t align_of_tag_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);
13101331
13111332 if (most_aligned_union_member) {
13121333 // create llvm type for union
......@@ -1328,7 +1349,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
13281349 }
13291350 enum_type->data.enumeration.union_type_ref = union_type_ref;
13301351
1331 assert(8*LLVMPreferredAlignmentOfType(g->target_data_ref, union_type_ref) >= biggest_align_in_bits);
1352 assert(8*LLVMABIAlignmentOfType(g->target_data_ref, union_type_ref) >= biggest_align_in_bits);
13321353 assert(8*LLVMStoreSizeOfType(g->target_data_ref, union_type_ref) >= biggest_size_in_bits);
13331354
13341355 if (align_of_tag_in_bits >= biggest_align_in_bits) {
......@@ -1347,7 +1368,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
13471368
13481369 // create debug type for tag
13491370 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(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);
1371 uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type_entry->type_ref);
13511372 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
13521373 ZigLLVMTypeToScope(enum_type->di_type), "AnonEnum",
13531374 import->di_file, (unsigned)(decl_node->line + 1),
......@@ -1405,7 +1426,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
14051426
14061427 // create debug type for tag
14071428 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(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);
1429 uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type_entry->type_ref);
14091430 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
14101431 ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name),
14111432 import->di_file, (unsigned)(decl_node->line + 1),
......@@ -1497,7 +1518,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
14971518 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
14981519 TypeTableEntry *field_type = type_struct_field->type_entry;
14991520 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);
1500 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref);
1521 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref);
15011522 uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, i);
15021523 di_element_types[i] = ZigLLVMCreateDebugMemberType(g->dbuilder,
15031524 ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
......@@ -1522,6 +1543,7 @@ TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *f
15221543
15231544 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);
15241545 struct_type->di_type = replacement_di_type;
1546 struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref, struct_type->type_ref);
15251547
15261548 return struct_type;
15271549}
......@@ -1663,6 +1685,10 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
16631685 struct_type->data.structure.gen_field_count = (uint32_t)gen_field_count;
16641686
16651687 LLVMStructSetBody(struct_type->type_ref, element_types, (unsigned)gen_field_count, packed);
1688
1689 // if you hit this assert then probably this type or a related type didn't
1690 // get ensure_complete_type called on it before using it with something that
1691 // requires a complete type
16661692 assert(LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref) > 0);
16671693
16681694 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(debug_field_count);
......@@ -1760,6 +1786,8 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type) {
17601786 enum_type->data.enumeration.src_field_count = field_count;
17611787 enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count);
17621788
1789 uint32_t biggest_align_bytes = 0;
1790
17631791 Scope *scope = &enum_type->data.enumeration.decls_scope->base;
17641792
17651793 uint32_t gen_field_index = 0;
......@@ -1782,12 +1810,22 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type) {
17821810
17831811 type_enum_field->gen_index = gen_field_index;
17841812 gen_field_index += 1;
1813
1814 uint32_t field_align_bytes = get_abi_alignment(g, field_type);
1815 if (field_align_bytes > biggest_align_bytes) {
1816 biggest_align_bytes = field_align_bytes;
1817 }
17851818 }
17861819
17871820 enum_type->data.enumeration.zero_bits_loop_flag = false;
17881821 enum_type->data.enumeration.gen_field_count = gen_field_index;
17891822 enum_type->zero_bits = (gen_field_index == 0 && field_count < 2);
17901823 enum_type->data.enumeration.zero_bits_known = true;
1824
1825 // also compute abi_alignment
1826 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count);
1827 uint32_t align_of_tag_in_bytes = LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref);
1828 enum_type->data.enumeration.abi_alignment = max(align_of_tag_in_bytes, biggest_align_bytes);
17911829}
17921830
17931831static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) {
......@@ -1797,7 +1835,19 @@ static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) {
17971835 return;
17981836
17991837 if (struct_type->data.structure.zero_bits_loop_flag) {
1838 // If we get here it's due to recursion. From this we conclude that the struct is
1839 // not zero bits, and if abi_alignment == 0 we further conclude that the first field
1840 // is a pointer to this very struct, or a function pointer with parameters that
1841 // reference such a type.
18001842 struct_type->data.structure.zero_bits_known = true;
1843 if (struct_type->data.structure.abi_alignment == 0) {
1844 if (struct_type->data.structure.layout == ContainerLayoutPacked) {
1845 struct_type->data.structure.abi_alignment = 1;
1846 } else {
1847 struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref,
1848 LLVMPointerType(LLVMInt8Type(), 0));
1849 }
1850 }
18011851 return;
18021852 }
18031853
......@@ -1833,6 +1883,17 @@ static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) {
18331883 if (!type_has_bits(field_type))
18341884 continue;
18351885
1886 if (gen_field_index == 0) {
1887 if (struct_type->data.structure.layout == ContainerLayoutPacked) {
1888 struct_type->data.structure.abi_alignment = 1;
1889 } else {
1890 // Alignment of structs is the alignment of the first field, for now.
1891 // TODO change this when we re-order struct fields (issue #168)
1892 struct_type->data.structure.abi_alignment = get_abi_alignment(g, field_type);
1893 assert(struct_type->data.structure.abi_alignment != 0);
1894 }
1895 }
1896
18361897 type_struct_field->gen_index = gen_field_index;
18371898 gen_field_index += 1;
18381899 }
......@@ -1925,7 +1986,8 @@ static void typecheck_panic_fn(CodeGen *g, FnTableEntry *panic_fn) {
19251986 if (fn_type_id->param_count != 1) {
19261987 return wrong_panic_prototype(g, proto_node, fn_type);
19271988 }
1928 TypeTableEntry *const_u8_slice = get_slice_type(g, g->builtin_types.entry_u8, true);
1989 TypeTableEntry *const_u8_ptr = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
1990 TypeTableEntry *const_u8_slice = get_slice_type(g, const_u8_ptr);
19291991 if (fn_type_id->param_info[0].type != const_u8_slice) {
19301992 return wrong_panic_prototype(g, proto_node, fn_type);
19311993 }
......@@ -1946,6 +2008,25 @@ TypeTableEntry *get_test_fn_type(CodeGen *g) {
19462008 return g->test_fn_type;
19472009}
19482010
2011static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_t *result) {
2012 IrInstruction *align_result = analyze_const_value(g, scope, node, get_align_amt_type(g), nullptr);
2013 if (type_is_invalid(align_result->value.type))
2014 return false;
2015
2016 uint32_t align_bytes = bigint_as_unsigned(&align_result->value.data.x_bigint);
2017 if (align_bytes == 0) {
2018 add_node_error(g, node, buf_sprintf("alignment must be >= 1"));
2019 return false;
2020 }
2021 if (!is_power_of_2(align_bytes)) {
2022 add_node_error(g, node, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes));
2023 return false;
2024 }
2025
2026 *result = align_bytes;
2027 return true;
2028}
2029
19492030static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
19502031 ImportTableEntry *import = tld_fn->base.import;
19512032 AstNode *source_node = tld_fn->base.source_node;
......@@ -1982,6 +2063,16 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
19822063 return;
19832064 }
19842065
2066 if (fn_proto->align_expr != nullptr) {
2067 if (!analyze_const_align(g, tld_fn->base.parent_scope, fn_proto->align_expr,
2068 &fn_table_entry->align_bytes))
2069 {
2070 fn_table_entry->type_entry = g->builtin_types.entry_invalid;
2071 tld_fn->base.resolution = TldResolutionInvalid;
2072 return;
2073 }
2074 }
2075
19852076 if (!fn_table_entry->type_entry->data.fn.is_generic) {
19862077 g->fn_protos.append(fn_table_entry);
19872078
......@@ -2149,6 +2240,7 @@ void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value) {
21492240 assert(tld->id == TldIdVar);
21502241 TldVar *tld_var = (TldVar *)tld;
21512242 tld_var->var->value = value;
2243 tld_var->var->align_bytes = get_abi_alignment(g, value->type);
21522244}
21532245
21542246void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
......@@ -2236,6 +2328,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
22362328 case NodeTypeThisLiteral:
22372329 case NodeTypeSymbol:
22382330 case NodeTypePrefixOpExpr:
2331 case NodeTypeAddrOfExpr:
22392332 case NodeTypeIfBoolExpr:
22402333 case NodeTypeWhileExpr:
22412334 case NodeTypeForExpr:
......@@ -2331,6 +2424,7 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent
23312424 variable_entry->shadowable = false;
23322425 variable_entry->mem_slot_index = SIZE_MAX;
23332426 variable_entry->src_arg_index = SIZE_MAX;
2427 variable_entry->align_bytes = get_abi_alignment(g, value->type);
23342428
23352429 assert(name);
23362430
......@@ -2389,7 +2483,8 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent
23892483}
23902484
23912485static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
2392 AstNodeVariableDeclaration *var_decl = &tld_var->base.source_node->data.variable_declaration;
2486 AstNode *source_node = tld_var->base.source_node;
2487 AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration;
23932488
23942489 bool is_const = var_decl->is_const;
23952490 bool is_export = (tld_var->base.visib_mod == VisibModExport);
......@@ -2401,8 +2496,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
24012496 explicit_type = validate_var_type(g, var_decl->type, proposed_type);
24022497 }
24032498
2404 AstNode *source_node = tld_var->base.source_node;
2405
24062499 if (is_export && is_extern) {
24072500 add_node_error(g, source_node, buf_sprintf("variable is both export and extern"));
24082501 }
......@@ -2458,6 +2551,12 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
24582551 is_const, init_val, &tld_var->base);
24592552 tld_var->var->linkage = linkage;
24602553
2554 if (var_decl->align_expr != nullptr) {
2555 if (!analyze_const_align(g, tld_var->base.parent_scope, var_decl->align_expr, &tld_var->var->align_bytes)) {
2556 tld_var->var->value->type = g->builtin_types.entry_invalid;
2557 }
2558 }
2559
24612560 g->global_vars.append(tld_var);
24622561}
24632562
......@@ -3129,26 +3228,28 @@ void semantic_analyze(CodeGen *g) {
31293228
31303229TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
31313230 size_t index;
3132 if (size_in_bits == 3) {
3231 if (size_in_bits == 2) {
31333232 index = 0;
3134 } else if (size_in_bits == 4) {
3233 } else if (size_in_bits == 3) {
31353234 index = 1;
3136 } else if (size_in_bits == 5) {
3235 } else if (size_in_bits == 4) {
31373236 index = 2;
3138 } else if (size_in_bits == 6) {
3237 } else if (size_in_bits == 5) {
31393238 index = 3;
3140 } else if (size_in_bits == 7) {
3239 } else if (size_in_bits == 6) {
31413240 index = 4;
3142 } else if (size_in_bits == 8) {
3241 } else if (size_in_bits == 7) {
31433242 index = 5;
3144 } else if (size_in_bits == 16) {
3243 } else if (size_in_bits == 8) {
31453244 index = 6;
3146 } else if (size_in_bits == 32) {
3245 } else if (size_in_bits == 16) {
31473246 index = 7;
3148 } else if (size_in_bits == 64) {
3247 } else if (size_in_bits == 32) {
31493248 index = 8;
3150 } else if (size_in_bits == 128) {
3249 } else if (size_in_bits == 64) {
31513250 index = 9;
3251 } else if (size_in_bits == 128) {
3252 index = 10;
31523253 } else {
31533254 return nullptr;
31543255 }
......@@ -3723,8 +3824,10 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr
37233824{
37243825 assert(array_val->type->id == TypeTableEntryIdArray);
37253826
3827 TypeTableEntry *ptr_type = get_pointer_to_type(g, array_val->type->data.array.child_type, is_const);
3828
37263829 const_val->special = ConstValSpecialStatic;
3727 const_val->type = get_slice_type(g, array_val->type->data.array.child_type, is_const);
3830 const_val->type = get_slice_type(g, ptr_type);
37283831 const_val->data.x_struct.fields = create_const_vals(2);
37293832
37303833 init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const);
......@@ -4342,14 +4445,15 @@ uint32_t type_id_hash(TypeId x) {
43424445 return hash_ptr(x.data.pointer.child_type) +
43434446 (x.data.pointer.is_const ? (uint32_t)2749109194 : (uint32_t)4047371087) +
43444447 (x.data.pointer.is_volatile ? (uint32_t)536730450 : (uint32_t)1685612214) +
4345 (((uint32_t)x.data.pointer.bit_offset) * (uint32_t)2639019452) +
4346 (((uint32_t)x.data.pointer.unaligned_bit_count) * (uint32_t)529908881);
4448 (((uint32_t)x.data.pointer.alignment) ^ (uint32_t)0x777fbe0e) +
4449 (((uint32_t)x.data.pointer.bit_offset) ^ (uint32_t)2639019452) +
4450 (((uint32_t)x.data.pointer.unaligned_bit_count) ^ (uint32_t)529908881);
43474451 case TypeTableEntryIdArray:
43484452 return hash_ptr(x.data.array.child_type) +
4349 ((uint32_t)x.data.array.size * (uint32_t)2122979968);
4453 ((uint32_t)x.data.array.size ^ (uint32_t)2122979968);
43504454 case TypeTableEntryIdInt:
43514455 return (x.data.integer.is_signed ? (uint32_t)2652528194 : (uint32_t)163929201) +
4352 (((uint32_t)x.data.integer.bit_count) * (uint32_t)2998081557);
4456 (((uint32_t)x.data.integer.bit_count) ^ (uint32_t)2998081557);
43534457 }
43544458 zig_unreachable();
43554459}
......@@ -4387,6 +4491,7 @@ bool type_id_eql(TypeId a, TypeId b) {
43874491 return a.data.pointer.child_type == b.data.pointer.child_type &&
43884492 a.data.pointer.is_const == b.data.pointer.is_const &&
43894493 a.data.pointer.is_volatile == b.data.pointer.is_volatile &&
4494 a.data.pointer.alignment == b.data.pointer.alignment &&
43904495 a.data.pointer.bit_offset == b.data.pointer.bit_offset &&
43914496 a.data.pointer.unaligned_bit_count == b.data.pointer.unaligned_bit_count;
43924497 case TypeTableEntryIdArray:
......@@ -4692,3 +4797,30 @@ void add_link_lib_symbol(CodeGen *g, Buf *lib_name, Buf *symbol_name) {
46924797 }
46934798 link_lib->symbols.append(symbol_name);
46944799}
4800
4801uint32_t get_abi_alignment(CodeGen *g, TypeTableEntry *type_entry) {
4802 type_ensure_zero_bits_known(g, type_entry);
4803 if (type_entry->zero_bits) return 0;
4804
4805 // We need to make this function work without requiring ensure_complete_type
4806 // so that we can have structs with fields that are pointers to their own type.
4807 if (type_entry->id == TypeTableEntryIdStruct) {
4808 assert(type_entry->data.structure.abi_alignment != 0);
4809 return type_entry->data.structure.abi_alignment;
4810 } else if (type_entry->id == TypeTableEntryIdEnum) {
4811 assert(type_entry->data.enumeration.abi_alignment != 0);
4812 return type_entry->data.enumeration.abi_alignment;
4813 } else if (type_entry->id == TypeTableEntryIdUnion) {
4814 zig_panic("TODO");
4815 } else {
4816 return LLVMABIAlignmentOfType(g->target_data_ref, type_entry->type_ref);
4817 }
4818}
4819
4820TypeTableEntry *get_align_amt_type(CodeGen *g) {
4821 if (g->align_amt_type == nullptr) {
4822 // according to LLVM the maximum alignment is 1 << 29.
4823 g->align_amt_type = get_int_type(g, false, 29);
4824 }
4825 return g->align_amt_type;
4826}
src/analyze.hpp+5-2
......@@ -16,7 +16,7 @@ ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *m
1616TypeTableEntry *new_type_table_entry(TypeTableEntryId id);
1717TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
1818TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type, bool is_const,
19 bool is_volatile, uint32_t bit_offset, uint32_t unaligned_bit_count);
19 bool is_volatile, uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count);
2020uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);
2121uint64_t type_size_bits(CodeGen *g, TypeTableEntry *type_entry);
2222TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint32_t size_in_bits);
......@@ -26,7 +26,7 @@ TypeTableEntry *get_c_int_type(CodeGen *g, CIntType c_int_type);
2626TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id);
2727TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type);
2828TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size);
29TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
29TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *ptr_type);
3030TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind,
3131 AstNode *decl_node, const char *name, ContainerLayout layout);
3232TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);
......@@ -171,4 +171,7 @@ bool calling_convention_does_first_arg_return(CallingConvention cc);
171171LinkLib *add_link_lib(CodeGen *codegen, Buf *lib);
172172void add_link_lib_symbol(CodeGen *g, Buf *lib_name, Buf *symbol_name);
173173
174uint32_t get_abi_alignment(CodeGen *g, TypeTableEntry *type_entry);
175TypeTableEntry *get_align_amt_type(CodeGen *g);
176
174177#endif
src/ast_render.cpp+34-4
......@@ -65,10 +65,6 @@ static const char *prefix_op_str(PrefixOp prefix_op) {
6565 case PrefixOpNegationWrap: return "-%";
6666 case PrefixOpBoolNot: return "!";
6767 case PrefixOpBinNot: return "~";
68 case PrefixOpAddressOf: return "&";
69 case PrefixOpConstAddressOf: return "&const ";
70 case PrefixOpVolatileAddressOf: return "&volatile ";
71 case PrefixOpConstVolatileAddressOf: return "&const volatile ";
7268 case PrefixOpDereference: return "*";
7369 case PrefixOpMaybe: return "?";
7470 case PrefixOpError: return "%";
......@@ -192,6 +188,8 @@ static const char *node_type_str(NodeType node_type) {
192188 return "Symbol";
193189 case NodeTypePrefixOpExpr:
194190 return "PrefixOpExpr";
191 case NodeTypeAddrOfExpr:
192 return "AddrOfExpr";
195193 case NodeTypeUse:
196194 return "Use";
197195 case NodeTypeBoolLiteral:
......@@ -583,6 +581,38 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
583581 render_node_ungrouped(ar, node->data.prefix_op_expr.primary_expr);
584582 break;
585583 }
584 case NodeTypeAddrOfExpr:
585 {
586 fprintf(ar->f, "&");
587 if (node->data.addr_of_expr.align_expr != nullptr) {
588 fprintf(ar->f, "align ");
589 render_node_grouped(ar, node->data.addr_of_expr.align_expr);
590 if (node->data.addr_of_expr.bit_offset_start != nullptr) {
591 assert(node->data.addr_of_expr.bit_offset_end != nullptr);
592
593 Buf offset_start_buf = BUF_INIT;
594 buf_resize(&offset_start_buf, 0);
595 bigint_append_buf(&offset_start_buf, node->data.addr_of_expr.bit_offset_start, 10);
596
597 Buf offset_end_buf = BUF_INIT;
598 buf_resize(&offset_end_buf, 0);
599 bigint_append_buf(&offset_end_buf, node->data.addr_of_expr.bit_offset_end, 10);
600
601 fprintf(ar->f, ":%s:%s ", buf_ptr(&offset_start_buf), buf_ptr(&offset_end_buf));
602 } else {
603 fprintf(ar->f, " ");
604 }
605 }
606 if (node->data.addr_of_expr.is_const) {
607 fprintf(ar->f, "const ");
608 }
609 if (node->data.addr_of_expr.is_volatile) {
610 fprintf(ar->f, "volatile ");
611 }
612
613 render_node_ungrouped(ar, node->data.addr_of_expr.op_expr);
614 break;
615 }
586616 case NodeTypeFnCallExpr:
587617 {
588618 if (node->data.fn_call_expr.is_builtin) {
src/codegen.cpp+104-120
......@@ -350,6 +350,12 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
350350 zig_unreachable();
351351}
352352
353static uint32_t get_pref_fn_align(CodeGen *g, LLVMTypeRef fn_type_ref) {
354 uint32_t pref_align = LLVMPreferredAlignmentOfType(g->target_data_ref, fn_type_ref);
355 uint32_t abi_align = LLVMABIAlignmentOfType(g->target_data_ref, fn_type_ref);
356 return (pref_align > abi_align) ? pref_align : abi_align;
357}
358
353359static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
354360 if (fn_table_entry->llvm_value)
355361 return fn_table_entry->llvm_value;
......@@ -442,14 +448,14 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
442448 if (fn_table_entry->section_name) {
443449 LLVMSetSection(fn_table_entry->llvm_value, buf_ptr(fn_table_entry->section_name));
444450 }
445 if (fn_table_entry->alignment) {
446 LLVMSetAlignment(fn_table_entry->llvm_value, (unsigned)fn_table_entry->alignment);
447 } else if (external_linkage) {
451 if (fn_table_entry->align_bytes > 0) {
452 LLVMSetAlignment(fn_table_entry->llvm_value, (unsigned)fn_table_entry->align_bytes);
453 } else if (fn_table_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionUnspecified) {
448454 LLVMSetAlignment(fn_table_entry->llvm_value,
449 LLVMABIAlignmentOfType(g->target_data_ref, fn_table_entry->type_entry->data.fn.raw_type_ref));
455 get_pref_fn_align(g, fn_table_entry->type_entry->data.fn.raw_type_ref));
450456 } else {
451457 LLVMSetAlignment(fn_table_entry->llvm_value,
452 LLVMPreferredAlignmentOfType(g->target_data_ref, fn_table_entry->type_entry->data.fn.raw_type_ref));
458 LLVMABIAlignmentOfType(g->target_data_ref, fn_table_entry->type_entry->data.fn.raw_type_ref));
453459 }
454460
455461 return fn_table_entry->llvm_value;
......@@ -604,13 +610,15 @@ static LLVMValueRef get_floor_ceil_fn(CodeGen *g, TypeTableEntry *type_entry, Zi
604610 return fn_val;
605611}
606612
607static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *type, bool is_volatile) {
613static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *type, TypeTableEntry *ptr_type) {
608614 if (type_has_bits(type)) {
609615 if (handle_is_ptr(type)) {
610616 return ptr;
611617 } else {
618 assert(ptr_type->id == TypeTableEntryIdPointer);
612619 LLVMValueRef result = LLVMBuildLoad(g->builder, ptr, "");
613 LLVMSetVolatile(result, is_volatile);
620 LLVMSetVolatile(result, ptr_type->data.pointer.is_volatile);
621 LLVMSetAlignment(result, ptr_type->data.pointer.alignment);
614622 return result;
615623 }
616624 } else {
......@@ -657,34 +665,6 @@ static bool ir_want_debug_safety(CodeGen *g, IrInstruction *instruction) {
657665 return true;
658666}
659667
660static bool is_array_of_at_least_n_bytes(CodeGen *g, TypeTableEntry *type_entry, uint32_t n) {
661 if (type_entry->id != TypeTableEntryIdArray)
662 return false;
663
664 TypeTableEntry *child_type = type_entry->data.array.child_type;
665 if (child_type->id != TypeTableEntryIdInt)
666 return false;
667
668 if (child_type != g->builtin_types.entry_u8)
669 return false;
670
671 if (type_entry->data.array.len < n)
672 return false;
673
674 return true;
675}
676
677static uint32_t get_type_alignment(CodeGen *g, TypeTableEntry *type_entry) {
678 uint32_t alignment = ZigLLVMGetPrefTypeAlignment(g->target_data_ref, type_entry->type_ref);
679 uint32_t dbl_ptr_bytes = g->pointer_size_bytes * 2;
680 if (is_array_of_at_least_n_bytes(g, type_entry, dbl_ptr_bytes)) {
681 return (alignment < dbl_ptr_bytes) ? dbl_ptr_bytes : alignment;
682 } else {
683 return alignment;
684 }
685}
686
687
688668static Buf *panic_msg_buf(PanicMsgId msg_id) {
689669 switch (msg_id) {
690670 case PanicMsgIdCount:
......@@ -745,7 +725,8 @@ static void gen_panic_raw(CodeGen *g, LLVMValueRef msg_ptr, LLVMValueRef msg_len
745725}
746726
747727static void gen_panic(CodeGen *g, LLVMValueRef msg_arg) {
748 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
728 TypeTableEntry *ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
729 TypeTableEntry *str_type = get_slice_type(g, ptr_type);
749730 size_t ptr_index = str_type->data.structure.fields[slice_ptr_index].gen_index;
750731 size_t len_index = str_type->data.structure.fields[slice_len_index].gen_index;
751732 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, msg_arg, (unsigned)ptr_index, "");
......@@ -806,7 +787,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
806787 LLVMSetLinkage(global_value, LLVMInternalLinkage);
807788 LLVMSetGlobalConstant(global_value, false);
808789 LLVMSetUnnamedAddr(global_value, true);
809 LLVMSetAlignment(global_value, get_type_alignment(g, g->builtin_types.entry_u8));
790 LLVMSetAlignment(global_value, get_abi_alignment(g, g->builtin_types.entry_u8));
810791
811792 TypeTableEntry *usize = g->builtin_types.entry_usize;
812793 LLVMValueRef full_buf_ptr_indices[] = {
......@@ -833,7 +814,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
833814 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true");
834815 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr);
835816 }
836 LLVMSetAlignment(fn_val, LLVMPreferredAlignmentOfType(g->target_data_ref, fn_type_ref));
817 LLVMSetAlignment(fn_val, get_pref_fn_align(g, fn_type_ref));
837818
838819 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry");
839820 LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder);
......@@ -1056,50 +1037,49 @@ static LLVMRealPredicate cmp_op_to_real_predicate(IrBinOp cmp_op) {
10561037 }
10571038}
10581039
1059static LLVMValueRef gen_struct_memcpy(CodeGen *g, LLVMValueRef src, LLVMValueRef dest,
1060 TypeTableEntry *type_entry)
1061{
1062 assert(handle_is_ptr(type_entry));
1063
1064 assert(LLVMGetTypeKind(LLVMTypeOf(src)) == LLVMPointerTypeKind);
1065 assert(LLVMGetTypeKind(LLVMTypeOf(dest)) == LLVMPointerTypeKind);
1066
1067 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
1068
1069 LLVMValueRef src_ptr = LLVMBuildBitCast(g->builder, src, ptr_u8, "");
1070 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, dest, ptr_u8, "");
1071
1072 TypeTableEntry *usize = g->builtin_types.entry_usize;
1073 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref);
1074 uint64_t align_bytes = get_type_alignment(g, type_entry);
1075 assert(size_bytes > 0);
1076 assert(align_bytes > 0);
1077
1078 LLVMValueRef params[] = {
1079 dest_ptr, // dest pointer
1080 src_ptr, // source pointer
1081 LLVMConstInt(usize->type_ref, size_bytes, false),
1082 LLVMConstInt(LLVMInt32Type(), align_bytes, false),
1083 LLVMConstNull(LLVMInt1Type()), // is volatile
1084 };
1085
1086 return LLVMBuildCall(g->builder, get_memcpy_fn_val(g), params, 5, "");
1087}
1088
10891040static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *ptr_type,
10901041 LLVMValueRef value)
10911042{
1043 assert(ptr_type->id == TypeTableEntryIdPointer);
10921044 TypeTableEntry *child_type = ptr_type->data.pointer.child_type;
10931045
10941046 if (!type_has_bits(child_type))
10951047 return nullptr;
10961048
1097 if (handle_is_ptr(child_type))
1098 return gen_struct_memcpy(g, value, ptr, child_type);
1049 if (handle_is_ptr(child_type)) {
1050 assert(LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMPointerTypeKind);
1051 assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind);
1052
1053 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
1054
1055 LLVMValueRef src_ptr = LLVMBuildBitCast(g->builder, value, ptr_u8, "");
1056 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, ptr, ptr_u8, "");
1057
1058 TypeTableEntry *usize = g->builtin_types.entry_usize;
1059 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, child_type->type_ref);
1060 uint64_t align_bytes = ptr_type->data.pointer.alignment;
1061 assert(size_bytes > 0);
1062 assert(align_bytes > 0);
1063
1064 LLVMValueRef volatile_bit = ptr_type->data.pointer.is_volatile ?
1065 LLVMConstAllOnes(LLVMInt1Type()) : LLVMConstNull(LLVMInt1Type());
1066
1067 LLVMValueRef params[] = {
1068 dest_ptr, // dest pointer
1069 src_ptr, // source pointer
1070 LLVMConstInt(usize->type_ref, size_bytes, false),
1071 LLVMConstInt(LLVMInt32Type(), align_bytes, false),
1072 volatile_bit,
1073 };
1074
1075 LLVMBuildCall(g->builder, get_memcpy_fn_val(g), params, 5, "");
1076 return nullptr;
1077 }
10991078
11001079 uint32_t unaligned_bit_count = ptr_type->data.pointer.unaligned_bit_count;
11011080 if (unaligned_bit_count == 0) {
11021081 LLVMValueRef llvm_instruction = LLVMBuildStore(g->builder, value, ptr);
1082 LLVMSetAlignment(llvm_instruction, ptr_type->data.pointer.alignment);
11031083 LLVMSetVolatile(llvm_instruction, ptr_type->data.pointer.is_volatile);
11041084 return nullptr;
11051085 }
......@@ -1122,6 +1102,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, TypeTableEntry
11221102 LLVMValueRef ored_value = LLVMBuildOr(g->builder, shifted_value, anded_containing_int, "");
11231103
11241104 LLVMValueRef llvm_instruction = LLVMBuildStore(g->builder, ored_value, ptr);
1105 LLVMSetAlignment(llvm_instruction, ptr_type->data.pointer.alignment);
11251106 LLVMSetVolatile(llvm_instruction, ptr_type->data.pointer.is_volatile);
11261107 return nullptr;
11271108}
......@@ -2010,23 +1991,24 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
20101991
20111992 if (have_init_expr) {
20121993 assert(var->value->type == init_value->value.type);
2013 gen_assign_raw(g, var->value_ref, get_pointer_to_type(g, var->value->type, false),
2014 ir_llvm_value(g, init_value));
1994 TypeTableEntry *var_ptr_type = get_pointer_to_type_extra(g, var->value->type, false, false,
1995 var->align_bytes, 0, 0);
1996 gen_assign_raw(g, var->value_ref, var_ptr_type, ir_llvm_value(g, init_value));
20151997 } else {
2016 bool ignore_uninit = false;
2017 // handle runtime stack allocation
20181998 bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base);
2019 if (!ignore_uninit && want_safe) {
1999 if (want_safe) {
20202000 TypeTableEntry *usize = g->builtin_types.entry_usize;
20212001 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value->type->type_ref);
2022 uint64_t align_bytes = get_type_alignment(g, var->value->type);
2002 assert(size_bytes > 0);
2003
2004 assert(var->align_bytes > 0);
20232005
20242006 // memset uninitialized memory to 0xa
20252007 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
20262008 LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
20272009 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, var->value_ref, ptr_u8, "");
20282010 LLVMValueRef byte_count = LLVMConstInt(usize->type_ref, size_bytes, false);
2029 LLVMValueRef align_in_bytes = LLVMConstInt(LLVMInt32Type(), align_bytes, false);
2011 LLVMValueRef align_in_bytes = LLVMConstInt(LLVMInt32Type(), var->align_bytes, false);
20302012 LLVMValueRef params[] = {
20312013 dest_ptr,
20322014 fill_char,
......@@ -2051,15 +2033,14 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI
20512033 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
20522034 TypeTableEntry *ptr_type = instruction->ptr->value.type;
20532035 assert(ptr_type->id == TypeTableEntryIdPointer);
2054 bool is_volatile = ptr_type->data.pointer.is_volatile;
20552036
20562037 uint32_t unaligned_bit_count = ptr_type->data.pointer.unaligned_bit_count;
20572038 if (unaligned_bit_count == 0)
2058 return get_handle_value(g, ptr, child_type, is_volatile);
2039 return get_handle_value(g, ptr, child_type, ptr_type);
20592040
20602041 assert(!handle_is_ptr(child_type));
20612042 LLVMValueRef containing_int = LLVMBuildLoad(g->builder, ptr, "");
2062 LLVMSetVolatile(containing_int, is_volatile);
2043 LLVMSetVolatile(containing_int, ptr_type->data.pointer.is_volatile);
20632044
20642045 uint32_t bit_offset = ptr_type->data.pointer.bit_offset;
20652046 uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int));
......@@ -2097,9 +2078,8 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
20972078 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr);
20982079 TypeTableEntry *array_ptr_type = instruction->array_ptr->value.type;
20992080 assert(array_ptr_type->id == TypeTableEntryIdPointer);
2100 bool is_volatile = array_ptr_type->data.pointer.is_volatile;
21012081 TypeTableEntry *array_type = array_ptr_type->data.pointer.child_type;
2102 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, is_volatile);
2082 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);
21032083 LLVMValueRef subscript_value = ir_llvm_value(g, instruction->elem_index);
21042084 assert(subscript_value);
21052085
......@@ -2427,12 +2407,11 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,
24272407{
24282408 TypeTableEntry *ptr_type = instruction->value->value.type;
24292409 assert(ptr_type->id == TypeTableEntryIdPointer);
2430 bool is_volatile = ptr_type->data.pointer.is_volatile;
24312410 TypeTableEntry *maybe_type = ptr_type->data.pointer.child_type;
24322411 assert(maybe_type->id == TypeTableEntryIdMaybe);
24332412 TypeTableEntry *child_type = maybe_type->data.maybe.child_type;
24342413 LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value);
2435 LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, is_volatile);
2414 LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);
24362415 if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on) {
24372416 LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);
24382417 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeOk");
......@@ -2451,7 +2430,7 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,
24512430 if (maybe_is_ptr) {
24522431 return maybe_ptr;
24532432 } else {
2454 LLVMValueRef maybe_struct_ref = get_handle_value(g, maybe_ptr, maybe_type, is_volatile);
2433 LLVMValueRef maybe_struct_ref = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);
24552434 return LLVMBuildStructGEP(g->builder, maybe_struct_ref, maybe_child_index, "");
24562435 }
24572436 }
......@@ -2694,11 +2673,13 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns
26942673 LLVMValueRef is_volatile = ptr_type->data.pointer.is_volatile ?
26952674 LLVMConstAllOnes(LLVMInt1Type()) : LLVMConstNull(LLVMInt1Type());
26962675
2676 LLVMValueRef align_val = LLVMConstInt(LLVMInt32Type(), ptr_type->data.pointer.alignment, false);
2677
26972678 LLVMValueRef params[] = {
2698 dest_ptr_casted, // dest pointer
2699 char_val, // source pointer
2700 len_val, // byte count
2701 LLVMConstInt(LLVMInt32Type(), 1, false), // align in bytes
2679 dest_ptr_casted,
2680 char_val,
2681 len_val,
2682 align_val,
27022683 is_volatile,
27032684 };
27042685
......@@ -2725,11 +2706,14 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns
27252706 LLVMValueRef is_volatile = (dest_ptr_type->data.pointer.is_volatile || src_ptr_type->data.pointer.is_volatile) ?
27262707 LLVMConstAllOnes(LLVMInt1Type()) : LLVMConstNull(LLVMInt1Type());
27272708
2709 uint32_t min_align_bytes = min(src_ptr_type->data.pointer.alignment, dest_ptr_type->data.pointer.alignment);
2710 LLVMValueRef align_val = LLVMConstInt(LLVMInt32Type(), min_align_bytes, false);
2711
27282712 LLVMValueRef params[] = {
2729 dest_ptr_casted, // dest pointer
2730 src_ptr_casted, // source pointer
2731 len_val, // byte count
2732 LLVMConstInt(LLVMInt32Type(), 1, false), // align in bytes
2713 dest_ptr_casted,
2714 src_ptr_casted,
2715 len_val,
2716 align_val,
27332717 is_volatile,
27342718 };
27352719
......@@ -2743,9 +2727,8 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
27432727 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr);
27442728 TypeTableEntry *array_ptr_type = instruction->ptr->value.type;
27452729 assert(array_ptr_type->id == TypeTableEntryIdPointer);
2746 bool is_volatile = array_ptr_type->data.pointer.is_volatile;
27472730 TypeTableEntry *array_type = array_ptr_type->data.pointer.child_type;
2748 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, is_volatile);
2731 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type);
27492732
27502733 LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;
27512734
......@@ -2989,11 +2972,10 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI
29892972static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrCode *instruction) {
29902973 TypeTableEntry *ptr_type = instruction->value->value.type;
29912974 assert(ptr_type->id == TypeTableEntryIdPointer);
2992 bool is_volatile = ptr_type->data.pointer.is_volatile;
29932975 TypeTableEntry *err_union_type = ptr_type->data.pointer.child_type;
29942976 TypeTableEntry *child_type = err_union_type->data.error.child_type;
29952977 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);
2996 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, is_volatile);
2978 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
29972979
29982980 if (type_has_bits(child_type)) {
29992981 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
......@@ -3006,11 +2988,10 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab
30062988static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrPayload *instruction) {
30072989 TypeTableEntry *ptr_type = instruction->value->value.type;
30082990 assert(ptr_type->id == TypeTableEntryIdPointer);
3009 bool is_volatile = ptr_type->data.pointer.is_volatile;
30102991 TypeTableEntry *err_union_type = ptr_type->data.pointer.child_type;
30112992 TypeTableEntry *child_type = err_union_type->data.error.child_type;
30122993 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);
3013 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, is_volatile);
2994 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
30142995
30152996 if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on && g->error_decls.length > 1) {
30162997 LLVMValueRef err_val;
......@@ -3123,7 +3104,8 @@ static LLVMValueRef ir_render_enum_tag(CodeGen *g, IrExecutable *executable, IrI
31233104 return enum_val;
31243105
31253106 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, enum_val, enum_type->data.enumeration.gen_tag_index, "");
3126 return get_handle_value(g, tag_field_ptr, tag_type, false);
3107 TypeTableEntry *ptr_type = get_pointer_to_type(g, tag_type, false);
3108 return get_handle_value(g, tag_field_ptr, tag_type, ptr_type);
31273109}
31283110
31293111static LLVMValueRef ir_render_init_enum(CodeGen *g, IrExecutable *executable, IrInstructionInitEnum *instruction) {
......@@ -3164,8 +3146,10 @@ static LLVMValueRef ir_render_struct_init(CodeGen *g, IrExecutable *executable,
31643146 (unsigned)type_struct_field->gen_index, "");
31653147 LLVMValueRef value = ir_llvm_value(g, field->value);
31663148
3149 uint32_t field_align_bytes = get_abi_alignment(g, type_struct_field->type_entry);
3150
31673151 TypeTableEntry *ptr_type = get_pointer_to_type_extra(g, type_struct_field->type_entry,
3168 false, false,
3152 false, false, field_align_bytes,
31693153 (uint32_t)type_struct_field->packed_bits_offset, (uint32_t)type_struct_field->unaligned_bit_count);
31703154
31713155 gen_assign_raw(g, field_ptr, ptr_type, value);
......@@ -3243,15 +3227,13 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
32433227 case IrInstructionIdEmbedFile:
32443228 case IrInstructionIdIntType:
32453229 case IrInstructionIdMemberCount:
3246 case IrInstructionIdPreferredAlignOf:
3247 case IrInstructionIdAbiAlignOf:
3230 case IrInstructionIdAlignOf:
32483231 case IrInstructionIdFnProto:
32493232 case IrInstructionIdTestComptime:
32503233 case IrInstructionIdCheckSwitchProngs:
32513234 case IrInstructionIdCheckStatementIsVoid:
32523235 case IrInstructionIdTypeName:
32533236 case IrInstructionIdCanImplicitCast:
3254 case IrInstructionIdSetGlobalAlign:
32553237 case IrInstructionIdSetGlobalSection:
32563238 case IrInstructionIdSetGlobalLinkage:
32573239 case IrInstructionIdDeclRef:
......@@ -3259,6 +3241,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
32593241 case IrInstructionIdOffsetOf:
32603242 case IrInstructionIdTypeId:
32613243 case IrInstructionIdSetEvalBranchQuota:
3244 case IrInstructionIdPtrTypeOf:
32623245 zig_unreachable();
32633246 case IrInstructionIdReturn:
32643247 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
......@@ -3840,7 +3823,7 @@ static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const
38403823 LLVMSetLinkage(global_value, LLVMInternalLinkage);
38413824 LLVMSetGlobalConstant(global_value, true);
38423825 LLVMSetUnnamedAddr(global_value, true);
3843 LLVMSetAlignment(global_value, get_type_alignment(g, const_val->type));
3826 LLVMSetAlignment(global_value, get_abi_alignment(g, const_val->type));
38443827
38453828 const_val->global_refs->llvm_global = global_value;
38463829 }
......@@ -3856,8 +3839,8 @@ static void generate_error_name_table(CodeGen *g) {
38563839
38573840 assert(g->error_decls.length > 0);
38583841
3859 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
3860 TypeTableEntry *u8_ptr_type = str_type->data.structure.fields[0].type_entry;
3842 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
3843 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);
38613844
38623845 LLVMValueRef *values = allocate<LLVMValueRef>(g->error_decls.length);
38633846 values[0] = LLVMGetUndef(str_type->type_ref);
......@@ -3893,8 +3876,8 @@ static void generate_error_name_table(CodeGen *g) {
38933876}
38943877
38953878static void generate_enum_name_tables(CodeGen *g) {
3896 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
3897 TypeTableEntry *u8_ptr_type = str_type->data.structure.fields[0].type_entry;
3879 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
3880 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);
38983881
38993882 for (size_t enum_i = 0; enum_i < g->name_table_enums.length; enum_i += 1) {
39003883 TypeTableEntry *enum_tag_type = g->name_table_enums.at(enum_i);
......@@ -3965,9 +3948,10 @@ static void gen_global_var(CodeGen *g, VariableTableEntry *var, LLVMValueRef ini
39653948 // TODO ^^ make an actual global variable
39663949}
39673950
3968static LLVMValueRef build_alloca(CodeGen *g, TypeTableEntry *type_entry, const char *name) {
3951static LLVMValueRef build_alloca(CodeGen *g, TypeTableEntry *type_entry, const char *name, uint32_t alignment) {
3952 assert(alignment > 0);
39693953 LLVMValueRef result = LLVMBuildAlloca(g->builder, type_entry->type_ref, name);
3970 LLVMSetAlignment(result, get_type_alignment(g, type_entry));
3954 LLVMSetAlignment(result, alignment);
39713955 return result;
39723956}
39733957
......@@ -4056,6 +4040,7 @@ static void do_code_gen(CodeGen *g) {
40564040 // TODO debug info for the extern variable
40574041
40584042 LLVMSetLinkage(global_value, LLVMExternalLinkage);
4043 LLVMSetAlignment(global_value, var->align_bytes);
40594044 } else {
40604045 bool exported = (var->linkage == VarLinkageExport);
40614046 render_const_val(g, var->value);
......@@ -4068,8 +4053,7 @@ static void do_code_gen(CodeGen *g) {
40684053 if (tld_var->section_name) {
40694054 LLVMSetSection(global_value, buf_ptr(tld_var->section_name));
40704055 }
4071 LLVMSetAlignment(global_value, tld_var->alignment ?
4072 tld_var->alignment : get_type_alignment(g, var->value->type));
4056 LLVMSetAlignment(global_value, var->align_bytes);
40734057
40744058 // TODO debug info for function pointers
40754059 if (var->gen_is_const && var->value->type->id != TypeTableEntryIdFn) {
......@@ -4189,7 +4173,7 @@ static void do_code_gen(CodeGen *g) {
41894173 } else {
41904174 zig_unreachable();
41914175 }
4192 *slot = build_alloca(g, slot_type, "");
4176 *slot = build_alloca(g, slot_type, "", get_abi_alignment(g, slot_type));
41934177 }
41944178
41954179 ImportTableEntry *import = get_scope_import(&fn_table_entry->fndef_scope->base);
......@@ -4207,7 +4191,7 @@ static void do_code_gen(CodeGen *g) {
42074191 continue;
42084192
42094193 if (var->src_arg_index == SIZE_MAX) {
4210 var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name));
4194 var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name), var->align_bytes);
42114195
42124196 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
42134197 buf_ptr(&var->name), import->di_file, (unsigned)(var->decl_node->line + 1),
......@@ -4227,7 +4211,7 @@ static void do_code_gen(CodeGen *g) {
42274211 var->value_ref = LLVMGetParam(fn, (unsigned)var->gen_arg_index);
42284212 } else {
42294213 gen_type = var->value->type;
4230 var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name));
4214 var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name), var->align_bytes);
42314215 }
42324216 if (var->decl_node) {
42334217 var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
......@@ -4309,6 +4293,7 @@ static void do_code_gen(CodeGen *g) {
43094293}
43104294
43114295static const uint8_t int_sizes_in_bits[] = {
4296 2,
43124297 3,
43134298 4,
43144299 5,
......@@ -4605,8 +4590,7 @@ static void define_builtin_fns(CodeGen *g) {
46054590 create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy", 3);
46064591 create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3);
46074592 create_builtin_fn(g, BuiltinFnIdSizeof, "sizeOf", 1);
4608 create_builtin_fn(g, BuiltinFnIdPreferredAlignOf, "preferredAlignOf", 1);
4609 create_builtin_fn(g, BuiltinFnIdAbiAlignOf, "cAbiAlignOf", 1);
4593 create_builtin_fn(g, BuiltinFnIdAlignOf, "alignOf", 1);
46104594 create_builtin_fn(g, BuiltinFnIdMaxValue, "maxValue", 1);
46114595 create_builtin_fn(g, BuiltinFnIdMinValue, "minValue", 1);
46124596 create_builtin_fn(g, BuiltinFnIdMemberCount, "memberCount", 1);
......@@ -4634,7 +4618,6 @@ static void define_builtin_fns(CodeGen *g) {
46344618 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2);
46354619 create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);
46364620 create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2);
4637 create_builtin_fn(g, BuiltinFnIdSetGlobalAlign, "setGlobalAlign", 2);
46384621 create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
46394622 create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2);
46404623 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
......@@ -4989,7 +4972,8 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
49894972 exit(0);
49904973 }
49914974
4992 TypeTableEntry *str_type = get_slice_type(g, g->builtin_types.entry_u8, true);
4975 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true);
4976 TypeTableEntry *str_type = get_slice_type(g, u8_ptr_type);
49934977 TypeTableEntry *fn_type = get_test_fn_type(g);
49944978
49954979 const char *field_names[] = { "name", "func", };
src/ir.cpp+304-275
......@@ -51,6 +51,7 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc
5151static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction);
5252static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *expected_type);
5353static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr);
54static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg);
5455
5556ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) {
5657 assert(const_val->type->id == TypeTableEntryIdPointer);
......@@ -422,12 +423,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameAddress *)
422423 return IrInstructionIdFrameAddress;
423424}
424425
425static constexpr IrInstructionId ir_instruction_id(IrInstructionPreferredAlignOf *) {
426 return IrInstructionIdPreferredAlignOf;
427}
428
429static constexpr IrInstructionId ir_instruction_id(IrInstructionAbiAlignOf *) {
430 return IrInstructionIdAbiAlignOf;
426static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignOf *) {
427 return IrInstructionIdAlignOf;
431428}
432429
433430static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) {
......@@ -518,10 +515,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCanImplicitCast
518515 return IrInstructionIdCanImplicitCast;
519516}
520517
521static constexpr IrInstructionId ir_instruction_id(IrInstructionSetGlobalAlign *) {
522 return IrInstructionIdSetGlobalAlign;
523}
524
525518static constexpr IrInstructionId ir_instruction_id(IrInstructionSetGlobalSection *) {
526519 return IrInstructionIdSetGlobalSection;
527520}
......@@ -558,6 +551,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetEvalBranchQuo
558551 return IrInstructionIdSetEvalBranchQuota;
559552}
560553
554static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeOf *) {
555 return IrInstructionIdPtrTypeOf;
556}
557
561558template<typename T>
562559static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
563560 T *special_instruction = allocate<T>(1);
......@@ -988,6 +985,24 @@ static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instru
988985 return new_instruction;
989986}
990987
988static IrInstruction *ir_build_ptr_type_of(IrBuilder *irb, Scope *scope, AstNode *source_node,
989 IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value,
990 uint32_t bit_offset_start, uint32_t bit_offset_end)
991{
992 IrInstructionPtrTypeOf *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrTypeOf>(irb, scope, source_node);
993 ptr_type_of_instruction->align_value = align_value;
994 ptr_type_of_instruction->child_type = child_type;
995 ptr_type_of_instruction->is_const = is_const;
996 ptr_type_of_instruction->is_volatile = is_volatile;
997 ptr_type_of_instruction->bit_offset_start = bit_offset_start;
998 ptr_type_of_instruction->bit_offset_end = bit_offset_end;
999
1000 ir_ref_instruction(align_value, irb->current_basic_block);
1001 ir_ref_instruction(child_type, irb->current_basic_block);
1002
1003 return &ptr_type_of_instruction->base;
1004}
1005
9911006static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, IrInstruction *value) {
9921007 IrInstructionUnOp *br_instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node);
9931008 br_instruction->op_id = op_id;
......@@ -1112,26 +1127,28 @@ static IrInstruction *ir_build_store_ptr_from(IrBuilder *irb, IrInstruction *old
11121127}
11131128
11141129static IrInstruction *ir_build_var_decl(IrBuilder *irb, Scope *scope, AstNode *source_node,
1115 VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value)
1130 VariableTableEntry *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value)
11161131{
11171132 IrInstructionDeclVar *decl_var_instruction = ir_build_instruction<IrInstructionDeclVar>(irb, scope, source_node);
11181133 decl_var_instruction->base.value.special = ConstValSpecialStatic;
11191134 decl_var_instruction->base.value.type = irb->codegen->builtin_types.entry_void;
11201135 decl_var_instruction->var = var;
11211136 decl_var_instruction->var_type = var_type;
1137 decl_var_instruction->align_value = align_value;
11221138 decl_var_instruction->init_value = init_value;
11231139
11241140 if (var_type) ir_ref_instruction(var_type, irb->current_basic_block);
1141 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block);
11251142 ir_ref_instruction(init_value, irb->current_basic_block);
11261143
11271144 return &decl_var_instruction->base;
11281145}
11291146
11301147static IrInstruction *ir_build_var_decl_from(IrBuilder *irb, IrInstruction *old_instruction,
1131 VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value)
1148 VariableTableEntry *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value)
11321149{
11331150 IrInstruction *new_instruction = ir_build_var_decl(irb, old_instruction->scope,
1134 old_instruction->source_node, var, var_type, init_value);
1151 old_instruction->source_node, var, var_type, align_value, init_value);
11351152 ir_link_new_instruction(new_instruction, old_instruction);
11361153 return new_instruction;
11371154}
......@@ -1221,14 +1238,17 @@ static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode
12211238 return &instruction->base;
12221239}
12231240
1224static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node, bool is_const,
1225 IrInstruction *child_type)
1241static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
1242 IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value)
12261243{
12271244 IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, scope, source_node);
12281245 instruction->is_const = is_const;
1246 instruction->is_volatile = is_volatile;
12291247 instruction->child_type = child_type;
1248 instruction->align_value = align_value;
12301249
12311250 ir_ref_instruction(child_type, irb->current_basic_block);
1251 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block);
12321252
12331253 return &instruction->base;
12341254}
......@@ -1810,17 +1830,8 @@ static IrInstruction *ir_build_overflow_op_from(IrBuilder *irb, IrInstruction *o
18101830 return new_instruction;
18111831}
18121832
1813static IrInstruction *ir_build_preferred_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) {
1814 IrInstructionPreferredAlignOf *instruction = ir_build_instruction<IrInstructionPreferredAlignOf>(irb, scope, source_node);
1815 instruction->type_value = type_value;
1816
1817 ir_ref_instruction(type_value, irb->current_basic_block);
1818
1819 return &instruction->base;
1820}
1821
1822static IrInstruction *ir_build_abi_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) {
1823 IrInstructionAbiAlignOf *instruction = ir_build_instruction<IrInstructionAbiAlignOf>(irb, scope, source_node);
1833static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) {
1834 IrInstructionAlignOf *instruction = ir_build_instruction<IrInstructionAlignOf>(irb, scope, source_node);
18241835 instruction->type_value = type_value;
18251836
18261837 ir_ref_instruction(type_value, irb->current_basic_block);
......@@ -2097,19 +2108,6 @@ static IrInstruction *ir_build_can_implicit_cast(IrBuilder *irb, Scope *scope, A
20972108 return &instruction->base;
20982109}
20992110
2100static IrInstruction *ir_build_set_global_align(IrBuilder *irb, Scope *scope, AstNode *source_node,
2101 Tld *tld, IrInstruction *value)
2102{
2103 IrInstructionSetGlobalAlign *instruction = ir_build_instruction<IrInstructionSetGlobalAlign>(
2104 irb, scope, source_node);
2105 instruction->tld = tld;
2106 instruction->value = value;
2107
2108 ir_ref_instruction(value, irb->current_basic_block);
2109
2110 return &instruction->base;
2111}
2112
21132111static IrInstruction *ir_build_set_global_section(IrBuilder *irb, Scope *scope, AstNode *source_node,
21142112 Tld *tld, IrInstruction *value)
21152113{
......@@ -2277,11 +2275,20 @@ static IrInstruction *ir_instruction_binop_get_dep(IrInstructionBinOp *instructi
22772275}
22782276
22792277static IrInstruction *ir_instruction_declvar_get_dep(IrInstructionDeclVar *instruction, size_t index) {
2280 switch (index) {
2281 case 0: return instruction->init_value;
2282 case 1: return instruction->var_type;
2283 default: return nullptr;
2278 if (index == 0) return instruction->init_value;
2279 index -= 1;
2280
2281 if (instruction->align_value != nullptr) {
2282 if (index == 0) return instruction->align_value;
2283 index -= 1;
2284 }
2285
2286 if (instruction->var_type != nullptr) {
2287 if (index == 0) return instruction->var_type;
2288 index -= 1;
22842289 }
2290
2291 return nullptr;
22852292}
22862293
22872294static IrInstruction *ir_instruction_loadptr_get_dep(IrInstructionLoadPtr *instruction, size_t index) {
......@@ -2671,14 +2678,7 @@ static IrInstruction *ir_instruction_frameaddress_get_dep(IrInstructionFrameAddr
26712678 return nullptr;
26722679}
26732680
2674static IrInstruction *ir_instruction_preferredalignof_get_dep(IrInstructionPreferredAlignOf *instruction, size_t index) {
2675 switch (index) {
2676 case 0: return instruction->type_value;
2677 default: return nullptr;
2678 }
2679}
2680
2681static IrInstruction *ir_instruction_abialignof_get_dep(IrInstructionAbiAlignOf *instruction, size_t index) {
2681static IrInstruction *ir_instruction_alignof_get_dep(IrInstructionAlignOf *instruction, size_t index) {
26822682 switch (index) {
26832683 case 0: return instruction->type_value;
26842684 default: return nullptr;
......@@ -2854,13 +2854,6 @@ static IrInstruction *ir_instruction_canimplicitcast_get_dep(IrInstructionCanImp
28542854 }
28552855}
28562856
2857static IrInstruction *ir_instruction_setglobalalign_get_dep(IrInstructionSetGlobalAlign *instruction, size_t index) {
2858 switch (index) {
2859 case 0: return instruction->value;
2860 default: return nullptr;
2861 }
2862}
2863
28642857static IrInstruction *ir_instruction_setglobalsection_get_dep(IrInstructionSetGlobalSection *instruction, size_t index) {
28652858 switch (index) {
28662859 case 0: return instruction->value;
......@@ -2924,6 +2917,14 @@ static IrInstruction *ir_instruction_setevalbranchquota_get_dep(IrInstructionSet
29242917 }
29252918}
29262919
2920static IrInstruction *ir_instruction_ptrtypeof_get_dep(IrInstructionPtrTypeOf *instruction, size_t index) {
2921 switch (index) {
2922 case 0: return instruction->align_value;
2923 case 1: return instruction->child_type;
2924 default: return nullptr;
2925 }
2926}
2927
29272928static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) {
29282929 switch (instruction->id) {
29292930 case IrInstructionIdInvalid:
......@@ -3056,10 +3057,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
30563057 return ir_instruction_returnaddress_get_dep((IrInstructionReturnAddress *) instruction, index);
30573058 case IrInstructionIdFrameAddress:
30583059 return ir_instruction_frameaddress_get_dep((IrInstructionFrameAddress *) instruction, index);
3059 case IrInstructionIdPreferredAlignOf:
3060 return ir_instruction_preferredalignof_get_dep((IrInstructionPreferredAlignOf *) instruction, index);
3061 case IrInstructionIdAbiAlignOf:
3062 return ir_instruction_abialignof_get_dep((IrInstructionAbiAlignOf *) instruction, index);
3060 case IrInstructionIdAlignOf:
3061 return ir_instruction_alignof_get_dep((IrInstructionAlignOf *) instruction, index);
30633062 case IrInstructionIdOverflowOp:
30643063 return ir_instruction_overflowop_get_dep((IrInstructionOverflowOp *) instruction, index);
30653064 case IrInstructionIdTestErr:
......@@ -3102,8 +3101,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
31023101 return ir_instruction_typename_get_dep((IrInstructionTypeName *) instruction, index);
31033102 case IrInstructionIdCanImplicitCast:
31043103 return ir_instruction_canimplicitcast_get_dep((IrInstructionCanImplicitCast *) instruction, index);
3105 case IrInstructionIdSetGlobalAlign:
3106 return ir_instruction_setglobalalign_get_dep((IrInstructionSetGlobalAlign *) instruction, index);
31073104 case IrInstructionIdSetGlobalSection:
31083105 return ir_instruction_setglobalsection_get_dep((IrInstructionSetGlobalSection *) instruction, index);
31093106 case IrInstructionIdSetGlobalLinkage:
......@@ -3122,6 +3119,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
31223119 return ir_instruction_typeid_get_dep((IrInstructionTypeId *) instruction, index);
31233120 case IrInstructionIdSetEvalBranchQuota:
31243121 return ir_instruction_setevalbranchquota_get_dep((IrInstructionSetEvalBranchQuota *) instruction, index);
3122 case IrInstructionIdPtrTypeOf:
3123 return ir_instruction_ptrtypeof_get_dep((IrInstructionPtrTypeOf *) instruction, index);
31253124 }
31263125 zig_unreachable();
31273126}
......@@ -4286,23 +4285,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
42864285 return ir_build_return_address(irb, scope, node);
42874286 case BuiltinFnIdFrameAddress:
42884287 return ir_build_frame_address(irb, scope, node);
4289 case BuiltinFnIdPreferredAlignOf:
4290 {
4291 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4292 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4293 if (arg0_value == irb->codegen->invalid_instruction)
4294 return arg0_value;
4295
4296 return ir_build_preferred_align_of(irb, scope, node, arg0_value);
4297 }
4298 case BuiltinFnIdAbiAlignOf:
4288 case BuiltinFnIdAlignOf:
42994289 {
43004290 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
43014291 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
43024292 if (arg0_value == irb->codegen->invalid_instruction)
43034293 return arg0_value;
43044294
4305 return ir_build_abi_align_of(irb, scope, node, arg0_value);
4295 return ir_build_align_of(irb, scope, node, arg0_value);
43064296 }
43074297 case BuiltinFnIdAddWithOverflow:
43084298 return ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd);
......@@ -4335,7 +4325,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43354325
43364326 return ir_build_can_implicit_cast(irb, scope, node, arg0_value, arg1_value);
43374327 }
4338 case BuiltinFnIdSetGlobalAlign:
43394328 case BuiltinFnIdSetGlobalSection:
43404329 case BuiltinFnIdSetGlobalLinkage:
43414330 {
......@@ -4361,9 +4350,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
43614350 if (arg1_value == irb->codegen->invalid_instruction)
43624351 return arg1_value;
43634352
4364 if (builtin_fn->id == BuiltinFnIdSetGlobalAlign) {
4365 return ir_build_set_global_align(irb, scope, node, tld, arg1_value);
4366 } else if (builtin_fn->id == BuiltinFnIdSetGlobalSection) {
4353 if (builtin_fn->id == BuiltinFnIdSetGlobalSection) {
43674354 return ir_build_set_global_section(irb, scope, node, tld, arg1_value);
43684355 } else if (builtin_fn->id == BuiltinFnIdSetGlobalLinkage) {
43694356 return ir_build_set_global_linkage(irb, scope, node, tld, arg1_value);
......@@ -4652,17 +4639,51 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *
46524639 return ir_build_ref(irb, scope, value->source_node, value, lval.is_const, lval.is_volatile);
46534640}
46544641
4655static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *node,
4656 bool is_const, bool is_volatile, LVal lval)
4657{
4658 assert(node->type == NodeTypePrefixOpExpr);
4659 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
4642static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *node) {
4643 assert(node->type == NodeTypeAddrOfExpr);
4644 bool is_const = node->data.addr_of_expr.is_const;
4645 bool is_volatile = node->data.addr_of_expr.is_volatile;
4646 AstNode *expr_node = node->data.addr_of_expr.op_expr;
4647 AstNode *align_expr = node->data.addr_of_expr.align_expr;
46604648
4661 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, make_lval_addr(is_const, is_volatile));
4662 if (value == irb->codegen->invalid_instruction)
4663 return value;
4649 if (align_expr == nullptr) {
4650 return ir_gen_node_extra(irb, expr_node, scope, make_lval_addr(is_const, is_volatile));
4651 }
4652
4653 IrInstruction *align_value = ir_gen_node(irb, align_expr, scope);
4654 if (align_value == irb->codegen->invalid_instruction)
4655 return align_value;
4656
4657 IrInstruction *child_type = ir_gen_node(irb, expr_node, scope);
4658 if (child_type == irb->codegen->invalid_instruction)
4659 return child_type;
4660
4661 uint32_t bit_offset_start = 0;
4662 if (node->data.addr_of_expr.bit_offset_start != nullptr) {
4663 if (!bigint_fits_in_bits(node->data.addr_of_expr.bit_offset_start, 32, false)) {
4664 Buf *val_buf = buf_alloc();
4665 bigint_append_buf(val_buf, node->data.addr_of_expr.bit_offset_start, 10);
4666 exec_add_error_node(irb->codegen, irb->exec, node,
4667 buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf)));
4668 return irb->codegen->invalid_instruction;
4669 }
4670 bit_offset_start = bigint_as_unsigned(node->data.addr_of_expr.bit_offset_start);
4671 }
4672
4673 uint32_t bit_offset_end = 0;
4674 if (node->data.addr_of_expr.bit_offset_end != nullptr) {
4675 if (!bigint_fits_in_bits(node->data.addr_of_expr.bit_offset_end, 32, false)) {
4676 Buf *val_buf = buf_alloc();
4677 bigint_append_buf(val_buf, node->data.addr_of_expr.bit_offset_end, 10);
4678 exec_add_error_node(irb->codegen, irb->exec, node,
4679 buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf)));
4680 return irb->codegen->invalid_instruction;
4681 }
4682 bit_offset_end = bigint_as_unsigned(node->data.addr_of_expr.bit_offset_end);
4683 }
46644684
4665 return ir_lval_wrap(irb, scope, value, lval);
4685 return ir_build_ptr_type_of(irb, scope, node, child_type, is_const, is_volatile,
4686 align_value, bit_offset_start, bit_offset_end);
46664687}
46674688
46684689static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
......@@ -4725,14 +4746,6 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod
47254746 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval);
47264747 case PrefixOpNegationWrap:
47274748 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval);
4728 case PrefixOpAddressOf:
4729 return ir_gen_address_of(irb, scope, node, false, false, lval);
4730 case PrefixOpConstAddressOf:
4731 return ir_gen_address_of(irb, scope, node, true, false, lval);
4732 case PrefixOpVolatileAddressOf:
4733 return ir_gen_address_of(irb, scope, node, false, true, lval);
4734 case PrefixOpConstVolatileAddressOf:
4735 return ir_gen_address_of(irb, scope, node, true, true, lval);
47364749 case PrefixOpDereference:
47374750 return ir_gen_prefix_op_id_lval(irb, scope, node, IrUnOpDereference, lval);
47384751 case PrefixOpMaybe:
......@@ -4822,11 +4835,18 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
48224835 return irb->codegen->invalid_instruction;
48234836 }
48244837
4838 IrInstruction *align_value = nullptr;
4839 if (variable_declaration->align_expr != nullptr) {
4840 align_value = ir_gen_node(irb, variable_declaration->align_expr, scope);
4841 if (align_value == irb->codegen->invalid_instruction)
4842 return align_value;
4843 }
4844
48254845 IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope);
48264846 if (init_value == irb->codegen->invalid_instruction)
48274847 return init_value;
48284848
4829 IrInstruction *result = ir_build_var_decl(irb, scope, node, var, type_instruction, init_value);
4849 IrInstruction *result = ir_build_var_decl(irb, scope, node, var, type_instruction, align_value, init_value);
48304850 var->decl_instruction = result;
48314851 return result;
48324852}
......@@ -4883,7 +4903,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
48834903 err_val_ptr, false);
48844904 IrInstruction *var_value = node->data.while_expr.var_is_ptr ?
48854905 var_ptr_value : ir_build_load_ptr(irb, payload_scope, symbol_node, var_ptr_value);
4886 ir_build_var_decl(irb, payload_scope, symbol_node, payload_var, nullptr, var_value);
4906 ir_build_var_decl(irb, payload_scope, symbol_node, payload_var, nullptr, nullptr, var_value);
48874907 }
48884908
48894909 ZigList<IrInstruction *> incoming_values = {0};
......@@ -4922,7 +4942,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
49224942 true, false, false, is_comptime);
49234943 Scope *err_scope = err_var->child_scope;
49244944 IrInstruction *err_var_value = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr);
4925 ir_build_var_decl(irb, err_scope, symbol_node, err_var, nullptr, err_var_value);
4945 ir_build_var_decl(irb, err_scope, symbol_node, err_var, nullptr, nullptr, err_var_value);
49264946
49274947 else_result = ir_gen_node(irb, else_node, err_scope);
49284948 if (else_result == irb->codegen->invalid_instruction)
......@@ -4964,7 +4984,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
49644984 IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, child_scope, symbol_node, maybe_val_ptr, false);
49654985 IrInstruction *var_value = node->data.while_expr.var_is_ptr ?
49664986 var_ptr_value : ir_build_load_ptr(irb, child_scope, symbol_node, var_ptr_value);
4967 ir_build_var_decl(irb, child_scope, symbol_node, payload_var, nullptr, var_value);
4987 ir_build_var_decl(irb, child_scope, symbol_node, payload_var, nullptr, nullptr, var_value);
49684988
49694989 ZigList<IrInstruction *> incoming_values = {0};
49704990 ZigList<IrBasicBlock *> incoming_blocks = {0};
......@@ -5115,7 +5135,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
51155135 Scope *child_scope = elem_var->child_scope;
51165136
51175137 IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node);
5118 ir_build_var_decl(irb, child_scope, elem_node, elem_var, elem_var_type, undefined_value);
5138 ir_build_var_decl(irb, child_scope, elem_node, elem_var, elem_var_type, nullptr, undefined_value);
51195139 IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var, false, false);
51205140
51215141 AstNode *index_var_source_node;
......@@ -5133,7 +5153,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
51335153 IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize);
51345154 IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0);
51355155 IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1);
5136 ir_build_var_decl(irb, child_scope, index_var_source_node, index_var, usize, zero);
5156 ir_build_var_decl(irb, child_scope, index_var_source_node, index_var, usize, nullptr, zero);
51375157 IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var, false, false);
51385158
51395159
......@@ -5254,12 +5274,22 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n
52545274 AstNode *size_node = node->data.array_type.size;
52555275 AstNode *child_type_node = node->data.array_type.child_type;
52565276 bool is_const = node->data.array_type.is_const;
5277 bool is_volatile = node->data.array_type.is_volatile;
5278 AstNode *align_expr = node->data.array_type.align_expr;
52575279
52585280 if (size_node) {
52595281 if (is_const) {
52605282 add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type"));
52615283 return irb->codegen->invalid_instruction;
52625284 }
5285 if (is_volatile) {
5286 add_node_error(irb->codegen, node, buf_create_from_str("volatile qualifier invalid on array type"));
5287 return irb->codegen->invalid_instruction;
5288 }
5289 if (align_expr != nullptr) {
5290 add_node_error(irb->codegen, node, buf_create_from_str("align qualifier invalid on array type"));
5291 return irb->codegen->invalid_instruction;
5292 }
52635293
52645294 IrInstruction *size_value = ir_gen_node(irb, size_node, scope);
52655295 if (size_value == irb->codegen->invalid_instruction)
......@@ -5271,11 +5301,20 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n
52715301
52725302 return ir_build_array_type(irb, scope, node, size_value, child_type);
52735303 } else {
5304 IrInstruction *align_value;
5305 if (align_expr != nullptr) {
5306 align_value = ir_gen_node(irb, align_expr, scope);
5307 if (align_value == irb->codegen->invalid_instruction)
5308 return align_value;
5309 } else {
5310 align_value = nullptr;
5311 }
5312
52745313 IrInstruction *child_type = ir_gen_node(irb, child_type_node, scope);
52755314 if (child_type == irb->codegen->invalid_instruction)
52765315 return child_type;
52775316
5278 return ir_build_slice_type(irb, scope, node, is_const, child_type);
5317 return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, align_value);
52795318 }
52805319}
52815320
......@@ -5375,7 +5414,7 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no
53755414
53765415 IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, scope, node, maybe_val_ptr, false);
53775416 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, node, var_ptr_value);
5378 ir_build_var_decl(irb, scope, node, var, var_type, var_value);
5417 ir_build_var_decl(irb, scope, node, var, var_type, nullptr, var_value);
53795418 var_scope = var->child_scope;
53805419 } else {
53815420 var_scope = scope;
......@@ -5452,7 +5491,7 @@ static IrInstruction *ir_gen_try_expr(IrBuilder *irb, Scope *scope, AstNode *nod
54525491
54535492 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, scope, node, err_val_ptr, false);
54545493 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, node, var_ptr_value);
5455 ir_build_var_decl(irb, scope, node, var, var_type, var_value);
5494 ir_build_var_decl(irb, scope, node, var, var_type, nullptr, var_value);
54565495 var_scope = var->child_scope;
54575496 } else {
54585497 var_scope = scope;
......@@ -5477,7 +5516,7 @@ static IrInstruction *ir_gen_try_expr(IrBuilder *irb, Scope *scope, AstNode *nod
54775516 err_symbol, is_const, is_const, is_shadowable, is_comptime);
54785517
54795518 IrInstruction *var_value = ir_build_unwrap_err_code(irb, scope, node, err_val_ptr);
5480 ir_build_var_decl(irb, scope, node, var, var_type, var_value);
5519 ir_build_var_decl(irb, scope, node, var, var_type, nullptr, var_value);
54815520 err_var_scope = var->child_scope;
54825521 } else {
54835522 err_var_scope = scope;
......@@ -5531,7 +5570,7 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit
55315570 var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr);
55325571 }
55335572 IrInstruction *var_type = nullptr; // infer the type
5534 ir_build_var_decl(irb, scope, var_symbol_node, var, var_type, var_value);
5573 ir_build_var_decl(irb, scope, var_symbol_node, var, var_type, nullptr, var_value);
55355574 } else {
55365575 child_scope = scope;
55375576 }
......@@ -5912,7 +5951,7 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN
59125951 is_const, is_const, is_shadowable, is_comptime);
59135952 err_scope = var->child_scope;
59145953 IrInstruction *err_val = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr);
5915 ir_build_var_decl(irb, err_scope, var_node, var, var_type, err_val);
5954 ir_build_var_decl(irb, err_scope, var_node, var, var_type, nullptr, err_val);
59165955 } else {
59175956 err_scope = parent_scope;
59185957 }
......@@ -6056,6 +6095,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
60566095 return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval);
60576096 case NodeTypePrefixOpExpr:
60586097 return ir_gen_prefix_op_expr(irb, scope, node, lval);
6098 case NodeTypeAddrOfExpr:
6099 return ir_lval_wrap(irb, scope, ir_gen_address_of(irb, scope, node), lval);
60596100 case NodeTypeContainerInitExpr:
60606101 return ir_lval_wrap(irb, scope, ir_gen_container_init_expr(irb, scope, node), lval);
60616102 case NodeTypeVariableDeclaration:
......@@ -7264,7 +7305,8 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
72647305 }
72657306 if (convert_to_const_slice) {
72667307 assert(prev_inst->value.type->id == TypeTableEntryIdArray);
7267 TypeTableEntry *slice_type = get_slice_type(ira->codegen, prev_inst->value.type->data.array.child_type, true);
7308 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, prev_inst->value.type->data.array.child_type, true);
7309 TypeTableEntry *slice_type = get_slice_type(ira->codegen, ptr_type);
72687310 if (any_are_pure_error) {
72697311 return get_error_type(ira->codegen, slice_type);
72707312 } else {
......@@ -7569,7 +7611,7 @@ static TypeTableEntry *ir_analyze_void(IrAnalyze *ira, IrInstruction *instructio
75697611
75707612static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instruction,
75717613 ConstExprValue *pointee, TypeTableEntry *pointee_type,
7572 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile)
7614 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align)
75737615{
75747616 if (pointee_type->id == TypeTableEntryIdMetaType) {
75757617 TypeTableEntry *type_entry = pointee->data.x_type;
......@@ -7583,11 +7625,11 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio
75837625 const_val->type = pointee_type;
75847626 type_ensure_zero_bits_known(ira->codegen, type_entry);
75857627 const_val->data.x_type = get_pointer_to_type_extra(ira->codegen, type_entry,
7586 ptr_is_const, ptr_is_volatile, 0, 0);
7628 ptr_is_const, ptr_is_volatile, get_abi_alignment(ira->codegen, type_entry), 0, 0);
75877629 return const_instr;
75887630 } else {
75897631 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type,
7590 ptr_is_const, ptr_is_volatile, 0, 0);
7632 ptr_is_const, ptr_is_volatile, ptr_align, 0, 0);
75917633 IrInstruction *const_instr = ir_get_const(ira, instruction);
75927634 ConstExprValue *const_val = &const_instr->value;
75937635 const_val->type = ptr_type;
......@@ -7603,7 +7645,8 @@ static TypeTableEntry *ir_analyze_const_ptr(IrAnalyze *ira, IrInstruction *instr
76037645 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile)
76047646{
76057647 IrInstruction *const_instr = ir_get_const_ptr(ira, instruction, pointee,
7606 pointee_type, ptr_mut, ptr_is_const, ptr_is_volatile);
7648 pointee_type, ptr_mut, ptr_is_const, ptr_is_volatile,
7649 get_abi_alignment(ira->codegen, pointee_type));
76077650 ir_link_new_instruction(const_instr, instruction);
76087651 return const_instr->value.type;
76097652}
......@@ -7876,10 +7919,12 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
78767919 return ira->codegen->invalid_instruction;
78777920 bool final_is_const = (value->value.type->id == TypeTableEntryIdMetaType) ? is_const : true;
78787921 return ir_get_const_ptr(ira, source_instruction, val, value->value.type,
7879 ConstPtrMutComptimeConst, final_is_const, is_volatile);
7922 ConstPtrMutComptimeConst, final_is_const, is_volatile,
7923 get_abi_alignment(ira->codegen, value->value.type));
78807924 }
78817925
7882 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, is_const, is_volatile, 0, 0);
7926 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type,
7927 is_const, is_volatile, get_abi_alignment(ira->codegen, value->value.type), 0, 0);
78837928 FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
78847929 assert(fn_entry);
78857930 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope,
......@@ -8579,6 +8624,33 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst
85798624 return result->value.type;
85808625}
85818626
8627static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) {
8628 if (type_is_invalid(value->value.type))
8629 return false;
8630
8631 IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen));
8632 if (type_is_invalid(casted_value->value.type))
8633 return false;
8634
8635 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad);
8636 if (!const_val)
8637 return false;
8638
8639 uint32_t align_bytes = bigint_as_unsigned(&const_val->data.x_bigint);
8640 if (align_bytes == 0) {
8641 ir_add_error(ira, value, buf_sprintf("alignment must be >= 1"));
8642 return false;
8643 }
8644
8645 if (!is_power_of_2(align_bytes)) {
8646 ir_add_error(ira, value, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes));
8647 return false;
8648 }
8649
8650 *out = align_bytes;
8651 return true;
8652}
8653
85828654static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) {
85838655 if (type_is_invalid(value->value.type))
85848656 return false;
......@@ -8656,7 +8728,8 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {
86568728 if (type_is_invalid(value->value.type))
86578729 return nullptr;
86588730
8659 TypeTableEntry *str_type = get_slice_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
8731 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
8732 TypeTableEntry *str_type = get_slice_type(ira->codegen, ptr_type);
86608733 IrInstruction *casted_value = ir_implicit_cast(ira, value, str_type);
86618734 if (type_is_invalid(casted_value->value.type))
86628735 return nullptr;
......@@ -9715,6 +9788,14 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
97159788
97169789 bool is_comptime = ir_get_var_is_comptime(var);
97179790
9791 if (decl_var_instruction->align_value == nullptr) {
9792 var->align_bytes = get_abi_alignment(ira->codegen, result_type);
9793 } else {
9794 if (!ir_resolve_align(ira, decl_var_instruction->align_value->other, &var->align_bytes)) {
9795 var->value->type = ira->codegen->builtin_types.entry_invalid;
9796 }
9797 }
9798
97189799 if (casted_init_value->value.special != ConstValSpecialRuntime) {
97199800 if (var->mem_slot_index != SIZE_MAX) {
97209801 assert(var->mem_slot_index < ira->exec_context.mem_slot_count);
......@@ -9733,7 +9814,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
97339814 return ira->codegen->builtin_types.entry_invalid;
97349815 }
97359816
9736 ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value);
9817 ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, nullptr, casted_init_value);
97379818
97389819 FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
97399820 if (fn_entry)
......@@ -9892,11 +9973,12 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
98929973 ptr_mut = ConstPtrMutRuntimeVar;
98939974 }
98949975 return ir_get_const_ptr(ira, instruction, mem_slot, var->value->type,
9895 ptr_mut, is_const, is_volatile);
9976 ptr_mut, is_const, is_volatile, var->align_bytes);
98969977 } else {
98979978 IrInstruction *var_ptr_instruction = ir_build_var_ptr(&ira->new_irb,
98989979 instruction->scope, instruction->source_node, var, is_const, is_volatile);
9899 var_ptr_instruction->value.type = get_pointer_to_type(ira->codegen, var->value->type, var->src_is_const);
9980 var_ptr_instruction->value.type = get_pointer_to_type_extra(ira->codegen, var->value->type,
9981 var->src_is_const, is_volatile, var->align_bytes, 0, 0);
99009982 type_ensure_zero_bits_known(ira->codegen, var->value->type);
99019983
99029984 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr);
......@@ -10131,6 +10213,16 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1013110213 impl_fn->child_scope, param_name, true, var_args_val, nullptr);
1013210214 impl_fn->child_scope = var->child_scope;
1013310215 }
10216
10217 if (fn_proto_node->data.fn_proto.align_expr != nullptr) {
10218 IrInstruction *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope,
10219 fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen),
10220 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota,
10221 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec);
10222
10223 ir_resolve_align(ira, align_result, &impl_fn->align_bytes);
10224 }
10225
1013410226 {
1013510227 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
1013610228 TypeTableEntry *return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);
......@@ -10731,7 +10823,8 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
1073110823 TypeTableEntry *child_type = array_type->data.array.child_type;
1073210824 if (ptr_type->data.pointer.unaligned_bit_count == 0) {
1073310825 return_type = get_pointer_to_type_extra(ira->codegen, child_type,
10734 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 0, 0);
10826 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
10827 get_abi_alignment(ira->codegen, child_type), 0, 0);
1073510828 } else {
1073610829 uint64_t elem_val_scalar;
1073710830 if (!ir_resolve_usize(ira, elem_index, &elem_val_scalar))
......@@ -10742,6 +10835,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
1074210835
1074310836 return_type = get_pointer_to_type_extra(ira->codegen, child_type,
1074410837 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
10838 get_abi_alignment(ira->codegen, child_type),
1074510839 (uint32_t)bit_offset, (uint32_t)bit_width);
1074610840 }
1074710841 } else if (array_type->id == TypeTableEntryIdPointer) {
......@@ -10964,6 +11058,8 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
1096411058
1096511059 TypeStructField *field = find_struct_type_field(bare_type, field_name);
1096611060 if (field) {
11061 bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked);
11062 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);
1096711063 if (instr_is_comptime(container_ptr)) {
1096811064 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);
1096911065 if (!ptr_val)
......@@ -10973,7 +11069,7 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
1097311069 ConstExprValue *struct_val = const_ptr_pointee(ira->codegen, ptr_val);
1097411070 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];
1097511071 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type,
10976 is_const, is_volatile, 0, 0);
11072 is_const, is_volatile, align_bytes, 0, 0);
1097711073 ConstExprValue *const_val = ir_build_const_from(ira, &field_ptr_instruction->base);
1097811074 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct;
1097911075 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut;
......@@ -10988,6 +11084,7 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
1098811084 field->unaligned_bit_count : type_size_bits(ira->codegen, field->type_entry);
1098911085 ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
1099011086 return get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
11087 align_bytes,
1099111088 (uint32_t)(ptr_bit_offset + field->packed_bits_offset),
1099211089 (uint32_t)unaligned_bit_count_for_result_type);
1099311090 } else {
......@@ -11001,7 +11098,8 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
1100111098 TypeEnumField *field = find_enum_type_field(bare_type, field_name);
1100211099 if (field) {
1100311100 ir_build_enum_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
11004 return get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, 0, 0);
11101 return get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile,
11102 get_abi_alignment(ira->codegen, field->type_entry), 0, 0);
1100511103 } else {
1100611104 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
1100711105 field_ptr_instruction, container_ptr, container_type);
......@@ -11427,7 +11525,6 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira,
1142711525 if (type_is_invalid(type_entry))
1142811526 return type_entry;
1142911527
11430 // TODO handle typedefs
1143111528 if (type_entry->id != TypeTableEntryIdPointer) {
1143211529 ir_add_error_node(ira, ptr_type_child_instruction->base.source_node,
1143311530 buf_sprintf("expected pointer type, found '%s'", buf_ptr(&type_entry->name)));
......@@ -11439,69 +11536,6 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira,
1143911536 return ira->codegen->builtin_types.entry_type;
1144011537}
1144111538
11442static TypeTableEntry *ir_analyze_instruction_set_global_align(IrAnalyze *ira,
11443 IrInstructionSetGlobalAlign *instruction)
11444{
11445 Tld *tld = instruction->tld;
11446 IrInstruction *align_value = instruction->value->other;
11447
11448 resolve_top_level_decl(ira->codegen, tld, true, instruction->base.source_node);
11449 if (tld->resolution == TldResolutionInvalid)
11450 return ira->codegen->builtin_types.entry_invalid;
11451
11452 uint64_t scalar_align;
11453 if (!ir_resolve_usize(ira, align_value, &scalar_align))
11454 return ira->codegen->builtin_types.entry_invalid;
11455
11456 if (!is_power_of_2(scalar_align)) {
11457 ir_add_error(ira, instruction->value, buf_sprintf("alignment value must be power of 2"));
11458 return ira->codegen->builtin_types.entry_invalid;
11459 }
11460
11461 AstNode **set_global_align_node;
11462 uint32_t *alignment_ptr;
11463 if (tld->id == TldIdVar) {
11464 TldVar *tld_var = (TldVar *)tld;
11465 set_global_align_node = &tld_var->set_global_align_node;
11466 alignment_ptr = &tld_var->alignment;
11467
11468 if (tld_var->var->linkage == VarLinkageExternal) {
11469 ErrorMsg *msg = ir_add_error(ira, &instruction->base,
11470 buf_sprintf("cannot set alignment of external variable '%s'", buf_ptr(&tld_var->var->name)));
11471 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here"));
11472 return ira->codegen->builtin_types.entry_invalid;
11473 }
11474 } else if (tld->id == TldIdFn) {
11475 TldFn *tld_fn = (TldFn *)tld;
11476 FnTableEntry *fn_entry = tld_fn->fn_entry;
11477 set_global_align_node = &fn_entry->set_global_align_node;
11478 alignment_ptr = &fn_entry->alignment;
11479
11480 if (fn_entry->def_scope == nullptr) {
11481 ErrorMsg *msg = ir_add_error(ira, &instruction->base,
11482 buf_sprintf("cannot set alignment of external function '%s'", buf_ptr(&fn_entry->symbol_name)));
11483 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here"));
11484 return ira->codegen->builtin_types.entry_invalid;
11485 }
11486 } else {
11487 // error is caught in pass1 IR gen
11488 zig_unreachable();
11489 }
11490
11491 AstNode *source_node = instruction->base.source_node;
11492 if (*set_global_align_node) {
11493 ErrorMsg *msg = ir_add_error_node(ira, source_node,
11494 buf_sprintf("alignment set twice"));
11495 add_error_note(ira->codegen, msg, *set_global_align_node, buf_sprintf("first set here"));
11496 return ira->codegen->builtin_types.entry_invalid;
11497 }
11498 *set_global_align_node = source_node;
11499 *alignment_ptr = (uint32_t)scalar_align;
11500
11501 ir_build_const_from(ira, &instruction->base);
11502 return ira->codegen->builtin_types.entry_void;
11503}
11504
1150511539static TypeTableEntry *ir_analyze_instruction_set_global_section(IrAnalyze *ira,
1150611540 IrInstructionSetGlobalSection *instruction)
1150711541{
......@@ -11750,16 +11784,24 @@ static TypeTableEntry *ir_analyze_instruction_set_float_mode(IrAnalyze *ira,
1175011784static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
1175111785 IrInstructionSliceType *slice_type_instruction)
1175211786{
11753 IrInstruction *child_type = slice_type_instruction->child_type->other;
11754 if (type_is_invalid(child_type->value.type))
11755 return ira->codegen->builtin_types.entry_invalid;
11756 bool is_const = slice_type_instruction->is_const;
11787 uint32_t align_bytes;
11788 if (slice_type_instruction->align_value != nullptr) {
11789 if (!ir_resolve_align(ira, slice_type_instruction->align_value->other, &align_bytes))
11790 return ira->codegen->builtin_types.entry_invalid;
11791 }
1175711792
11758 TypeTableEntry *resolved_child_type = ir_resolve_type(ira, child_type);
11759 if (type_is_invalid(resolved_child_type))
11793 TypeTableEntry *child_type = ir_resolve_type(ira, slice_type_instruction->child_type->other);
11794 if (type_is_invalid(child_type))
1176011795 return ira->codegen->builtin_types.entry_invalid;
1176111796
11762 switch (resolved_child_type->id) {
11797 if (slice_type_instruction->align_value == nullptr) {
11798 align_bytes = get_abi_alignment(ira->codegen, child_type);
11799 }
11800
11801 bool is_const = slice_type_instruction->is_const;
11802 bool is_volatile = slice_type_instruction->is_volatile;
11803
11804 switch (child_type->id) {
1176311805 case TypeTableEntryIdInvalid: // handled above
1176411806 zig_unreachable();
1176511807 case TypeTableEntryIdVar:
......@@ -11770,7 +11812,7 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
1177011812 case TypeTableEntryIdArgTuple:
1177111813 case TypeTableEntryIdOpaque:
1177211814 ir_add_error_node(ira, slice_type_instruction->base.source_node,
11773 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&resolved_child_type->name)));
11815 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&child_type->name)));
1177411816 return ira->codegen->builtin_types.entry_invalid;
1177511817 case TypeTableEntryIdMetaType:
1177611818 case TypeTableEntryIdVoid:
......@@ -11792,8 +11834,10 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
1179211834 case TypeTableEntryIdBoundFn:
1179311835 case TypeTableEntryIdEnumTag:
1179411836 {
11795 type_ensure_zero_bits_known(ira->codegen, resolved_child_type);
11796 TypeTableEntry *result_type = get_slice_type(ira->codegen, resolved_child_type, is_const);
11837 type_ensure_zero_bits_known(ira->codegen, child_type);
11838 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type,
11839 is_const, is_volatile, align_bytes, 0, 0);
11840 TypeTableEntry *result_type = get_slice_type(ira->codegen, slice_ptr_type);
1179711841 ConstExprValue *out_val = ir_build_const_from(ira, &slice_type_instruction->base);
1179811842 out_val->data.x_type = result_type;
1179911843 return ira->codegen->builtin_types.entry_type;
......@@ -12018,7 +12062,6 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira,
1201812062 assert(ptr_type->id == TypeTableEntryIdPointer);
1201912063
1202012064 TypeTableEntry *type_entry = ptr_type->data.pointer.child_type;
12021 // TODO handle typedef
1202212065 if (type_is_invalid(type_entry)) {
1202312066 return ira->codegen->builtin_types.entry_invalid;
1202412067 } else if (type_entry->id != TypeTableEntryIdMaybe) {
......@@ -12028,7 +12071,8 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira,
1202812071 }
1202912072 TypeTableEntry *child_type = type_entry->data.maybe.child_type;
1203012073 TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, child_type,
12031 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 0, 0);
12074 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
12075 get_abi_alignment(ira->codegen, child_type), 0, 0);
1203212076
1203312077 if (instr_is_comptime(value)) {
1203412078 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
......@@ -12887,7 +12931,8 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc
1288712931 if (type_is_invalid(casted_value->value.type))
1288812932 return ira->codegen->builtin_types.entry_invalid;
1288912933
12890 TypeTableEntry *str_type = get_slice_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
12934 TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
12935 TypeTableEntry *str_type = get_slice_type(ira->codegen, u8_ptr_type);
1289112936 if (casted_value->value.special == ConstValSpecialStatic) {
1289212937 ErrorTableEntry *err = casted_value->value.data.x_pure_err;
1289312938 if (!err->cached_error_name_val) {
......@@ -12929,7 +12974,8 @@ static TypeTableEntry *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrIn
1292912974 IrInstruction *result = ir_build_enum_tag_name(&ira->new_irb, instruction->base.scope,
1293012975 instruction->base.source_node, target);
1293112976 ir_link_new_instruction(result, &instruction->base);
12932 result->value.type = get_slice_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
12977 TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
12978 result->value.type = get_slice_type(ira->codegen, u8_ptr_type);
1293312979 return result->value.type;
1293412980}
1293512981
......@@ -12972,16 +13018,22 @@ static TypeTableEntry *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,
1297213018 return ira->codegen->builtin_types.entry_invalid;
1297313019 }
1297413020
13021 bool is_packed = (container_type->data.structure.layout == ContainerLayoutPacked);
13022 uint32_t field_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry);
13023 uint32_t parent_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, container_type);
13024
1297513025 TypeTableEntry *field_ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry,
1297613026 field_ptr->value.type->data.pointer.is_const,
12977 field_ptr->value.type->data.pointer.is_volatile, 0, 0);
13027 field_ptr->value.type->data.pointer.is_volatile,
13028 field_ptr_align, 0, 0);
1297813029 IrInstruction *casted_field_ptr = ir_implicit_cast(ira, field_ptr, field_ptr_type);
1297913030 if (type_is_invalid(casted_field_ptr->value.type))
1298013031 return ira->codegen->builtin_types.entry_invalid;
1298113032
1298213033 TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, container_type,
1298313034 casted_field_ptr->value.type->data.pointer.is_const,
12984 casted_field_ptr->value.type->data.pointer.is_volatile, 0, 0);
13035 casted_field_ptr->value.type->data.pointer.is_volatile,
13036 parent_ptr_align, 0, 0);
1298513037
1298613038 if (instr_is_comptime(casted_field_ptr)) {
1298713039 ConstExprValue *field_ptr_val = ir_resolve_const(ira, casted_field_ptr, UndefBad);
......@@ -13436,7 +13488,9 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi
1343613488
1343713489 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
1343813490 TypeTableEntry *u8 = ira->codegen->builtin_types.entry_u8;
13439 TypeTableEntry *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 0, 0);
13491 uint32_t dest_align = (dest_uncasted_type->id == TypeTableEntryIdPointer) ?
13492 dest_uncasted_type->data.pointer.alignment : get_abi_alignment(ira->codegen, u8);
13493 TypeTableEntry *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, dest_align, 0, 0);
1344013494
1344113495 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr);
1344213496 if (type_is_invalid(casted_dest_ptr->value.type))
......@@ -13517,17 +13571,21 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi
1351713571 if (type_is_invalid(count_value->value.type))
1351813572 return ira->codegen->builtin_types.entry_invalid;
1351913573
13574 TypeTableEntry *u8 = ira->codegen->builtin_types.entry_u8;
1352013575 TypeTableEntry *dest_uncasted_type = dest_ptr->value.type;
1352113576 TypeTableEntry *src_uncasted_type = src_ptr->value.type;
1352213577 bool dest_is_volatile = (dest_uncasted_type->id == TypeTableEntryIdPointer) &&
1352313578 dest_uncasted_type->data.pointer.is_volatile;
1352413579 bool src_is_volatile = (src_uncasted_type->id == TypeTableEntryIdPointer) &&
1352513580 src_uncasted_type->data.pointer.is_volatile;
13581 uint32_t dest_align = (dest_uncasted_type->id == TypeTableEntryIdPointer) ?
13582 dest_uncasted_type->data.pointer.alignment : get_abi_alignment(ira->codegen, u8);
13583 uint32_t src_align = (src_uncasted_type->id == TypeTableEntryIdPointer) ?
13584 src_uncasted_type->data.pointer.alignment : get_abi_alignment(ira->codegen, u8);
1352613585
1352713586 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
13528 TypeTableEntry *u8 = ira->codegen->builtin_types.entry_u8;
13529 TypeTableEntry *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 0, 0);
13530 TypeTableEntry *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, src_is_volatile, 0, 0);
13587 TypeTableEntry *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, dest_align, 0, 0);
13588 TypeTableEntry *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, src_is_volatile, src_align, 0, 0);
1353113589
1353213590 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut);
1353313591 if (type_is_invalid(casted_dest_ptr->value.type))
......@@ -13662,17 +13720,24 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
1366213720 TypeTableEntry *return_type;
1366313721
1366413722 if (array_type->id == TypeTableEntryIdArray) {
13665 return_type = get_slice_type(ira->codegen, array_type->data.array.child_type, ptr_type->data.pointer.is_const);
13723 uint32_t normal_array_alignment = get_abi_alignment(ira->codegen, array_type);
13724 uint32_t align_bytes = (ptr_type->data.pointer.alignment >= normal_array_alignment) ?
13725 normal_array_alignment : 1;
13726 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.array.child_type,
13727 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, align_bytes, 0, 0);
13728 return_type = get_slice_type(ira->codegen, slice_ptr_type);
1366613729 } else if (array_type->id == TypeTableEntryIdPointer) {
13667 return_type = get_slice_type(ira->codegen, array_type->data.pointer.child_type,
13668 array_type->data.pointer.is_const);
13730 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.pointer.child_type,
13731 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile,
13732 array_type->data.pointer.alignment, 0, 0);
13733 return_type = get_slice_type(ira->codegen, slice_ptr_type);
1366913734 if (!end) {
1367013735 ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value"));
1367113736 return ira->codegen->builtin_types.entry_invalid;
1367213737 }
1367313738 } else if (is_slice(array_type)) {
1367413739 TypeTableEntry *ptr_type = array_type->data.structure.fields[slice_ptr_index].type_entry;
13675 return_type = get_slice_type(ira->codegen, ptr_type->data.pointer.child_type, ptr_type->data.pointer.is_const);
13740 return_type = get_slice_type(ira->codegen, ptr_type);
1367613741 } else {
1367713742 ir_add_error(ira, &instruction->base,
1367813743 buf_sprintf("slice of non-array type '%s'", buf_ptr(&array_type->name)));
......@@ -13860,7 +13925,7 @@ static TypeTableEntry *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrIn
1386013925 return u8_ptr_const;
1386113926}
1386213927
13863static TypeTableEntry *ir_analyze_instruction_preferred_align_of(IrAnalyze *ira, IrInstructionPreferredAlignOf *instruction) {
13928static TypeTableEntry *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) {
1386413929 IrInstruction *type_value = instruction->type_value->other;
1386513930 if (type_is_invalid(type_value->value.type))
1386613931 return ira->codegen->builtin_types.entry_invalid;
......@@ -13884,62 +13949,11 @@ static TypeTableEntry *ir_analyze_instruction_preferred_align_of(IrAnalyze *ira,
1388413949 case TypeTableEntryIdBlock:
1388513950 case TypeTableEntryIdBoundFn:
1388613951 case TypeTableEntryIdArgTuple:
13887 ir_add_error(ira, instruction->type_value,
13888 buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name)));
13889 return ira->codegen->builtin_types.entry_invalid;
1389013952 case TypeTableEntryIdVoid:
13891 case TypeTableEntryIdBool:
13892 case TypeTableEntryIdInt:
13893 case TypeTableEntryIdFloat:
13894 case TypeTableEntryIdPointer:
13895 case TypeTableEntryIdArray:
13896 case TypeTableEntryIdStruct:
13897 case TypeTableEntryIdMaybe:
13898 case TypeTableEntryIdErrorUnion:
13899 case TypeTableEntryIdPureError:
13900 case TypeTableEntryIdEnum:
13901 case TypeTableEntryIdEnumTag:
13902 case TypeTableEntryIdUnion:
13903 case TypeTableEntryIdFn:
1390413953 case TypeTableEntryIdOpaque:
13905 {
13906 uint64_t align_in_bytes = LLVMPreferredAlignmentOfType(ira->codegen->target_data_ref, type_entry->type_ref);
13907 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
13908 bigint_init_unsigned(&out_val->data.x_bigint, align_in_bytes);
13909 return ira->codegen->builtin_types.entry_num_lit_int;
13910 }
13911 }
13912 zig_unreachable();
13913}
13914
13915static TypeTableEntry *ir_analyze_instruction_abi_align_of(IrAnalyze *ira, IrInstructionAbiAlignOf *instruction) {
13916 IrInstruction *type_value = instruction->type_value->other;
13917 if (type_is_invalid(type_value->value.type))
13918 return ira->codegen->builtin_types.entry_invalid;
13919 TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);
13920
13921 ensure_complete_type(ira->codegen, type_entry);
13922 if (type_is_invalid(type_entry))
13923 return ira->codegen->builtin_types.entry_invalid;
13924
13925 switch (type_entry->id) {
13926 case TypeTableEntryIdInvalid:
13927 case TypeTableEntryIdVar:
13928 zig_unreachable();
13929 case TypeTableEntryIdMetaType:
13930 case TypeTableEntryIdUnreachable:
13931 case TypeTableEntryIdNumLitFloat:
13932 case TypeTableEntryIdNumLitInt:
13933 case TypeTableEntryIdUndefLit:
13934 case TypeTableEntryIdNullLit:
13935 case TypeTableEntryIdNamespace:
13936 case TypeTableEntryIdBlock:
13937 case TypeTableEntryIdBoundFn:
13938 case TypeTableEntryIdArgTuple:
1393913954 ir_add_error(ira, instruction->type_value,
1394013955 buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name)));
1394113956 return ira->codegen->builtin_types.entry_invalid;
13942 case TypeTableEntryIdVoid:
1394313957 case TypeTableEntryIdBool:
1394413958 case TypeTableEntryIdInt:
1394513959 case TypeTableEntryIdFloat:
......@@ -13953,9 +13967,8 @@ static TypeTableEntry *ir_analyze_instruction_abi_align_of(IrAnalyze *ira, IrIns
1395313967 case TypeTableEntryIdEnumTag:
1395413968 case TypeTableEntryIdUnion:
1395513969 case TypeTableEntryIdFn:
13956 case TypeTableEntryIdOpaque:
1395713970 {
13958 uint64_t align_in_bytes = LLVMABIAlignmentOfType(ira->codegen->target_data_ref, type_entry->type_ref);
13971 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry);
1395913972 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
1396013973 bigint_init_unsigned(&out_val->data.x_bigint, align_in_bytes);
1396113974 return ira->codegen->builtin_types.entry_num_lit_int;
......@@ -14143,7 +14156,8 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
1414314156 } else if (type_entry->id == TypeTableEntryIdErrorUnion) {
1414414157 TypeTableEntry *child_type = type_entry->data.error.child_type;
1414514158 TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, child_type,
14146 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 0, 0);
14159 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
14160 get_abi_alignment(ira->codegen, child_type), 0, 0);
1414714161 if (instr_is_comptime(value)) {
1414814162 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);
1414914163 if (!ptr_val)
......@@ -14390,7 +14404,8 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio
1439014404 if (type_is_invalid(msg->value.type))
1439114405 return ira->codegen->builtin_types.entry_invalid;
1439214406
14393 TypeTableEntry *str_type = get_slice_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
14407 TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
14408 TypeTableEntry *str_type = get_slice_type(ira->codegen, u8_ptr_type);
1439414409 IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type);
1439514410 if (type_is_invalid(casted_msg->value.type))
1439614411 return ira->codegen->builtin_types.entry_invalid;
......@@ -14814,6 +14829,23 @@ static TypeTableEntry *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstr
1481414829 return usize;
1481514830}
1481614831
14832static TypeTableEntry *ir_analyze_instruction_ptr_type_of(IrAnalyze *ira, IrInstructionPtrTypeOf *instruction) {
14833 TypeTableEntry *child_type = ir_resolve_type(ira, instruction->child_type->other);
14834 if (type_is_invalid(child_type))
14835 return ira->codegen->builtin_types.entry_invalid;
14836
14837 uint32_t align_bytes;
14838 if (!ir_resolve_align(ira, instruction->align_value->other, &align_bytes))
14839 return ira->codegen->builtin_types.entry_invalid;
14840
14841 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
14842 out_val->data.x_type = get_pointer_to_type_extra(ira->codegen, child_type,
14843 instruction->is_const, instruction->is_volatile, align_bytes,
14844 instruction->bit_offset_start, instruction->bit_offset_end);
14845
14846 return ira->codegen->builtin_types.entry_type;
14847}
14848
1481714849static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
1481814850 switch (instruction->id) {
1481914851 case IrInstructionIdInvalid:
......@@ -14862,8 +14894,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1486214894 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);
1486314895 case IrInstructionIdPtrTypeChild:
1486414896 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);
14865 case IrInstructionIdSetGlobalAlign:
14866 return ir_analyze_instruction_set_global_align(ira, (IrInstructionSetGlobalAlign *)instruction);
1486714897 case IrInstructionIdSetGlobalSection:
1486814898 return ir_analyze_instruction_set_global_section(ira, (IrInstructionSetGlobalSection *)instruction);
1486914899 case IrInstructionIdSetGlobalLinkage:
......@@ -14952,10 +14982,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1495214982 return ir_analyze_instruction_return_address(ira, (IrInstructionReturnAddress *)instruction);
1495314983 case IrInstructionIdFrameAddress:
1495414984 return ir_analyze_instruction_frame_address(ira, (IrInstructionFrameAddress *)instruction);
14955 case IrInstructionIdPreferredAlignOf:
14956 return ir_analyze_instruction_preferred_align_of(ira, (IrInstructionPreferredAlignOf *)instruction);
14957 case IrInstructionIdAbiAlignOf:
14958 return ir_analyze_instruction_abi_align_of(ira, (IrInstructionAbiAlignOf *)instruction);
14985 case IrInstructionIdAlignOf:
14986 return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction);
1495914987 case IrInstructionIdOverflowOp:
1496014988 return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction);
1496114989 case IrInstructionIdTestErr:
......@@ -14996,6 +15024,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1499615024 return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction);
1499715025 case IrInstructionIdSetEvalBranchQuota:
1499815026 return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstructionSetEvalBranchQuota *)instruction);
15027 case IrInstructionIdPtrTypeOf:
15028 return ir_analyze_instruction_ptr_type_of(ira, (IrInstructionPtrTypeOf *)instruction);
1499915029 case IrInstructionIdMaybeWrap:
1500015030 case IrInstructionIdErrWrapCode:
1500115031 case IrInstructionIdErrWrapPayload:
......@@ -15108,11 +15138,11 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1510815138 case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free
1510915139 case IrInstructionIdCheckSwitchProngs:
1511015140 case IrInstructionIdCheckStatementIsVoid:
15111 case IrInstructionIdSetGlobalAlign:
1511215141 case IrInstructionIdSetGlobalSection:
1511315142 case IrInstructionIdSetGlobalLinkage:
1511415143 case IrInstructionIdPanic:
1511515144 case IrInstructionIdSetEvalBranchQuota:
15145 case IrInstructionIdPtrTypeOf:
1511615146 return true;
1511715147 case IrInstructionIdPhi:
1511815148 case IrInstructionIdUnOp:
......@@ -15151,8 +15181,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1515115181 case IrInstructionIdBoolNot:
1515215182 case IrInstructionIdSlice:
1515315183 case IrInstructionIdMemberCount:
15154 case IrInstructionIdPreferredAlignOf:
15155 case IrInstructionIdAbiAlignOf:
15184 case IrInstructionIdAlignOf:
1515615185 case IrInstructionIdReturnAddress:
1515715186 case IrInstructionIdFrameAddress:
1515815187 case IrInstructionIdTestErr:
src/ir_print.cpp+14-19
......@@ -664,14 +664,8 @@ static void ir_print_return_address(IrPrint *irp, IrInstructionReturnAddress *in
664664 fprintf(irp->f, "@returnAddress()");
665665}
666666
667static void ir_print_preferred_align_of(IrPrint *irp, IrInstructionPreferredAlignOf *instruction) {
668 fprintf(irp->f, "@preferredAlignOf(");
669 ir_print_other_instruction(irp, instruction->type_value);
670 fprintf(irp->f, ")");
671}
672
673static void ir_print_abi_align_of(IrPrint *irp, IrInstructionAbiAlignOf *instruction) {
674 fprintf(irp->f, "@abiAlignOf(");
667static void ir_print_align_of(IrPrint *irp, IrInstructionAlignOf *instruction) {
668 fprintf(irp->f, "@alignOf(");
675669 ir_print_other_instruction(irp, instruction->type_value);
676670 fprintf(irp->f, ")");
677671}
......@@ -860,10 +854,14 @@ static void ir_print_can_implicit_cast(IrPrint *irp, IrInstructionCanImplicitCas
860854 fprintf(irp->f, ")");
861855}
862856
863static void ir_print_set_global_align(IrPrint *irp, IrInstructionSetGlobalAlign *instruction) {
864 fprintf(irp->f, "@setGlobalAlign(%s,", buf_ptr(instruction->tld->name));
865 ir_print_other_instruction(irp, instruction->value);
866 fprintf(irp->f, ")");
857static void ir_print_ptr_type_of(IrPrint *irp, IrInstructionPtrTypeOf *instruction) {
858 fprintf(irp->f, "&align ");
859 ir_print_other_instruction(irp, instruction->align_value);
860 const char *const_str = instruction->is_const ? "const " : "";
861 const char *volatile_str = instruction->is_volatile ? "volatile " : "";
862 fprintf(irp->f, ":%" PRIu32 ":%" PRIu32 " %s%s", instruction->bit_offset_start, instruction->bit_offset_end,
863 const_str, volatile_str);
864 ir_print_other_instruction(irp, instruction->child_type);
867865}
868866
869867static void ir_print_set_global_section(IrPrint *irp, IrInstructionSetGlobalSection *instruction) {
......@@ -1116,11 +1114,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
11161114 case IrInstructionIdFrameAddress:
11171115 ir_print_frame_address(irp, (IrInstructionFrameAddress *)instruction);
11181116 break;
1119 case IrInstructionIdPreferredAlignOf:
1120 ir_print_preferred_align_of(irp, (IrInstructionPreferredAlignOf *)instruction);
1121 break;
1122 case IrInstructionIdAbiAlignOf:
1123 ir_print_abi_align_of(irp, (IrInstructionAbiAlignOf *)instruction);
1117 case IrInstructionIdAlignOf:
1118 ir_print_align_of(irp, (IrInstructionAlignOf *)instruction);
11241119 break;
11251120 case IrInstructionIdOverflowOp:
11261121 ir_print_overflow_op(irp, (IrInstructionOverflowOp *)instruction);
......@@ -1191,8 +1186,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
11911186 case IrInstructionIdCanImplicitCast:
11921187 ir_print_can_implicit_cast(irp, (IrInstructionCanImplicitCast *)instruction);
11931188 break;
1194 case IrInstructionIdSetGlobalAlign:
1195 ir_print_set_global_align(irp, (IrInstructionSetGlobalAlign *)instruction);
1189 case IrInstructionIdPtrTypeOf:
1190 ir_print_ptr_type_of(irp, (IrInstructionPtrTypeOf *)instruction);
11961191 break;
11971192 case IrInstructionIdSetGlobalSection:
11981193 ir_print_set_global_section(irp, (IrInstructionSetGlobalSection *)instruction);
src/parseh.cpp+8
......@@ -710,6 +710,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
710710 TypeTableEntry *enum_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base,
711711 ContainerKindEnum, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern);
712712 enum_type->data.enumeration.zero_bits_known = true;
713 enum_type->data.enumeration.abi_alignment = 1;
713714 c->enum_type_table.put(bare_name, enum_type);
714715 c->decl_table.put(enum_decl, enum_type);
715716 replace_with_fwd_decl(c, enum_type, full_type_name);
......@@ -741,6 +742,7 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
741742 enum_type->data.enumeration.gen_field_count = 0;
742743 enum_type->data.enumeration.complete = true;
743744 enum_type->data.enumeration.zero_bits_known = true;
745 enum_type->data.enumeration.abi_alignment = 1;
744746 enum_type->data.enumeration.tag_type = tag_type_entry;
745747
746748 enum_type->data.enumeration.src_field_count = field_count;
......@@ -778,6 +780,9 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
778780 // create llvm type for root struct
779781 enum_type->type_ref = tag_type_entry->type_ref;
780782
783 enum_type->data.enumeration.abi_alignment = LLVMABIAlignmentOfType(c->codegen->target_data_ref,
784 enum_type->type_ref);
785
781786 // create debug type for tag
782787 unsigned line = c->source_node ? (c->source_node->line + 1) : 0;
783788 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, enum_type->type_ref);
......@@ -864,6 +869,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
864869 TypeTableEntry *struct_type = get_partial_container_type(c->codegen, &c->import->decls_scope->base,
865870 ContainerKindStruct, c->source_node, buf_ptr(full_type_name), ContainerLayoutExtern);
866871 struct_type->data.structure.zero_bits_known = true;
872 struct_type->data.structure.abi_alignment = 1;
867873
868874 c->struct_type_table.put(bare_name, struct_type);
869875 c->decl_table.put(record_decl, struct_type);
......@@ -950,6 +956,8 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_
950956
951957 struct_type->data.structure.gen_field_count = field_count;
952958 struct_type->data.structure.complete = true;
959 struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(c->codegen->target_data_ref,
960 struct_type->type_ref);
953961
954962 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(c->codegen->target_data_ref, struct_type->type_ref);
955963 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(c->codegen->target_data_ref, struct_type->type_ref);
src/parser.cpp+90-38
......@@ -228,6 +228,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
228228static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index);
229229static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bool mandatory);
230230static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory);
231static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory);
231232
232233static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) {
233234 if (token->id == token_id) {
......@@ -384,7 +385,7 @@ static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bo
384385}
385386
386387/*
387ArrayType : "[" option(Expression) "]" option("const") PrefixOpExpression
388ArrayType : "[" option(Expression) "]" option("align" PrimaryExpression)) option("const") option("volatile") PrefixOpExpression
388389*/
389390static AstNode *ast_parse_array_type_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
390391 Token *l_bracket = &pc->tokens->at(*token_index);
......@@ -403,10 +404,22 @@ static AstNode *ast_parse_array_type_expr(ParseContext *pc, size_t *token_index,
403404
404405 ast_eat_token(pc, token_index, TokenIdRBracket);
405406
406 Token *const_tok = &pc->tokens->at(*token_index);
407 if (const_tok->id == TokenIdKeywordConst) {
407 Token *token = &pc->tokens->at(*token_index);
408 if (token->id == TokenIdKeywordAlign) {
409 *token_index += 1;
410 node->data.array_type.align_expr = ast_parse_primary_expr(pc, token_index, true);
411
412 token = &pc->tokens->at(*token_index);
413 }
414 if (token->id == TokenIdKeywordConst) {
408415 *token_index += 1;
409416 node->data.array_type.is_const = true;
417
418 token = &pc->tokens->at(*token_index);
419 }
420 if (token->id == TokenIdKeywordVolatile) {
421 *token_index += 1;
422 node->data.array_type.is_volatile = true;
410423 }
411424
412425 node->data.array_type.child_type = ast_parse_type_expr(pc, token_index, true);
......@@ -953,7 +966,6 @@ static PrefixOp tok_to_prefix_op(Token *token) {
953966 case TokenIdDash: return PrefixOpNegation;
954967 case TokenIdMinusPercent: return PrefixOpNegationWrap;
955968 case TokenIdTilde: return PrefixOpBinNot;
956 case TokenIdAmpersand: return PrefixOpAddressOf;
957969 case TokenIdStar: return PrefixOpDereference;
958970 case TokenIdMaybe: return PrefixOpMaybe;
959971 case TokenIdPercent: return PrefixOpError;
......@@ -964,12 +976,52 @@ static PrefixOp tok_to_prefix_op(Token *token) {
964976 }
965977}
966978
979static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {
980 Token *ampersand_tok = ast_eat_token(pc, token_index, TokenIdAmpersand);
981
982 AstNode *node = ast_create_node(pc, NodeTypeAddrOfExpr, ampersand_tok);
983
984 Token *token = &pc->tokens->at(*token_index);
985 if (token->id == TokenIdKeywordAlign) {
986 *token_index += 1;
987 node->data.addr_of_expr.align_expr = ast_parse_primary_expr(pc, token_index, true);
988
989 token = &pc->tokens->at(*token_index);
990 if (token->id == TokenIdColon) {
991 *token_index += 1;
992 Token *bit_offset_start_tok = ast_eat_token(pc, token_index, TokenIdIntLiteral);
993 ast_eat_token(pc, token_index, TokenIdColon);
994 Token *bit_offset_end_tok = ast_eat_token(pc, token_index, TokenIdIntLiteral);
995 token = &pc->tokens->at(*token_index);
996
997 node->data.addr_of_expr.bit_offset_start = token_bigint(bit_offset_start_tok);
998 node->data.addr_of_expr.bit_offset_end = token_bigint(bit_offset_end_tok);
999 }
1000 }
1001 if (token->id == TokenIdKeywordConst) {
1002 *token_index += 1;
1003 node->data.addr_of_expr.is_const = true;
1004
1005 token = &pc->tokens->at(*token_index);
1006 }
1007 if (token->id == TokenIdKeywordVolatile) {
1008 *token_index += 1;
1009 node->data.addr_of_expr.is_volatile = true;
1010 }
1011
1012 node->data.addr_of_expr.op_expr = ast_parse_prefix_op_expr(pc, token_index, true);
1013 return node;
1014}
1015
9671016/*
9681017PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression
969PrefixOp = "!" | "-" | "~" | "*" | ("&" option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%"
1018PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" PrimaryExpression option(":" Integer ":" Integer)) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%"
9701019*/
9711020static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
9721021 Token *token = &pc->tokens->at(*token_index);
1022 if (token->id == TokenIdAmpersand) {
1023 return ast_parse_addr_of(pc, token_index);
1024 }
9731025 PrefixOp prefix_op = tok_to_prefix_op(token);
9741026 if (prefix_op == PrefixOpInvalid) {
9751027 return ast_parse_suffix_op_expr(pc, token_index, mandatory);
......@@ -997,23 +1049,6 @@ static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index,
9971049 node->column += 1;
9981050 }
9991051
1000 if (prefix_op == PrefixOpAddressOf) {
1001 Token *const_or_volatile_tok = &pc->tokens->at(*token_index);
1002 if (const_or_volatile_tok->id == TokenIdKeywordConst) {
1003 *token_index += 1;
1004 Token *volatile_token = &pc->tokens->at(*token_index);
1005 if (volatile_token->id == TokenIdKeywordVolatile) {
1006 *token_index += 1;
1007 prefix_op = PrefixOpConstVolatileAddressOf;
1008 } else {
1009 prefix_op = PrefixOpConstAddressOf;
1010 }
1011 } else if (const_or_volatile_tok->id == TokenIdKeywordVolatile) {
1012 prefix_op = PrefixOpVolatileAddressOf;
1013 *token_index += 1;
1014 }
1015 }
1016
10171052 AstNode *prefix_op_expr = ast_parse_prefix_op_expr(pc, token_index, true);
10181053 node->data.prefix_op_expr.primary_expr = prefix_op_expr;
10191054 node->data.prefix_op_expr.prefix_op = prefix_op;
......@@ -1499,7 +1534,7 @@ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {
14991534}
15001535
15011536/*
1502VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) "=" Expression
1537VariableDeclaration = option("comptime") ("var" | "const") Symbol option(":" TypeExpr) option("align" PrimaryExpression) "=" Expression
15031538*/
15041539static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *token_index, bool mandatory,
15051540 VisibMod visib_mod)
......@@ -1549,25 +1584,28 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to
15491584 Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);
15501585 node->data.variable_declaration.symbol = token_buf(name_token);
15511586
1552 Token *eq_or_colon = &pc->tokens->at(*token_index);
1553 *token_index += 1;
1554 if (eq_or_colon->id == TokenIdEq) {
1555 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
1556 } else if (eq_or_colon->id == TokenIdColon) {
1587 Token *next_token = &pc->tokens->at(*token_index);
1588
1589 if (next_token->id == TokenIdColon) {
1590 *token_index += 1;
15571591 node->data.variable_declaration.type = ast_parse_type_expr(pc, token_index, true);
1558 Token *eq_token = &pc->tokens->at(*token_index);
1559 if (eq_token->id == TokenIdEq) {
1560 *token_index += 1;
1592 next_token = &pc->tokens->at(*token_index);
1593 }
15611594
1562 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
1563 }
1564 } else {
1565 ast_invalid_token_error(pc, eq_or_colon);
1595 if (next_token->id == TokenIdKeywordAlign) {
1596 *token_index += 1;
1597 node->data.variable_declaration.align_expr = ast_parse_primary_expr(pc, token_index, true);
1598 next_token = &pc->tokens->at(*token_index);
1599 }
1600
1601 if (next_token->id == TokenIdEq) {
1602 *token_index += 1;
1603 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
1604 next_token = &pc->tokens->at(*token_index);
15661605 }
15671606
15681607 // peek ahead and ensure that all variable declarations are followed by a semicolon
1569 Token *semicolon_token = &pc->tokens->at(*token_index);
1570 ast_expect_token(pc, semicolon_token, TokenIdSemicolon);
1608 ast_expect_token(pc, next_token, TokenIdSemicolon);
15711609
15721610 return node;
15731611}
......@@ -2165,7 +2203,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
21652203}
21662204
21672205/*
2168FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("->" TypeExpr)
2206FnProto = option("coldcc" | "nakedcc" | "stdcallcc") "fn" option(Symbol) ParamDeclList option("align" PrimaryExpression) option("->" TypeExpr)
21692207*/
21702208static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
21712209 Token *first_token = &pc->tokens->at(*token_index);
......@@ -2200,6 +2238,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
22002238 node->data.fn_proto.cc = cc;
22012239
22022240 Token *fn_name = &pc->tokens->at(*token_index);
2241
22032242 if (fn_name->id == TokenIdSymbol) {
22042243 *token_index += 1;
22052244 node->data.fn_proto.name = token_buf(fn_name);
......@@ -2210,6 +2249,12 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
22102249 ast_parse_param_decl_list(pc, token_index, &node->data.fn_proto.params, &node->data.fn_proto.is_var_args);
22112250
22122251 Token *next_token = &pc->tokens->at(*token_index);
2252 if (next_token->id == TokenIdKeywordAlign) {
2253 *token_index += 1;
2254
2255 node->data.fn_proto.align_expr = ast_parse_primary_expr(pc, token_index, true);
2256 next_token = &pc->tokens->at(*token_index);
2257 }
22132258 if (next_token->id == TokenIdArrow) {
22142259 *token_index += 1;
22152260 node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, false);
......@@ -2595,6 +2640,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
25952640 case NodeTypeFnProto:
25962641 visit_field(&node->data.fn_proto.return_type, visit, context);
25972642 visit_node_list(&node->data.fn_proto.params, visit, context);
2643 visit_field(&node->data.fn_proto.align_expr, visit, context);
25982644 break;
25992645 case NodeTypeFnDef:
26002646 visit_field(&node->data.fn_def.fn_proto, visit, context);
......@@ -2621,6 +2667,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
26212667 case NodeTypeVariableDeclaration:
26222668 visit_field(&node->data.variable_declaration.type, visit, context);
26232669 visit_field(&node->data.variable_declaration.expr, visit, context);
2670 visit_field(&node->data.variable_declaration.align_expr, visit, context);
26242671 break;
26252672 case NodeTypeErrorValueDecl:
26262673 // none
......@@ -2769,6 +2816,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
27692816 case NodeTypeArrayType:
27702817 visit_field(&node->data.array_type.size, visit, context);
27712818 visit_field(&node->data.array_type.child_type, visit, context);
2819 visit_field(&node->data.array_type.align_expr, visit, context);
27722820 break;
27732821 case NodeTypeErrorType:
27742822 // none
......@@ -2776,5 +2824,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
27762824 case NodeTypeVarLiteral:
27772825 // none
27782826 break;
2827 case NodeTypeAddrOfExpr:
2828 visit_field(&node->data.addr_of_expr.align_expr, visit, context);
2829 visit_field(&node->data.addr_of_expr.op_expr, visit, context);
2830 break;
27792831 }
27802832}
src/tokenizer.cpp+2
......@@ -107,6 +107,7 @@ struct ZigKeyword {
107107};
108108
109109static const struct ZigKeyword zig_keywords[] = {
110 {"align", TokenIdKeywordAlign},
110111 {"and", TokenIdKeywordAnd},
111112 {"asm", TokenIdKeywordAsm},
112113 {"break", TokenIdKeywordBreak},
......@@ -1454,6 +1455,7 @@ const char * token_name(TokenId id) {
14541455 case TokenIdFatArrow: return "=>";
14551456 case TokenIdFloatLiteral: return "FloatLiteral";
14561457 case TokenIdIntLiteral: return "IntLiteral";
1458 case TokenIdKeywordAlign: return "align";
14571459 case TokenIdKeywordAnd: return "and";
14581460 case TokenIdKeywordAsm: return "asm";
14591461 case TokenIdKeywordBreak: return "break";
src/tokenizer.hpp+1
......@@ -46,6 +46,7 @@ enum TokenId {
4646 TokenIdFatArrow,
4747 TokenIdFloatLiteral,
4848 TokenIdIntLiteral,
49 TokenIdKeywordAlign,
4950 TokenIdKeywordAnd,
5051 TokenIdKeywordAsm,
5152 TokenIdKeywordBreak,
src/zig_llvm.cpp-5
......@@ -713,11 +713,6 @@ void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module) {
713713 unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION);
714714}
715715
716unsigned ZigLLVMGetPrefTypeAlignment(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
717 return unwrap(TD)->getPrefTypeAlignment(unwrap(Ty));
718}
719
720
721716static AtomicOrdering mapFromLLVMOrdering(LLVMAtomicOrdering Ordering) {
722717 switch (Ordering) {
723718 case LLVMAtomicOrderingNotAtomic: return AtomicOrdering::NotAtomic;
src/zig_llvm.hpp-2
......@@ -167,8 +167,6 @@ void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state);
167167void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value);
168168void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn);
169169
170unsigned ZigLLVMGetPrefTypeAlignment(LLVMTargetDataRef TD, LLVMTypeRef Ty);
171
172170
173171// copied from include/llvm/ADT/Triple.h
174172
std/hash_map.zig+1-1
......@@ -251,7 +251,7 @@ test "basicHashMapTest" {
251251}
252252
253253fn hash_i32(x: i32) -> u32 {
254 *@ptrCast(&u32, &x)
254 @bitCast(u32, x)
255255}
256256
257257fn eql_i32(a: i32, b: i32) -> bool {
std/mem.zig+1-4
......@@ -21,10 +21,7 @@ pub const Allocator = struct {
2121
2222 /// Aborts the program if an allocation fails.
2323 fn checkedAlloc(self: &Allocator, comptime T: type, n: usize) -> []T {
24 alloc(self, T, n) %% |err| {
25 %%io.stderr.printf("allocation failure: {}\n", @errorName(err));
26 os.abort()
27 }
24 alloc(self, T, n) %% |err| debug.panic("allocation failure: {}", @errorName(err))
2825 }
2926
3027 fn create(self: &Allocator, comptime T: type) -> %&T {
test/cases/alignof.zig+3-6
......@@ -3,12 +3,9 @@ const builtin = @import("builtin");
33
44const Foo = struct { x: u32, y: u32, z: u32, };
55
6test "@abiAlignOf(T) before referencing T" {
7 comptime assert(@cAbiAlignOf(Foo) != @maxValue(usize));
6test "@alignOf(T) before referencing T" {
7 comptime assert(@alignOf(Foo) != @maxValue(usize));
88 if (builtin.arch == builtin.Arch.x86_64) {
9 comptime {
10 assert(@cAbiAlignOf(Foo) == 4);
11 assert(@preferredAlignOf(Foo) == 8);
12 }
9 comptime assert(@alignOf(Foo) == 4);
1310 }
1411}
test/cases/enum.zig+2-2
......@@ -124,8 +124,8 @@ const BareNumber = enum {
124124
125125test "enum alignment" {
126126 comptime {
127 assert(@cAbiAlignOf(AlignTestEnum) >= @cAbiAlignOf([9]u8));
128 assert(@cAbiAlignOf(AlignTestEnum) >= @cAbiAlignOf(u64));
127 assert(@alignOf(AlignTestEnum) >= @alignOf([9]u8));
128 assert(@alignOf(AlignTestEnum) >= @alignOf(u64));
129129 }
130130}
131131
test/cases/struct.zig-2
......@@ -201,8 +201,6 @@ test "packed struct" {
201201}
202202
203203
204const u2 = @IntType(false, 2);
205
206204const BitField1 = packed struct {
207205 a: u3,
208206 b: u3,
test/cases/switch.zig-1
......@@ -172,7 +172,6 @@ test "switch handles all cases of number" {
172172 comptime testSwitchHandleAllCases();
173173}
174174
175const u2 = @IntType(false, 2);
176175fn testSwitchHandleAllCases() {
177176 assert(testSwitchHandleAllCasesExhaustive(0) == 3);
178177 assert(testSwitchHandleAllCasesExhaustive(1) == 2);
test/compile_errors.zig+9-28
......@@ -1316,13 +1316,15 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
13161316 \\}
13171317 , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");
13181318
1319 cases.add("set global variable alignment to non power of 2",
1320 \\const some_data: [100]u8 = undefined;
1321 \\comptime {
1322 \\ @setGlobalAlign(some_data, 3);
1323 \\}
1319 cases.add("global variable alignment non power of 2",
1320 \\const some_data: [100]u8 align 3 = undefined;
13241321 \\export fn entry() -> usize { @sizeOf(@typeOf(some_data)) }
1325 , ".tmp_source.zig:3:32: error: alignment value must be power of 2");
1322 , ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2");
1323
1324 cases.add("function alignment non power of 2",
1325 \\extern fn foo() align 3;
1326 \\export fn entry() { foo() }
1327 , ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2");
13261328
13271329 cases.add("compile log",
13281330 \\export fn foo() {
......@@ -1342,9 +1344,6 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
13421344 ".tmp_source.zig:2:17: note: called from here");
13431345
13441346 cases.add("casting bit offset pointer to regular pointer",
1345 \\const u2 = @IntType(false, 2);
1346 \\const u3 = @IntType(false, 3);
1347 \\
13481347 \\const BitField = packed struct {
13491348 \\ a: u3,
13501349 \\ b: u3,
......@@ -1360,7 +1359,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
13601359 \\}
13611360 \\
13621361 \\export fn entry() -> usize { @sizeOf(@typeOf(foo)) }
1363 , ".tmp_source.zig:11:26: error: expected type '&const u3', found '&:3:6 const u3'");
1362 , ".tmp_source.zig:8:26: error: expected type '&const u3', found '&align 1:3:6 const u3'");
13641363
13651364 cases.add("referring to a struct that is invalid",
13661365 \\const UsbDeviceRequest = struct {
......@@ -1626,24 +1625,6 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
16261625 "error: 'main' is private",
16271626 ".tmp_source.zig:1:1: note: declared here");
16281627
1629 cases.add("@setGlobalAlign extern variable",
1630 \\extern var foo: i32;
1631 \\comptime {
1632 \\ @setGlobalAlign(foo, 4);
1633 \\}
1634 ,
1635 ".tmp_source.zig:3:5: error: cannot set alignment of external variable 'foo'",
1636 ".tmp_source.zig:1:8: note: declared here");
1637
1638 cases.add("@setGlobalAlign extern fn",
1639 \\extern fn foo();
1640 \\comptime {
1641 \\ @setGlobalAlign(foo, 4);
1642 \\}
1643 ,
1644 ".tmp_source.zig:3:5: error: cannot set alignment of external function 'foo'",
1645 ".tmp_source.zig:1:8: note: declared here");
1646
16471628 cases.add("@setGlobalSection extern variable",
16481629 \\extern var foo: i32;
16491630 \\comptime {