authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-27 01:28:08-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-10-27 01:28:08-04:00
log540bac09280dc9511145f44fda49d3a84b699820
tree1443e18d6e54093366615789ae36e1e0f3fb04bd
parent4f4da3c10c56eb1d60fdb2a98a46634d4dc608fe
parent4c306af4eb79071c966b99e877970f0a4582d891

Merge branch 'master' into self-hosted


37 files changed, 498 insertions(+), 204 deletions(-)

c_headers/stdarg.h+4
...@@ -26,10 +26,14 @@...@@ -26,10 +26,14 @@
26#ifndef __STDARG_H26#ifndef __STDARG_H
27#define __STDARG_H27#define __STDARG_H
2828
29/* zig: added because macos _va_list.h was duplicately defining va_list
30 */
29#ifndef _VA_LIST31#ifndef _VA_LIST
32#ifndef _VA_LIST_T
30typedef __builtin_va_list va_list;33typedef __builtin_va_list va_list;
31#define _VA_LIST34#define _VA_LIST
32#endif35#endif
36#endif
33#define va_start(ap, param) __builtin_va_start(ap, param)37#define va_start(ap, param) __builtin_va_start(ap, param)
34#define va_end(ap) __builtin_va_end(ap)38#define va_end(ap) __builtin_va_end(ap)
35#define va_arg(ap, type) __builtin_va_arg(ap, type)39#define va_arg(ap, type) __builtin_va_arg(ap, type)
src-self-hosted/main.zig+1
...@@ -5,6 +5,7 @@ const heap = @import("std").mem;...@@ -5,6 +5,7 @@ const heap = @import("std").mem;
55
6// TODO: OutSteam and InStream interface6// TODO: OutSteam and InStream interface
7// TODO: move allocator to heap namespace7// TODO: move allocator to heap namespace
8// TODO: sync up CLI with c++ code
89
9error InvalidArgument;10error InvalidArgument;
10error MissingArg0;11error MissingArg0;
src/all_types.hpp+7-1
...@@ -1008,6 +1008,9 @@ struct TypeTableEntryEnum {...@@ -1008,6 +1008,9 @@ struct TypeTableEntryEnum {
10081008
1009 size_t gen_union_index;1009 size_t gen_union_index;
1010 size_t gen_tag_index;1010 size_t gen_tag_index;
1011
1012 uint32_t union_size_bytes;
1013 TypeTableEntry *most_aligned_union_member;
1011};1014};
10121015
1013struct TypeTableEntryEnumTag {1016struct TypeTableEntryEnumTag {
...@@ -1514,9 +1517,12 @@ struct CodeGen {...@@ -1514,9 +1517,12 @@ struct CodeGen {
1514 size_t version_major;1517 size_t version_major;
1515 size_t version_minor;1518 size_t version_minor;
1516 size_t version_patch;1519 size_t version_patch;
1517 bool verbose;1520 bool verbose_tokenize;
1521 bool verbose_ast;
1518 bool verbose_link;1522 bool verbose_link;
1519 bool verbose_ir;1523 bool verbose_ir;
1524 bool verbose_llvm_ir;
1525 bool verbose_cimport;
1520 ErrColor err_color;1526 ErrColor err_color;
1521 ImportTableEntry *root_import;1527 ImportTableEntry *root_import;
1522 ImportTableEntry *bootstrap_import;1528 ImportTableEntry *bootstrap_import;
src/analyze.cpp+34-16
...@@ -27,9 +27,17 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type);...@@ -27,9 +27,17 @@ static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type);
27static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type);27static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type);
2828
29ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {29ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
30 // if this assert fails, then parsec generated code that30 if (node->owner->c_import_node != nullptr) {
31 // failed semantic analysis, which isn't supposed to happen31 // if this happens, then parsec generated code that
32 assert(!node->owner->c_import_node);32 // failed semantic analysis, which isn't supposed to happen
33 ErrorMsg *err = add_node_error(g, node->owner->c_import_node,
34 buf_sprintf("compiler bug: @cImport generated invalid zig code"));
35
36 add_error_note(g, err, node, msg);
37
38 g->errors.append(err);
39 return err;
40 }
3341
34 ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column,42 ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column,
35 node->owner->source_code, node->owner->line_offsets, msg);43 node->owner->source_code, node->owner->line_offsets, msg);
...@@ -39,9 +47,20 @@ ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {...@@ -39,9 +47,20 @@ ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
39}47}
4048
41ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg) {49ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg) {
42 // if this assert fails, then parsec generated code that50 if (node->owner->c_import_node != nullptr) {
43 // failed semantic analysis, which isn't supposed to happen51 // if this happens, then parsec generated code that
44 assert(!node->owner->c_import_node);52 // failed semantic analysis, which isn't supposed to happen
53
54 Buf *note_path = buf_create_from_str("?.c");
55 Buf *note_source = buf_create_from_str("TODO: remember C source location to display here ");
56 ZigList<size_t> note_line_offsets = {0};
57 note_line_offsets.append(0);
58 ErrorMsg *note = err_msg_create_with_line(note_path, 0, 0,
59 note_source, &note_line_offsets, msg);
60
61 err_msg_add_note(parent_msg, note);
62 return note;
63 }
4564
46 ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column,65 ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column,
47 node->owner->source_code, node->owner->line_offsets, msg);66 node->owner->source_code, node->owner->line_offsets, msg);
...@@ -1344,6 +1363,8 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {...@@ -1344,6 +1363,8 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
1344 // unset temporary flag1363 // unset temporary flag
1345 enum_type->data.enumeration.embedded_in_current = false;1364 enum_type->data.enumeration.embedded_in_current = false;
1346 enum_type->data.enumeration.complete = true;1365 enum_type->data.enumeration.complete = true;
1366 enum_type->data.enumeration.union_size_bytes = biggest_size_in_bits / 8;
1367 enum_type->data.enumeration.most_aligned_union_member = most_aligned_union_member;
13471368
1348 if (!enum_type->data.enumeration.is_invalid) {1369 if (!enum_type->data.enumeration.is_invalid) {
1349 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count);1370 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count);
...@@ -1365,10 +1386,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {...@@ -1365,10 +1386,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
1365 };1386 };
1366 union_type_ref = LLVMStructType(union_element_types, 2, false);1387 union_type_ref = LLVMStructType(union_element_types, 2, false);
1367 } else {1388 } else {
1368 LLVMTypeRef union_element_types[] = {1389 union_type_ref = most_aligned_union_member->type_ref;
1369 most_aligned_union_member->type_ref,
1370 };
1371 union_type_ref = LLVMStructType(union_element_types, 1, false);
1372 }1390 }
1373 enum_type->data.enumeration.union_type_ref = union_type_ref;1391 enum_type->data.enumeration.union_type_ref = union_type_ref;
13741392
...@@ -2804,7 +2822,6 @@ static bool is_container(TypeTableEntry *type_entry) {...@@ -2804,7 +2822,6 @@ static bool is_container(TypeTableEntry *type_entry) {
2804 switch (type_entry->id) {2822 switch (type_entry->id) {
2805 case TypeTableEntryIdInvalid:2823 case TypeTableEntryIdInvalid:
2806 case TypeTableEntryIdVar:2824 case TypeTableEntryIdVar:
2807 case TypeTableEntryIdOpaque:
2808 zig_unreachable();2825 zig_unreachable();
2809 case TypeTableEntryIdStruct:2826 case TypeTableEntryIdStruct:
2810 case TypeTableEntryIdEnum:2827 case TypeTableEntryIdEnum:
...@@ -2831,6 +2848,7 @@ static bool is_container(TypeTableEntry *type_entry) {...@@ -2831,6 +2848,7 @@ static bool is_container(TypeTableEntry *type_entry) {
2831 case TypeTableEntryIdBoundFn:2848 case TypeTableEntryIdBoundFn:
2832 case TypeTableEntryIdEnumTag:2849 case TypeTableEntryIdEnumTag:
2833 case TypeTableEntryIdArgTuple:2850 case TypeTableEntryIdArgTuple:
2851 case TypeTableEntryIdOpaque:
2834 return false;2852 return false;
2835 }2853 }
2836 zig_unreachable();2854 zig_unreachable();
...@@ -2982,7 +3000,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ...@@ -2982,7 +3000,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ
2982 return;3000 return;
2983 }3001 }
29843002
2985 if (g->verbose) {3003 if (g->verbose_ir) {
2986 fprintf(stderr, "{ // (analyzed)\n");3004 fprintf(stderr, "{ // (analyzed)\n");
2987 ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);3005 ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);
2988 fprintf(stderr, "}\n");3006 fprintf(stderr, "}\n");
...@@ -3015,7 +3033,7 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -3015,7 +3033,7 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
3015 fn_table_entry->anal_state = FnAnalStateInvalid;3033 fn_table_entry->anal_state = FnAnalStateInvalid;
3016 return;3034 return;
3017 }3035 }
3018 if (g->verbose) {3036 if (g->verbose_ir) {
3019 fprintf(stderr, "\n");3037 fprintf(stderr, "\n");
3020 ast_render(g, stderr, fn_table_entry->body_node, 4);3038 ast_render(g, stderr, fn_table_entry->body_node, 4);
3021 fprintf(stderr, "\n{ // (IR)\n");3039 fprintf(stderr, "\n{ // (IR)\n");
...@@ -3115,7 +3133,7 @@ void preview_use_decl(CodeGen *g, AstNode *node) {...@@ -3115,7 +3133,7 @@ void preview_use_decl(CodeGen *g, AstNode *node) {
3115}3133}
31163134
3117ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code) {3135ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code) {
3118 if (g->verbose) {3136 if (g->verbose_tokenize) {
3119 fprintf(stderr, "\nOriginal Source (%s):\n", buf_ptr(abs_full_path));3137 fprintf(stderr, "\nOriginal Source (%s):\n", buf_ptr(abs_full_path));
3120 fprintf(stderr, "----------------\n");3138 fprintf(stderr, "----------------\n");
3121 fprintf(stderr, "%s\n", buf_ptr(source_code));3139 fprintf(stderr, "%s\n", buf_ptr(source_code));
...@@ -3135,7 +3153,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a...@@ -3135,7 +3153,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
3135 exit(1);3153 exit(1);
3136 }3154 }
31373155
3138 if (g->verbose) {3156 if (g->verbose_tokenize) {
3139 print_tokens(source_code, tokenization.tokens);3157 print_tokens(source_code, tokenization.tokens);
31403158
3141 fprintf(stderr, "\nAST:\n");3159 fprintf(stderr, "\nAST:\n");
...@@ -3150,7 +3168,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a...@@ -3150,7 +3168,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
31503168
3151 import_entry->root = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color);3169 import_entry->root = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color);
3152 assert(import_entry->root);3170 assert(import_entry->root);
3153 if (g->verbose) {3171 if (g->verbose_ast) {
3154 ast_print(stderr, import_entry->root, 0);3172 ast_print(stderr, import_entry->root, 0);
3155 }3173 }
31563174
src/codegen.cpp+73-34
...@@ -196,10 +196,6 @@ void codegen_set_is_static(CodeGen *g, bool is_static) {...@@ -196,10 +196,6 @@ void codegen_set_is_static(CodeGen *g, bool is_static) {
196 g->is_static = is_static;196 g->is_static = is_static;
197}197}
198198
199void codegen_set_verbose(CodeGen *g, bool verbose) {
200 g->verbose = verbose;
201}
202
203void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) {199void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) {
204 g->each_lib_rpath = each_lib_rpath;200 g->each_lib_rpath = each_lib_rpath;
205}201}
...@@ -452,10 +448,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -452,10 +448,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
452 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMExternalLinkage);448 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMExternalLinkage);
453 break;449 break;
454 case GlobalLinkageIdWeak:450 case GlobalLinkageIdWeak:
455 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMWeakAnyLinkage);451 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMWeakODRLinkage);
456 break;452 break;
457 case GlobalLinkageIdLinkOnce:453 case GlobalLinkageIdLinkOnce:
458 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMLinkOnceAnyLinkage);454 LLVMSetLinkage(fn_table_entry->llvm_value, LLVMLinkOnceODRLinkage);
459 break;455 break;
460 }456 }
461457
...@@ -3665,6 +3661,12 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con...@@ -3665,6 +3661,12 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
3665 zig_unreachable();3661 zig_unreachable();
3666}3662}
36673663
3664// We have this because union constants can't be represented by the official union type,
3665// and this property bubbles up in whatever aggregate type contains a union constant
3666static bool is_llvm_value_unnamed_type(TypeTableEntry *type_entry, LLVMValueRef val) {
3667 return LLVMTypeOf(val) != type_entry->type_ref;
3668}
3669
3668static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {3670static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3669 TypeTableEntry *type_entry = const_val->type;3671 TypeTableEntry *type_entry = const_val->type;
3670 assert(!type_entry->zero_bits);3672 assert(!type_entry->zero_bits);
...@@ -3726,24 +3728,34 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3726,24 +3728,34 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3726 } else {3728 } else {
3727 LLVMValueRef child_val;3729 LLVMValueRef child_val;
3728 LLVMValueRef maybe_val;3730 LLVMValueRef maybe_val;
3731 bool make_unnamed_struct;
3729 if (const_val->data.x_maybe) {3732 if (const_val->data.x_maybe) {
3730 child_val = gen_const_val(g, const_val->data.x_maybe);3733 child_val = gen_const_val(g, const_val->data.x_maybe);
3731 maybe_val = LLVMConstAllOnes(LLVMInt1Type());3734 maybe_val = LLVMConstAllOnes(LLVMInt1Type());
3735
3736 make_unnamed_struct = is_llvm_value_unnamed_type(const_val->type, child_val);
3732 } else {3737 } else {
3733 child_val = LLVMConstNull(child_type->type_ref);3738 child_val = LLVMGetUndef(child_type->type_ref);
3734 maybe_val = LLVMConstNull(LLVMInt1Type());3739 maybe_val = LLVMConstNull(LLVMInt1Type());
3740
3741 make_unnamed_struct = false;
3735 }3742 }
3736 LLVMValueRef fields[] = {3743 LLVMValueRef fields[] = {
3737 child_val,3744 child_val,
3738 maybe_val,3745 maybe_val,
3739 };3746 };
3740 return LLVMConstStruct(fields, 2, false);3747 if (make_unnamed_struct) {
3748 return LLVMConstStruct(fields, 2, false);
3749 } else {
3750 return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
3751 }
3741 }3752 }
3742 }3753 }
3743 case TypeTableEntryIdStruct:3754 case TypeTableEntryIdStruct:
3744 {3755 {
3745 LLVMValueRef *fields = allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count);3756 LLVMValueRef *fields = allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count);
3746 size_t src_field_count = type_entry->data.structure.src_field_count;3757 size_t src_field_count = type_entry->data.structure.src_field_count;
3758 bool make_unnamed_struct = false;
3747 if (type_entry->data.structure.layout == ContainerLayoutPacked) {3759 if (type_entry->data.structure.layout == ContainerLayoutPacked) {
3748 size_t src_field_index = 0;3760 size_t src_field_index = 0;
3749 while (src_field_index < src_field_count) {3761 while (src_field_index < src_field_count) {
...@@ -3761,8 +3773,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3761,8 +3773,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3761 }3773 }
37623774
3763 if (src_field_index + 1 == src_field_index_end) {3775 if (src_field_index + 1 == src_field_index_end) {
3764 fields[type_struct_field->gen_index] =3776 ConstExprValue *field_val = &const_val->data.x_struct.fields[src_field_index];
3765 gen_const_val(g, &const_val->data.x_struct.fields[src_field_index]);3777 LLVMValueRef val = gen_const_val(g, field_val);
3778 fields[type_struct_field->gen_index] = val;
3779 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(field_val->type, val);
3766 } else {3780 } else {
3767 LLVMTypeRef big_int_type_ref = LLVMStructGetTypeAtIndex(type_entry->type_ref,3781 LLVMTypeRef big_int_type_ref = LLVMStructGetTypeAtIndex(type_entry->type_ref,
3768 (unsigned)type_struct_field->gen_index);3782 (unsigned)type_struct_field->gen_index);
...@@ -3790,11 +3804,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3790,11 +3804,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3790 if (type_struct_field->gen_index == SIZE_MAX) {3804 if (type_struct_field->gen_index == SIZE_MAX) {
3791 continue;3805 continue;
3792 }3806 }
3793 fields[type_struct_field->gen_index] = gen_const_val(g, &const_val->data.x_struct.fields[i]);3807 ConstExprValue *field_val = &const_val->data.x_struct.fields[i];
3808 LLVMValueRef val = gen_const_val(g, field_val);
3809 fields[type_struct_field->gen_index] = val;
3810 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(field_val->type, val);
3794 }3811 }
3795 }3812 }
3796 return LLVMConstStruct(fields, type_entry->data.structure.gen_field_count,3813 if (make_unnamed_struct) {
3797 type_entry->data.structure.layout == ContainerLayoutPacked);3814 return LLVMConstStruct(fields, type_entry->data.structure.gen_field_count,
3815 type_entry->data.structure.layout == ContainerLayoutPacked);
3816 } else {
3817 return LLVMConstNamedStruct(type_entry->type_ref, fields, type_entry->data.structure.gen_field_count);
3818 }
3798 }3819 }
3799 case TypeTableEntryIdUnion:3820 case TypeTableEntryIdUnion:
3800 {3821 {
...@@ -3808,11 +3829,19 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3808,11 +3829,19 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3808 }3829 }
38093830
3810 LLVMValueRef *values = allocate<LLVMValueRef>(len);3831 LLVMValueRef *values = allocate<LLVMValueRef>(len);
3832 LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref;
3833 bool make_unnamed_struct = false;
3811 for (uint64_t i = 0; i < len; i += 1) {3834 for (uint64_t i = 0; i < len; i += 1) {
3812 ConstExprValue *elem_value = &const_val->data.x_array.s_none.elements[i];3835 ConstExprValue *elem_value = &const_val->data.x_array.s_none.elements[i];
3813 values[i] = gen_const_val(g, elem_value);3836 LLVMValueRef val = gen_const_val(g, elem_value);
3837 values[i] = val;
3838 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val);
3839 }
3840 if (make_unnamed_struct) {
3841 return LLVMConstStruct(values, len, true);
3842 } else {
3843 return LLVMConstArray(element_type_ref, values, (unsigned)len);
3814 }3844 }
3815 return LLVMConstArray(LLVMTypeOf(values[0]), values, (unsigned)len);
3816 }3845 }
3817 case TypeTableEntryIdEnum:3846 case TypeTableEntryIdEnum:
3818 {3847 {
...@@ -3825,14 +3854,20 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3825,14 +3854,20 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3825 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag];3854 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag];
3826 assert(enum_field->value == const_val->data.x_enum.tag);3855 assert(enum_field->value == const_val->data.x_enum.tag);
3827 LLVMValueRef union_value;3856 LLVMValueRef union_value;
3857
3858 bool make_unnamed_struct;
3859
3828 if (type_has_bits(enum_field->type_entry)) {3860 if (type_has_bits(enum_field->type_entry)) {
3829 uint64_t union_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,
3830 union_type_ref);
3831 uint64_t field_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,3861 uint64_t field_type_bytes = LLVMStoreSizeOfType(g->target_data_ref,
3832 enum_field->type_entry->type_ref);3862 enum_field->type_entry->type_ref);
3833 uint64_t pad_bytes = union_type_bytes - field_type_bytes;3863 uint64_t pad_bytes = type_entry->data.enumeration.union_size_bytes - field_type_bytes;
3864
3865 ConstExprValue *payload_value = const_val->data.x_enum.payload;
3866 LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value);
3867
3868 make_unnamed_struct = is_llvm_value_unnamed_type(payload_value->type, correctly_typed_value) ||
3869 payload_value->type != type_entry->data.enumeration.most_aligned_union_member;
38343870
3835 LLVMValueRef correctly_typed_value = gen_const_val(g, const_val->data.x_enum.payload);
3836 if (pad_bytes == 0) {3871 if (pad_bytes == 0) {
3837 union_value = correctly_typed_value;3872 union_value = correctly_typed_value;
3838 } else {3873 } else {
...@@ -3843,12 +3878,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3843,12 +3878,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3843 union_value = LLVMConstStruct(fields, 2, false);3878 union_value = LLVMConstStruct(fields, 2, false);
3844 }3879 }
3845 } else {3880 } else {
3881 make_unnamed_struct = false;
3846 union_value = LLVMGetUndef(union_type_ref);3882 union_value = LLVMGetUndef(union_type_ref);
3847 }3883 }
3848 LLVMValueRef fields[2];3884 LLVMValueRef fields[2];
3849 fields[type_entry->data.enumeration.gen_tag_index] = tag_value;3885 fields[type_entry->data.enumeration.gen_tag_index] = tag_value;
3850 fields[type_entry->data.enumeration.gen_union_index] = union_value;3886 fields[type_entry->data.enumeration.gen_union_index] = union_value;
3851 return LLVMConstStruct(fields, 2, false);3887
3888 if (make_unnamed_struct) {
3889 return LLVMConstStruct(fields, 2, false);
3890 } else {
3891 return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
3892 }
3852 }3893 }
3853 }3894 }
3854 case TypeTableEntryIdFn:3895 case TypeTableEntryIdFn:
...@@ -3932,18 +3973,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3932,18 +3973,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3932 } else {3973 } else {
3933 LLVMValueRef err_tag_value;3974 LLVMValueRef err_tag_value;
3934 LLVMValueRef err_payload_value;3975 LLVMValueRef err_payload_value;
3976 bool make_unnamed_struct;
3935 if (const_val->data.x_err_union.err) {3977 if (const_val->data.x_err_union.err) {
3936 err_tag_value = LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err_union.err->value, false);3978 err_tag_value = LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err_union.err->value, false);
3937 err_payload_value = LLVMConstNull(child_type->type_ref);3979 err_payload_value = LLVMConstNull(child_type->type_ref);
3980 make_unnamed_struct = false;
3938 } else {3981 } else {
3939 err_tag_value = LLVMConstNull(g->err_tag_type->type_ref);3982 err_tag_value = LLVMConstNull(g->err_tag_type->type_ref);
3940 err_payload_value = gen_const_val(g, const_val->data.x_err_union.payload);3983 ConstExprValue *payload_val = const_val->data.x_err_union.payload;
3984 err_payload_value = gen_const_val(g, payload_val);
3985 make_unnamed_struct = is_llvm_value_unnamed_type(payload_val->type, err_payload_value);
3941 }3986 }
3942 LLVMValueRef fields[] = {3987 LLVMValueRef fields[] = {
3943 err_tag_value,3988 err_tag_value,
3944 err_payload_value,3989 err_payload_value,
3945 };3990 };
3946 return LLVMConstStruct(fields, 2, false);3991 if (make_unnamed_struct) {
3992 return LLVMConstStruct(fields, 2, false);
3993 } else {
3994 return LLVMConstNamedStruct(type_entry->type_ref, fields, 2);
3995 }
3947 }3996 }
3948 }3997 }
3949 case TypeTableEntryIdVoid:3998 case TypeTableEntryIdVoid:
...@@ -4159,10 +4208,6 @@ static void validate_inline_fns(CodeGen *g) {...@@ -4159,10 +4208,6 @@ static void validate_inline_fns(CodeGen *g) {
4159}4208}
41604209
4161static void do_code_gen(CodeGen *g) {4210static void do_code_gen(CodeGen *g) {
4162 if (g->verbose) {
4163 fprintf(stderr, "\nCode Generation:\n");
4164 fprintf(stderr, "------------------\n");
4165 }
4166 assert(!g->errors.length);4211 assert(!g->errors.length);
41674212
4168 codegen_add_time_event(g, "Code Generation");4213 codegen_add_time_event(g, "Code Generation");
...@@ -4439,7 +4484,8 @@ static void do_code_gen(CodeGen *g) {...@@ -4439,7 +4484,8 @@ static void do_code_gen(CodeGen *g) {
44394484
4440 ZigLLVMDIBuilderFinalize(g->dbuilder);4485 ZigLLVMDIBuilderFinalize(g->dbuilder);
44414486
4442 if (g->verbose || g->verbose_ir) {4487 if (g->verbose_llvm_ir) {
4488 fflush(stderr);
4443 LLVMDumpModule(g->module);4489 LLVMDumpModule(g->module);
4444 }4490 }
44454491
...@@ -5269,10 +5315,6 @@ static void gen_root_source(CodeGen *g) {...@@ -5269,10 +5315,6 @@ static void gen_root_source(CodeGen *g) {
5269 resolve_top_level_decl(g, panic_tld, false, nullptr);5315 resolve_top_level_decl(g, panic_tld, false, nullptr);
5270 }5316 }
52715317
5272 if (g->verbose) {
5273 fprintf(stderr, "\nIR Generation and Semantic Analysis:\n");
5274 fprintf(stderr, "--------------------------------------\n");
5275 }
5276 if (!g->error_during_imports) {5318 if (!g->error_during_imports) {
5277 semantic_analyze(g);5319 semantic_analyze(g);
5278 }5320 }
...@@ -5286,9 +5328,6 @@ static void gen_root_source(CodeGen *g) {...@@ -5286,9 +5328,6 @@ static void gen_root_source(CodeGen *g) {
5286 }5328 }
52875329
5288 report_errors_and_maybe_exit(g);5330 report_errors_and_maybe_exit(g);
5289 if (g->verbose) {
5290 fprintf(stderr, "OK\n");
5291 }
52925331
5293}5332}
52945333
src/codegen.hpp-1
...@@ -25,7 +25,6 @@ void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);...@@ -25,7 +25,6 @@ void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);
2525
26void codegen_set_is_static(CodeGen *codegen, bool is_static);26void codegen_set_is_static(CodeGen *codegen, bool is_static);
27void codegen_set_strip(CodeGen *codegen, bool strip);27void codegen_set_strip(CodeGen *codegen, bool strip);
28void codegen_set_verbose(CodeGen *codegen, bool verbose);
29void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);28void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);
30void codegen_set_out_name(CodeGen *codegen, Buf *out_name);29void codegen_set_out_name(CodeGen *codegen, Buf *out_name);
31void codegen_set_libc_lib_dir(CodeGen *codegen, Buf *libc_lib_dir);30void codegen_set_libc_lib_dir(CodeGen *codegen, Buf *libc_lib_dir);
src/config.h.in-1
...@@ -20,7 +20,6 @@...@@ -20,7 +20,6 @@
20#define ZIG_DYNAMIC_LINKER "@ZIG_DYNAMIC_LINKER@"20#define ZIG_DYNAMIC_LINKER "@ZIG_DYNAMIC_LINKER@"
2121
22#cmakedefine ZIG_EACH_LIB_RPATH22#cmakedefine ZIG_EACH_LIB_RPATH
23#cmakedefine ZIG_LLVM_OLD_CXX_ABI
2423
25// Only used for running tests before installing.24// Only used for running tests before installing.
26#define ZIG_TEST_DIR "@CMAKE_SOURCE_DIR@/test"25#define ZIG_TEST_DIR "@CMAKE_SOURCE_DIR@/test"
src/errmsg.cpp+1
...@@ -123,6 +123,7 @@ ErrorMsg *err_msg_create_with_line(Buf *path, size_t line, size_t column,...@@ -123,6 +123,7 @@ ErrorMsg *err_msg_create_with_line(Buf *path, size_t line, size_t column,
123 size_t end_line = line + 1;123 size_t end_line = line + 1;
124 size_t line_end_offset = (end_line >= line_offsets->length) ? buf_len(source) : line_offsets->at(line + 1);124 size_t line_end_offset = (end_line >= line_offsets->length) ? buf_len(source) : line_offsets->at(line + 1);
125 size_t len = (line_end_offset + 1 > line_start_offset) ? (line_end_offset - line_start_offset - 1) : 0;125 size_t len = (line_end_offset + 1 > line_start_offset) ? (line_end_offset - line_start_offset - 1) : 0;
126 if (len == SIZE_MAX) len = 0;
126127
127 buf_init_from_mem(&err_msg->line_buf, buf_ptr(source) + line_start_offset, len);128 buf_init_from_mem(&err_msg->line_buf, buf_ptr(source) + line_start_offset, len);
128129
src/ir.cpp+8-3
...@@ -7849,7 +7849,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node...@@ -7849,7 +7849,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node
7849 if (ir_executable.invalid)7849 if (ir_executable.invalid)
7850 return codegen->invalid_instruction;7850 return codegen->invalid_instruction;
78517851
7852 if (codegen->verbose) {7852 if (codegen->verbose_ir) {
7853 fprintf(stderr, "\nSource: ");7853 fprintf(stderr, "\nSource: ");
7854 ast_render(codegen, stderr, node, 4);7854 ast_render(codegen, stderr, node, 4);
7855 fprintf(stderr, "\n{ // (IR)\n");7855 fprintf(stderr, "\n{ // (IR)\n");
...@@ -7870,7 +7870,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node...@@ -7870,7 +7870,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node
7870 if (type_is_invalid(result_type))7870 if (type_is_invalid(result_type))
7871 return codegen->invalid_instruction;7871 return codegen->invalid_instruction;
78727872
7873 if (codegen->verbose) {7873 if (codegen->verbose_ir) {
7874 fprintf(stderr, "{ // (analyzed)\n");7874 fprintf(stderr, "{ // (analyzed)\n");
7875 ir_print(codegen, stderr, &analyzed_executable, 4);7875 ir_print(codegen, stderr, &analyzed_executable, 4);
7876 fprintf(stderr, "}\n");7876 fprintf(stderr, "}\n");
...@@ -13514,7 +13514,7 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc...@@ -13514,7 +13514,7 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc
13514 return ira->codegen->builtin_types.entry_invalid;13514 return ira->codegen->builtin_types.entry_invalid;
13515 }13515 }
1351613516
13517 if (ira->codegen->verbose) {13517 if (ira->codegen->verbose_cimport) {
13518 fprintf(stderr, "\nC imports:\n");13518 fprintf(stderr, "\nC imports:\n");
13519 fprintf(stderr, "-----------\n");13519 fprintf(stderr, "-----------\n");
13520 ast_render(ira->codegen, stderr, child_import->root, 4);13520 ast_render(ira->codegen, stderr, child_import->root, 4);
...@@ -15312,6 +15312,11 @@ static TypeTableEntry *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, Ir...@@ -15312,6 +15312,11 @@ static TypeTableEntry *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, Ir
15312 if (!ir_resolve_align(ira, align_bytes_inst, &align_bytes))15312 if (!ir_resolve_align(ira, align_bytes_inst, &align_bytes))
15313 return ira->codegen->builtin_types.entry_invalid;15313 return ira->codegen->builtin_types.entry_invalid;
1531415314
15315 if (align_bytes > 256) {
15316 ir_add_error(ira, &instruction->base, buf_sprintf("attempt to @setAlignStack(%" PRIu32 "); maximum is 256", align_bytes));
15317 return ira->codegen->builtin_types.entry_invalid;
15318 }
15319
15315 FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);15320 FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
15316 if (fn_entry == nullptr) {15321 if (fn_entry == nullptr) {
15317 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack outside function"));15322 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack outside function"));
src/link.cpp+8-14
...@@ -37,7 +37,12 @@ static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path)...@@ -37,7 +37,12 @@ static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path)
37 parent_gen->zig_lib_dir);37 parent_gen->zig_lib_dir);
3838
39 child_gen->want_h_file = false;39 child_gen->want_h_file = false;
40 child_gen->verbose_tokenize = parent_gen->verbose_tokenize;
41 child_gen->verbose_ast = parent_gen->verbose_ast;
40 child_gen->verbose_link = parent_gen->verbose_link;42 child_gen->verbose_link = parent_gen->verbose_link;
43 child_gen->verbose_ir = parent_gen->verbose_ir;
44 child_gen->verbose_llvm_ir = parent_gen->verbose_llvm_ir;
45 child_gen->verbose_cimport = parent_gen->verbose_cimport;
4146
42 codegen_set_cache_dir(child_gen, parent_gen->cache_dir);47 codegen_set_cache_dir(child_gen, parent_gen->cache_dir);
4348
...@@ -46,7 +51,6 @@ static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path)...@@ -46,7 +51,6 @@ static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path)
4651
47 codegen_set_out_name(child_gen, buf_create_from_str(oname));52 codegen_set_out_name(child_gen, buf_create_from_str(oname));
4853
49 codegen_set_verbose(child_gen, parent_gen->verbose);
50 codegen_set_errmsg_color(child_gen, parent_gen->err_color);54 codegen_set_errmsg_color(child_gen, parent_gen->err_color);
5155
52 codegen_set_mmacosx_version_min(child_gen, parent_gen->mmacosx_version_min);56 codegen_set_mmacosx_version_min(child_gen, parent_gen->mmacosx_version_min);
...@@ -858,15 +862,12 @@ void codegen_link(CodeGen *g, const char *out_file) {...@@ -858,15 +862,12 @@ void codegen_link(CodeGen *g, const char *out_file) {
858 buf_resize(&lj.out_file, 0);862 buf_resize(&lj.out_file, 0);
859 }863 }
860864
861 if (g->verbose || g->verbose_ir) {865 if (g->verbose_llvm_ir) {
862 fprintf(stderr, "\nOptimization:\n");866 fprintf(stderr, "\nOptimization:\n");
863 fprintf(stderr, "---------------\n");867 fprintf(stderr, "---------------\n");
868 fflush(stderr);
864 LLVMDumpModule(g->module);869 LLVMDumpModule(g->module);
865 }870 }
866 if (g->verbose || g->verbose_link) {
867 fprintf(stderr, "\nLink:\n");
868 fprintf(stderr, "-------\n");
869 }
870871
871 bool override_out_file = (buf_len(&lj.out_file) != 0);872 bool override_out_file = (buf_len(&lj.out_file) != 0);
872 if (!override_out_file) {873 if (!override_out_file) {
...@@ -887,9 +888,6 @@ void codegen_link(CodeGen *g, const char *out_file) {...@@ -887,9 +888,6 @@ void codegen_link(CodeGen *g, const char *out_file) {
887 zig_panic("unable to rename object file into final output: %s", err_str(err));888 zig_panic("unable to rename object file into final output: %s", err_str(err));
888 }889 }
889 }890 }
890 if (g->verbose || g->verbose_link) {
891 fprintf(stderr, "OK\n");
892 }
893 return;891 return;
894 }892 }
895893
...@@ -907,7 +905,7 @@ void codegen_link(CodeGen *g, const char *out_file) {...@@ -907,7 +905,7 @@ void codegen_link(CodeGen *g, const char *out_file) {
907 construct_linker_job(&lj);905 construct_linker_job(&lj);
908906
909907
910 if (g->verbose || g->verbose_link) {908 if (g->verbose_link) {
911 for (size_t i = 0; i < lj.args.length; i += 1) {909 for (size_t i = 0; i < lj.args.length; i += 1) {
912 const char *space = (i != 0) ? " " : "";910 const char *space = (i != 0) ? " " : "";
913 fprintf(stderr, "%s%s", space, lj.args.at(i));911 fprintf(stderr, "%s%s", space, lj.args.at(i));
...@@ -924,8 +922,4 @@ void codegen_link(CodeGen *g, const char *out_file) {...@@ -924,8 +922,4 @@ void codegen_link(CodeGen *g, const char *out_file) {
924 }922 }
925923
926 codegen_add_time_event(g, "Done");924 codegen_add_time_event(g, "Done");
927
928 if (g->verbose || g->verbose_link) {
929 fprintf(stderr, "OK\n");
930 }
931}925}
src/main.cpp+85-57
...@@ -20,66 +20,69 @@ static int usage(const char *arg0) {...@@ -20,66 +20,69 @@ static int usage(const char *arg0) {
20 fprintf(stderr, "Usage: %s [command] [options]\n"20 fprintf(stderr, "Usage: %s [command] [options]\n"
21 "Commands:\n"21 "Commands:\n"
22 " build build project from build.zig\n"22 " build build project from build.zig\n"
23 " build-exe [source] create executable from source or object files\n"23 " build-exe $source create executable from source or object files\n"
24 " build-lib [source] create library from source or object files\n"24 " build-lib $source create library from source or object files\n"
25 " build-obj [source] create object from source or assembly\n"25 " build-obj $source create object from source or assembly\n"
26 " parsec [source] convert c code to zig code\n"26 " parsec $source convert c code to zig code\n"
27 " targets list available compilation targets\n"27 " targets list available compilation targets\n"
28 " test [source] create and run a test build\n"28 " test $source create and run a test build\n"
29 " version print version number and exit\n"29 " version print version number and exit\n"
30 " zen print zen of zig and exit\n"30 " zen print zen of zig and exit\n"
31 "Compile Options:\n"31 "Compile Options:\n"
32 " --assembly [source] add assembly file to build\n"32 " --assembly $source add assembly file to build\n"
33 " --cache-dir [path] override the cache directory\n"33 " --cache-dir $path override the cache directory\n"
34 " --color [auto|off|on] enable or disable colored error messages\n"34 " --color $auto|off|on enable or disable colored error messages\n"
35 " --enable-timing-info print timing diagnostics\n"35 " --enable-timing-info print timing diagnostics\n"
36 " --libc-include-dir [path] directory where libc stdlib.h resides\n"36 " --libc-include-dir $path directory where libc stdlib.h resides\n"
37 " --name [name] override output name\n"37 " --name $name override output name\n"
38 " --output [file] override destination path\n"38 " --output $file override destination path\n"
39 " --output-h [file] override generated header file path\n"39 " --output-h $file override generated header file path\n"
40 " --pkg-begin [name] [path] make package available to import and push current pkg\n"40 " --pkg-begin $name $path make package available to import and push current pkg\n"
41 " --pkg-end pop current pkg\n"41 " --pkg-end pop current pkg\n"
42 " --release-fast build with optimizations on and safety off\n"42 " --release-fast build with optimizations on and safety off\n"
43 " --release-safe build with optimizations on and safety on\n"43 " --release-safe build with optimizations on and safety on\n"
44 " --static output will be statically linked\n"44 " --static output will be statically linked\n"
45 " --strip exclude debug symbols\n"45 " --strip exclude debug symbols\n"
46 " --target-arch [name] specify target architecture\n"46 " --target-arch $name specify target architecture\n"
47 " --target-environ [name] specify target environment\n"47 " --target-environ $name specify target environment\n"
48 " --target-os [name] specify target operating system\n"48 " --target-os $name specify target operating system\n"
49 " --verbose turn on compiler debug output\n"49 " --verbose-tokenize turn on compiler debug output for tokenization\n"
50 " --verbose-link turn on compiler debug output for linking only\n"50 " --verbose-ast turn on compiler debug output for parsing into an AST\n"
51 " --verbose-ir turn on compiler debug output for IR only\n"51 " --verbose-link turn on compiler debug output for linking\n"
52 " --zig-install-prefix [path] override directory where zig thinks it is installed\n"52 " --verbose-ir turn on compiler debug output for Zig IR\n"
53 " -dirafter [dir] same as -isystem but do it last\n"53 " --verbose-llvm-ir turn on compiler debug output for LLVM IR\n"
54 " -isystem [dir] add additional search path for other .h files\n"54 " --verbose-cimport turn on compiler debug output for C imports\n"
55 " -mllvm [arg] additional arguments to forward to LLVM's option processing\n"55 " --zig-install-prefix $path override directory where zig thinks it is installed\n"
56 " -dirafter $dir same as -isystem but do it last\n"
57 " -isystem $dir add additional search path for other .h files\n"
58 " -mllvm $arg additional arguments to forward to LLVM's option processing\n"
56 "Link Options:\n"59 "Link Options:\n"
57 " --ar-path [path] set the path to ar\n"60 " --ar-path $path set the path to ar\n"
58 " --dynamic-linker [path] set the path to ld.so\n"61 " --dynamic-linker $path set the path to ld.so\n"
59 " --each-lib-rpath add rpath for each used dynamic library\n"62 " --each-lib-rpath add rpath for each used dynamic library\n"
60 " --libc-lib-dir [path] directory where libc crt1.o resides\n"63 " --libc-lib-dir $path directory where libc crt1.o resides\n"
61 " --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n"64 " --libc-static-lib-dir $path directory where libc crtbegin.o resides\n"
62 " --msvc-lib-dir [path] (windows) directory where vcruntime.lib resides\n"65 " --msvc-lib-dir $path (windows) directory where vcruntime.lib resides\n"
63 " --kernel32-lib-dir [path] (windows) directory where kernel32.lib resides\n"66 " --kernel32-lib-dir $path (windows) directory where kernel32.lib resides\n"
64 " --library [lib] link against lib\n"67 " --library $lib link against lib\n"
65 " --library-path [dir] add a directory to the library search path\n"68 " --library-path $dir add a directory to the library search path\n"
66 " --linker-script [path] use a custom linker script\n"69 " --linker-script $path use a custom linker script\n"
67 " --object [obj] add object file to build\n"70 " --object $obj add object file to build\n"
68 " -L[dir] alias for --library-path\n"71 " -L$dir alias for --library-path\n"
69 " -rdynamic add all symbols to the dynamic symbol table\n"72 " -rdynamic add all symbols to the dynamic symbol table\n"
70 " -rpath [path] add directory to the runtime library search path\n"73 " -rpath $path add directory to the runtime library search path\n"
71 " -mconsole (windows) --subsystem console to the linker\n"74 " -mconsole (windows) --subsystem console to the linker\n"
72 " -mwindows (windows) --subsystem windows to the linker\n"75 " -mwindows (windows) --subsystem windows to the linker\n"
73 " -framework [name] (darwin) link against framework\n"76 " -framework $name (darwin) link against framework\n"
74 " -mios-version-min [ver] (darwin) set iOS deployment target\n"77 " -mios-version-min $ver (darwin) set iOS deployment target\n"
75 " -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target\n"78 " -mmacosx-version-min $ver (darwin) set Mac OS X deployment target\n"
76 " --ver-major [ver] dynamic library semver major version\n"79 " --ver-major $ver dynamic library semver major version\n"
77 " --ver-minor [ver] dynamic library semver minor version\n"80 " --ver-minor $ver dynamic library semver minor version\n"
78 " --ver-patch [ver] dynamic library semver patch version\n"81 " --ver-patch $ver dynamic library semver patch version\n"
79 "Test Options:\n"82 "Test Options:\n"
80 " --test-filter [text] skip tests that do not match filter\n"83 " --test-filter $text skip tests that do not match filter\n"
81 " --test-name-prefix [text] add prefix to all tests\n"84 " --test-name-prefix $text add prefix to all tests\n"
82 " --test-cmd [arg] specify test execution command one arg at a time\n"85 " --test-cmd $arg specify test execution command one arg at a time\n"
83 " --test-cmd-bin appends test binary path to test cmd args\n"86 " --test-cmd-bin appends test binary path to test cmd args\n"
84 , arg0);87 , arg0);
85 return EXIT_FAILURE;88 return EXIT_FAILURE;
...@@ -273,9 +276,12 @@ int main(int argc, char **argv) {...@@ -273,9 +276,12 @@ int main(int argc, char **argv) {
273 bool is_static = false;276 bool is_static = false;
274 OutType out_type = OutTypeUnknown;277 OutType out_type = OutTypeUnknown;
275 const char *out_name = nullptr;278 const char *out_name = nullptr;
276 bool verbose = false;279 bool verbose_tokenize = false;
280 bool verbose_ast = false;
277 bool verbose_link = false;281 bool verbose_link = false;
278 bool verbose_ir = false;282 bool verbose_ir = false;
283 bool verbose_llvm_ir = false;
284 bool verbose_cimport = false;
279 ErrColor color = ErrColorAuto;285 ErrColor color = ErrColorAuto;
280 const char *libc_lib_dir = nullptr;286 const char *libc_lib_dir = nullptr;
281 const char *libc_static_lib_dir = nullptr;287 const char *libc_static_lib_dir = nullptr;
...@@ -326,9 +332,7 @@ int main(int argc, char **argv) {...@@ -326,9 +332,7 @@ int main(int argc, char **argv) {
326 args.append(NULL); // placeholder332 args.append(NULL); // placeholder
327 args.append(NULL); // placeholder333 args.append(NULL); // placeholder
328 for (int i = 2; i < argc; i += 1) {334 for (int i = 2; i < argc; i += 1) {
329 if (strcmp(argv[i], "--debug-build-verbose") == 0) {335 if (strcmp(argv[i], "--help") == 0) {
330 verbose = true;
331 } else if (strcmp(argv[i], "--help") == 0) {
332 asked_for_help = true;336 asked_for_help = true;
333 args.append(argv[i]);337 args.append(argv[i]);
334 } else if (i + 1 < argc && strcmp(argv[i], "--build-file") == 0) {338 } else if (i + 1 < argc && strcmp(argv[i], "--build-file") == 0) {
...@@ -361,7 +365,6 @@ int main(int argc, char **argv) {...@@ -361,7 +365,6 @@ int main(int argc, char **argv) {
361365
362 CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, zig_lib_dir_buf);366 CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, zig_lib_dir_buf);
363 codegen_set_out_name(g, buf_create_from_str("build"));367 codegen_set_out_name(g, buf_create_from_str("build"));
364 codegen_set_verbose(g, verbose);
365368
366 Buf build_file_abs = BUF_INIT;369 Buf build_file_abs = BUF_INIT;
367 os_path_resolve(buf_create_from_str("."), buf_create_from_str(build_file), &build_file_abs);370 os_path_resolve(buf_create_from_str("."), buf_create_from_str(build_file), &build_file_abs);
...@@ -396,14 +399,30 @@ int main(int argc, char **argv) {...@@ -396,14 +399,30 @@ int main(int argc, char **argv) {
396 "\n"399 "\n"
397 "General Options:\n"400 "General Options:\n"
398 " --help Print this help and exit\n"401 " --help Print this help and exit\n"
399 " --build-file [file] Override path to build.zig\n"402 " --build-file $file Override path to build.zig\n"
400 " --cache-dir [path] Override path to cache directory\n"403 " --cache-dir $path Override path to cache directory\n"
401 " --verbose Print commands before executing them\n"404 " --verbose Print commands before executing them\n"
402 " --debug-build-verbose Print verbose debugging information for the build system itself\n"405 " --verbose-tokenize Enable compiler debug output for tokenization\n"
403 " --prefix [prefix] Override default install prefix\n"406 " --verbose-ast Enable compiler debug output for parsing into an AST\n"
407 " --verbose-link Enable compiler debug output for linking\n"
408 " --verbose-ir Enable compiler debug output for Zig IR\n"
409 " --verbose-llvm-ir Enable compiler debug output for LLVM IR\n"
410 " --verbose-cimport Enable compiler debug output for C imports\n"
411 " --prefix $path Override default install prefix\n"
404 "\n"412 "\n"
405 "More options become available when the build file is found.\n"413 "Project-specific options become available when the build file is found.\n"
406 "Run this command with no options to generate a build.zig template.\n"414 "Run this command with no options to generate a build.zig template.\n"
415 "\n"
416 "Advanced Options:\n"
417 " --build-file $file Override path to build.zig\n"
418 " --cache-dir $path Override path to cache directory\n"
419 " --verbose-tokenize Enable compiler debug output for tokenization\n"
420 " --verbose-ast Enable compiler debug output for parsing into an AST\n"
421 " --verbose-link Enable compiler debug output for linking\n"
422 " --verbose-ir Enable compiler debug output for Zig IR\n"
423 " --verbose-llvm-ir Enable compiler debug output for LLVM IR\n"
424 " --verbose-cimport Enable compiler debug output for C imports\n"
425 "\n"
407 , zig_exe_path);426 , zig_exe_path);
408 return 0;427 return 0;
409 }428 }
...@@ -450,12 +469,18 @@ int main(int argc, char **argv) {...@@ -450,12 +469,18 @@ int main(int argc, char **argv) {
450 strip = true;469 strip = true;
451 } else if (strcmp(arg, "--static") == 0) {470 } else if (strcmp(arg, "--static") == 0) {
452 is_static = true;471 is_static = true;
453 } else if (strcmp(arg, "--verbose") == 0) {472 } else if (strcmp(arg, "--verbose-tokenize") == 0) {
454 verbose = true;473 verbose_tokenize = true;
474 } else if (strcmp(arg, "--verbose-ast") == 0) {
475 verbose_ast = true;
455 } else if (strcmp(arg, "--verbose-link") == 0) {476 } else if (strcmp(arg, "--verbose-link") == 0) {
456 verbose_link = true;477 verbose_link = true;
457 } else if (strcmp(arg, "--verbose-ir") == 0) {478 } else if (strcmp(arg, "--verbose-ir") == 0) {
458 verbose_ir = true;479 verbose_ir = true;
480 } else if (strcmp(arg, "--verbose-llvm-ir") == 0) {
481 verbose_llvm_ir = true;
482 } else if (strcmp(arg, "--verbose-cimport") == 0) {
483 verbose_cimport = true;
459 } else if (strcmp(arg, "-mwindows") == 0) {484 } else if (strcmp(arg, "-mwindows") == 0) {
460 mwindows = true;485 mwindows = true;
461 } else if (strcmp(arg, "-mconsole") == 0) {486 } else if (strcmp(arg, "-mconsole") == 0) {
...@@ -738,9 +763,12 @@ int main(int argc, char **argv) {...@@ -738,9 +763,12 @@ int main(int argc, char **argv) {
738 codegen_set_kernel32_lib_dir(g, buf_create_from_str(kernel32_lib_dir));763 codegen_set_kernel32_lib_dir(g, buf_create_from_str(kernel32_lib_dir));
739 if (dynamic_linker)764 if (dynamic_linker)
740 codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker));765 codegen_set_dynamic_linker(g, buf_create_from_str(dynamic_linker));
741 codegen_set_verbose(g, verbose);766 g->verbose_tokenize = verbose_tokenize;
767 g->verbose_ast = verbose_ast;
742 g->verbose_link = verbose_link;768 g->verbose_link = verbose_link;
743 g->verbose_ir = verbose_ir;769 g->verbose_ir = verbose_ir;
770 g->verbose_llvm_ir = verbose_llvm_ir;
771 g->verbose_cimport = verbose_cimport;
744 codegen_set_errmsg_color(g, color);772 codegen_set_errmsg_color(g, color);
745773
746 for (size_t i = 0; i < lib_dirs.length; i += 1) {774 for (size_t i = 0; i < lib_dirs.length; i += 1) {
src/parsec.cpp+1-1
...@@ -3167,7 +3167,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch...@@ -3167,7 +3167,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
3167{3167{
3168 Context context = {0};3168 Context context = {0};
3169 Context *c = &context;3169 Context *c = &context;
3170 c->warnings_on = codegen->verbose;3170 c->warnings_on = codegen->verbose_cimport;
3171 c->import = import;3171 c->import = import;
3172 c->errors = errors;3172 c->errors = errors;
3173 if (buf_ends_with_str(buf_create_from_str(target_file), ".h")) {3173 if (buf_ends_with_str(buf_create_from_str(target_file), ".h")) {
src/tokenizer.cpp+47-9
...@@ -416,6 +416,44 @@ static void handle_string_escape(Tokenize *t, uint8_t c) {...@@ -416,6 +416,44 @@ static void handle_string_escape(Tokenize *t, uint8_t c) {
416 }416 }
417}417}
418418
419static const char* get_escape_shorthand(uint8_t c) {
420 switch (c) {
421 case '\0':
422 return "\\0";
423 case '\a':
424 return "\\a";
425 case '\b':
426 return "\\b";
427 case '\t':
428 return "\\t";
429 case '\n':
430 return "\\n";
431 case '\v':
432 return "\\v";
433 case '\f':
434 return "\\f";
435 case '\r':
436 return "\\r";
437 default:
438 return nullptr;
439 }
440}
441
442static void invalid_char_error(Tokenize *t, uint8_t c) {
443 if (c == '\r') {
444 tokenize_error(t, "invalid carriage return, only '\\n' line endings are supported");
445 } else if (isprint(c)) {
446 tokenize_error(t, "invalid character: '%c'", c);
447 } else {
448 const char *sh = get_escape_shorthand(c);
449 if (sh) {
450 tokenize_error(t, "invalid character: '%s'", sh);
451 } else {
452 tokenize_error(t, "invalid character: '\\x%x'", c);
453 }
454 }
455}
456
419void tokenize(Buf *buf, Tokenization *out) {457void tokenize(Buf *buf, Tokenization *out) {
420 Tokenize t = {0};458 Tokenize t = {0};
421 t.out = out;459 t.out = out;
...@@ -580,7 +618,7 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -580,7 +618,7 @@ void tokenize(Buf *buf, Tokenization *out) {
580 t.state = TokenizeStateSawQuestionMark;618 t.state = TokenizeStateSawQuestionMark;
581 break;619 break;
582 default:620 default:
583 tokenize_error(&t, "invalid character: '%c'", c);621 invalid_char_error(&t, c);
584 }622 }
585 break;623 break;
586 case TokenizeStateSawQuestionMark:624 case TokenizeStateSawQuestionMark:
...@@ -890,7 +928,7 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -890,7 +928,7 @@ void tokenize(Buf *buf, Tokenization *out) {
890 t.state = TokenizeStateLineString;928 t.state = TokenizeStateLineString;
891 break;929 break;
892 default:930 default:
893 tokenize_error(&t, "invalid character: '%c'", c);931 invalid_char_error(&t, c);
894 break;932 break;
895 }933 }
896 break;934 break;
...@@ -919,7 +957,7 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -919,7 +957,7 @@ void tokenize(Buf *buf, Tokenization *out) {
919 break;957 break;
920 case '\\':958 case '\\':
921 if (t.cur_tok->data.str_lit.is_c_str) {959 if (t.cur_tok->data.str_lit.is_c_str) {
922 tokenize_error(&t, "invalid character: '%c'", c);960 invalid_char_error(&t, c);
923 }961 }
924 t.state = TokenizeStateLineStringContinue;962 t.state = TokenizeStateLineStringContinue;
925 break;963 break;
...@@ -949,7 +987,7 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -949,7 +987,7 @@ void tokenize(Buf *buf, Tokenization *out) {
949 buf_append_char(&t.cur_tok->data.str_lit.str, '\n');987 buf_append_char(&t.cur_tok->data.str_lit.str, '\n');
950 break;988 break;
951 default:989 default:
952 tokenize_error(&t, "invalid character: '%c'", c);990 invalid_char_error(&t, c);
953 break;991 break;
954 }992 }
955 break;993 break;
...@@ -1073,7 +1111,7 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -1073,7 +1111,7 @@ void tokenize(Buf *buf, Tokenization *out) {
1073 handle_string_escape(&t, '\"');1111 handle_string_escape(&t, '\"');
1074 break;1112 break;
1075 default:1113 default:
1076 tokenize_error(&t, "invalid character: '%c'", c);1114 invalid_char_error(&t, c);
1077 }1115 }
1078 break;1116 break;
1079 case TokenizeStateCharCode:1117 case TokenizeStateCharCode:
...@@ -1147,7 +1185,7 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -1147,7 +1185,7 @@ void tokenize(Buf *buf, Tokenization *out) {
1147 t.state = TokenizeStateStart;1185 t.state = TokenizeStateStart;
1148 break;1186 break;
1149 default:1187 default:
1150 tokenize_error(&t, "invalid character: '%c'", c);1188 invalid_char_error(&t, c);
1151 }1189 }
1152 break;1190 break;
1153 case TokenizeStateZero:1191 case TokenizeStateZero:
...@@ -1189,7 +1227,7 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -1189,7 +1227,7 @@ void tokenize(Buf *buf, Tokenization *out) {
1189 uint32_t digit_value = get_digit_value(c);1227 uint32_t digit_value = get_digit_value(c);
1190 if (digit_value >= t.radix) {1228 if (digit_value >= t.radix) {
1191 if (is_symbol_char(c)) {1229 if (is_symbol_char(c)) {
1192 tokenize_error(&t, "invalid character: '%c'", c);1230 invalid_char_error(&t, c);
1193 }1231 }
1194 // not my char1232 // not my char
1195 t.pos -= 1;1233 t.pos -= 1;
...@@ -1233,7 +1271,7 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -1233,7 +1271,7 @@ void tokenize(Buf *buf, Tokenization *out) {
1233 uint32_t digit_value = get_digit_value(c);1271 uint32_t digit_value = get_digit_value(c);
1234 if (digit_value >= t.radix) {1272 if (digit_value >= t.radix) {
1235 if (is_symbol_char(c)) {1273 if (is_symbol_char(c)) {
1236 tokenize_error(&t, "invalid character: '%c'", c);1274 invalid_char_error(&t, c);
1237 }1275 }
1238 // not my char1276 // not my char
1239 t.pos -= 1;1277 t.pos -= 1;
...@@ -1282,7 +1320,7 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -1282,7 +1320,7 @@ void tokenize(Buf *buf, Tokenization *out) {
1282 uint32_t digit_value = get_digit_value(c);1320 uint32_t digit_value = get_digit_value(c);
1283 if (digit_value >= t.radix) {1321 if (digit_value >= t.radix) {
1284 if (is_symbol_char(c)) {1322 if (is_symbol_char(c)) {
1285 tokenize_error(&t, "invalid character: '%c'", c);1323 invalid_char_error(&t, c);
1286 }1324 }
1287 // not my char1325 // not my char
1288 t.pos -= 1;1326 t.pos -= 1;
src/zig_llvm.cpp+2-9
...@@ -5,15 +5,6 @@...@@ -5,15 +5,6 @@
5 * See http://opensource.org/licenses/MIT5 * See http://opensource.org/licenses/MIT
6 */6 */
77
8// This must go before all includes.
9#include "config.h"
10#if defined(ZIG_LLVM_OLD_CXX_ABI)
11#define _GLIBCXX_USE_CXX11_ABI 0
12#endif
13
14
15#include "zig_llvm.hpp"
16
178
18/*9/*
19 * The point of this file is to contain all the LLVM C++ API interaction so that:10 * The point of this file is to contain all the LLVM C++ API interaction so that:
...@@ -22,6 +13,8 @@...@@ -22,6 +13,8 @@
22 * 3. Prevent C++ from infecting the rest of the project.13 * 3. Prevent C++ from infecting the rest of the project.
23 */14 */
2415
16#include "zig_llvm.hpp"
17
25#include <llvm/Analysis/TargetLibraryInfo.h>18#include <llvm/Analysis/TargetLibraryInfo.h>
26#include <llvm/Analysis/TargetTransformInfo.h>19#include <llvm/Analysis/TargetTransformInfo.h>
27#include <llvm/IR/DIBuilder.h>20#include <llvm/IR/DIBuilder.h>
std/build.zig+32-7
...@@ -33,6 +33,12 @@ pub const Builder = struct {...@@ -33,6 +33,12 @@ pub const Builder = struct {
33 available_options_map: AvailableOptionsMap,33 available_options_map: AvailableOptionsMap,
34 available_options_list: ArrayList(AvailableOption),34 available_options_list: ArrayList(AvailableOption),
35 verbose: bool,35 verbose: bool,
36 verbose_tokenize: bool,
37 verbose_ast: bool,
38 verbose_link: bool,
39 verbose_ir: bool,
40 verbose_llvm_ir: bool,
41 verbose_cimport: bool,
36 invalid_user_input: bool,42 invalid_user_input: bool,
37 zig_exe: []const u8,43 zig_exe: []const u8,
38 default_step: &Step,44 default_step: &Step,
...@@ -88,6 +94,12 @@ pub const Builder = struct {...@@ -88,6 +94,12 @@ pub const Builder = struct {
88 .build_root = build_root,94 .build_root = build_root,
89 .cache_root = %%os.path.relative(allocator, build_root, cache_root),95 .cache_root = %%os.path.relative(allocator, build_root, cache_root),
90 .verbose = false,96 .verbose = false,
97 .verbose_tokenize = false,
98 .verbose_ast = false,
99 .verbose_link = false,
100 .verbose_ir = false,
101 .verbose_llvm_ir = false,
102 .verbose_cimport = false,
91 .invalid_user_input = false,103 .invalid_user_input = false,
92 .allocator = allocator,104 .allocator = allocator,
93 .lib_paths = ArrayList([]const u8).init(allocator),105 .lib_paths = ArrayList([]const u8).init(allocator),
...@@ -536,15 +548,19 @@ pub const Builder = struct {...@@ -536,15 +548,19 @@ pub const Builder = struct {
536 return self.spawnChildEnvMap(null, &self.env_map, argv);548 return self.spawnChildEnvMap(null, &self.env_map, argv);
537 }549 }
538550
551 fn printCmd(cwd: ?[]const u8, argv: []const []const u8) {
552 if (cwd) |yes_cwd| %%io.stderr.print("cd {} && ", yes_cwd);
553 for (argv) |arg| {
554 %%io.stderr.print("{} ", arg);
555 }
556 %%io.stderr.printf("\n");
557 }
558
539 fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,559 fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
540 argv: []const []const u8) -> %void560 argv: []const []const u8) -> %void
541 {561 {
542 if (self.verbose) {562 if (self.verbose) {
543 if (cwd) |yes_cwd| %%io.stderr.print("cd {}; ", yes_cwd);563 printCmd(cwd, argv);
544 for (argv) |arg| {
545 %%io.stderr.print("{} ", arg);
546 }
547 %%io.stderr.printf("\n");
548 }564 }
549565
550 const child = %%os.ChildProcess.init(argv, self.allocator);566 const child = %%os.ChildProcess.init(argv, self.allocator);
...@@ -561,12 +577,15 @@ pub const Builder = struct {...@@ -561,12 +577,15 @@ pub const Builder = struct {
561 switch (term) {577 switch (term) {
562 Term.Exited => |code| {578 Term.Exited => |code| {
563 if (code != 0) {579 if (code != 0) {
564 %%io.stderr.printf("Process {} exited with error code {}\n", argv[0], code);580 %%io.stderr.printf("The following command exited with error code {}:\n", code);
581 printCmd(cwd, argv);
565 return error.UncleanExit;582 return error.UncleanExit;
566 }583 }
567 },584 },
568 else => {585 else => {
569 %%io.stderr.printf("Process {} terminated unexpectedly\n", argv[0]);586 %%io.stderr.printf("The following command terminated unexpectedly:\n");
587 printCmd(cwd, argv);
588
570 return error.UncleanExit;589 return error.UncleanExit;
571 },590 },
572 };591 };
...@@ -1117,6 +1136,12 @@ pub const LibExeObjStep = struct {...@@ -1117,6 +1136,12 @@ pub const LibExeObjStep = struct {
1117 if (self.verbose) {1136 if (self.verbose) {
1118 %%zig_args.append("--verbose");1137 %%zig_args.append("--verbose");
1119 }1138 }
1139 if (builder.verbose_tokenize) %%zig_args.append("--verbose-tokenize");
1140 if (builder.verbose_ast) %%zig_args.append("--verbose-ast");
1141 if (builder.verbose_cimport) %%zig_args.append("--verbose-cimport");
1142 if (builder.verbose_ir) %%zig_args.append("--verbose-ir");
1143 if (builder.verbose_llvm_ir) %%zig_args.append("--verbose-llvm-ir");
1144 if (builder.verbose_link) %%zig_args.append("--verbose-link");
11201145
1121 if (self.strip) {1146 if (self.strip) {
1122 %%zig_args.append("--strip");1147 %%zig_args.append("--strip");
std/fmt/errol/index.zig+9-13
...@@ -32,13 +32,13 @@ pub fn errol3(value: f64, buffer: []u8) -> FloatDecimal {...@@ -32,13 +32,13 @@ pub fn errol3(value: f64, buffer: []u8) -> FloatDecimal {
32fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {32fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {
33 // check if in integer or fixed range33 // check if in integer or fixed range
3434
35 if (val >= 9.007199254740992e15 and val < 3.40282366920938e+38) {35 if (val > 9.007199254740992e15 and val < 3.40282366920938e+38) {
36 return errolInt(val, buffer);36 return errolInt(val, buffer);
37 } else if (val >= 16.0 and val < 9.007199254740992e15) {37 } else if (val >= 16.0 and val < 9.007199254740992e15) {
38 return errolFixed(val, buffer);38 return errolFixed(val, buffer);
39 }39 }
4040
41 41
42 // normalize the midpoint42 // normalize the midpoint
4343
44 const e = math.frexp(val).exponent;44 const e = math.frexp(val).exponent;
...@@ -138,7 +138,7 @@ fn tableLowerBound(k: u64) -> usize {...@@ -138,7 +138,7 @@ fn tableLowerBound(k: u64) -> usize {
138138
139 while (j < enum3.len) {139 while (j < enum3.len) {
140 if (enum3[j] < k) {140 if (enum3[j] < k) {
141 j = 2 * k + 2;141 j = 2 * j + 2;
142 } else {142 } else {
143 i = j;143 i = j;
144 j = 2 * j + 1;144 j = 2 * j + 1;
...@@ -217,7 +217,7 @@ fn hpMul10(hp: &HP) {...@@ -217,7 +217,7 @@ fn hpMul10(hp: &HP) {
217217
218 hp.val *= 10.0;218 hp.val *= 10.0;
219 hp.off *= 10.0;219 hp.off *= 10.0;
220 220
221 var off = hp.val;221 var off = hp.val;
222 off -= val * 8.0;222 off -= val * 8.0;
223 off -= val * 2.0;223 off -= val * 2.0;
...@@ -235,13 +235,13 @@ fn hpMul10(hp: &HP) {...@@ -235,13 +235,13 @@ fn hpMul10(hp: &HP) {
235fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {235fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {
236 const pow19 = u128(1e19);236 const pow19 = u128(1e19);
237237
238 assert((val >= 9.007199254740992e15) and val < (3.40282366920938e38));238 assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));
239239
240 var mid = u128(val);240 var mid = u128(val);
241 var low: u128 = mid - fpeint((fpnext(val) - val) / 2.0);241 var low: u128 = mid - fpeint((fpnext(val) - val) / 2.0);
242 var high: u128 = mid + fpeint((val - fpprev(val)) / 2.0);242 var high: u128 = mid + fpeint((val - fpprev(val)) / 2.0);
243243
244 if (@bitCast(u64, val) & 0x1 != 0) { 244 if (@bitCast(u64, val) & 0x1 != 0) {
245 high -= 1;245 high -= 1;
246 } else {246 } else {
247 low -= 1;247 low -= 1;
...@@ -347,11 +347,11 @@ fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {...@@ -347,11 +347,11 @@ fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {
347}347}
348348
349fn fpnext(val: f64) -> f64 {349fn fpnext(val: f64) -> f64 {
350 return @bitCast(f64, @bitCast(u64, val) + 1);350 return @bitCast(f64, @bitCast(u64, val) +% 1);
351}351}
352352
353fn fpprev(val: f64) -> f64 {353fn fpprev(val: f64) -> f64 {
354 return @bitCast(f64, @bitCast(u64, val) - 1);354 return @bitCast(f64, @bitCast(u64, val) -% 1);
355}355}
356356
357pub const c_digits_lut = []u8 {357pub const c_digits_lut = []u8 {
...@@ -510,10 +510,6 @@ fn u64toa(value_param: u64, buffer: []u8) -> usize {...@@ -510,10 +510,6 @@ fn u64toa(value_param: u64, buffer: []u8) -> usize {
510 buf_index += 1;510 buf_index += 1;
511 buffer[buf_index] = c_digits_lut[d8];511 buffer[buf_index] = c_digits_lut[d8];
512 buf_index += 1;512 buf_index += 1;
513 buffer[buf_index] = c_digits_lut[d8];
514 buf_index += 1;
515 buffer[buf_index] = c_digits_lut[d8];
516 buf_index += 1;
517 buffer[buf_index] = c_digits_lut[d8 + 1];513 buffer[buf_index] = c_digits_lut[d8 + 1];
518 buf_index += 1;514 buf_index += 1;
519 } else {515 } else {
...@@ -613,7 +609,7 @@ fn fpeint(from: f64) -> u128 {...@@ -613,7 +609,7 @@ fn fpeint(from: f64) -> u128 {
613 const bits = @bitCast(u64, from);609 const bits = @bitCast(u64, from);
614 assert((bits & ((1 << 52) - 1)) == 0);610 assert((bits & ((1 << 52) - 1)) == 0);
615611
616 return u64(1) << u6(((bits >> 52) - 1023));612 return u128(1) << @truncate(u7, (bits >> 52) -% 1023);
617}613}
618614
619615
std/fmt/index.zig+60-11
...@@ -244,30 +244,47 @@ pub fn formatBuf(buf: []const u8, width: usize,...@@ -244,30 +244,47 @@ pub fn formatBuf(buf: []const u8, width: usize,
244}244}
245245
246pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool {246pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool {
247 var buffer: [20]u8 = undefined;247 var x = f64(value);
248 const float_decimal = errol3(f64(value), buffer[0..]);248
249 if (float_decimal.exp != 0) {249 // Errol doesn't handle these special cases.
250 if (!output(context, float_decimal.digits[0..1]))250 if (math.isNan(x)) {
251 return false;251 return output(context, "NaN");
252 } else {252 }
253 if (!output(context, "0"))253 if (math.signbit(x)) {
254 if (!output(context, "-"))
254 return false;255 return false;
256 x = -x;
255 }257 }
258 if (math.isPositiveInf(x)) {
259 return output(context, "Infinity");
260 }
261 if (x == 0.0) {
262 return output(context, "0.0");
263 }
264
265 var buffer: [32]u8 = undefined;
266 const float_decimal = errol3(x, buffer[0..]);
267 if (!output(context, float_decimal.digits[0..1]))
268 return false;
256 if (!output(context, "."))269 if (!output(context, "."))
257 return false;270 return false;
258 if (float_decimal.digits.len > 1) {271 if (float_decimal.digits.len > 1) {
259 const start = if (float_decimal.exp == 0) usize(0) else usize(1);272 const num_digits = if (@typeOf(value) == f32) {
260 if (!output(context, float_decimal.digits[start .. math.min(usize(7), float_decimal.digits.len)]))273 math.min(usize(9), float_decimal.digits.len)
274 } else {
275 float_decimal.digits.len
276 };
277 if (!output(context, float_decimal.digits[1 .. num_digits]))
261 return false;278 return false;
262 } else {279 } else {
263 if (!output(context, "0"))280 if (!output(context, "0"))
264 return false;281 return false;
265 }282 }
266283
267 if (float_decimal.exp != 1 and float_decimal.exp != 0) {284 if (float_decimal.exp != 1) {
268 if (!output(context, "e"))285 if (!output(context, "e"))
269 return false;286 return false;
270 if (!formatInt(float_decimal.exp, 10, false, 0, context, output))287 if (!formatInt(float_decimal.exp - 1, 10, false, 0, context, output))
271 return false;288 return false;
272 }289 }
273 return true;290 return true;
...@@ -514,6 +531,38 @@ test "fmt.format" {...@@ -514,6 +531,38 @@ test "fmt.format" {
514 const result = bufPrint(buf1[0..], "u3: {}\n", value);531 const result = bufPrint(buf1[0..], "u3: {}\n", value);
515 assert(mem.eql(u8, result, "u3: 5\n"));532 assert(mem.eql(u8, result, "u3: 5\n"));
516 }533 }
534
535 // TODO get these tests passing in release modes
536 // https://github.com/zig-lang/zig/issues/564
537 if (builtin.mode == builtin.Mode.Debug) {
538 {
539 var buf1: [32]u8 = undefined;
540 const value: f32 = 12.34;
541 const result = bufPrint(buf1[0..], "f32: {}\n", value);
542 assert(mem.eql(u8, result, "f32: 1.23400001e1\n"));
543 }
544 {
545 var buf1: [32]u8 = undefined;
546 const value: f64 = -12.34e10;
547 const result = bufPrint(buf1[0..], "f64: {}\n", value);
548 assert(mem.eql(u8, result, "f64: -1.234e11\n"));
549 }
550 {
551 var buf1: [32]u8 = undefined;
552 const result = bufPrint(buf1[0..], "f64: {}\n", math.nan_f64);
553 assert(mem.eql(u8, result, "f64: NaN\n"));
554 }
555 {
556 var buf1: [32]u8 = undefined;
557 const result = bufPrint(buf1[0..], "f64: {}\n", math.inf_f64);
558 assert(mem.eql(u8, result, "f64: Infinity\n"));
559 }
560 {
561 var buf1: [32]u8 = undefined;
562 const result = bufPrint(buf1[0..], "f64: {}\n", -math.inf_f64);
563 assert(mem.eql(u8, result, "f64: -Infinity\n"));
564 }
565 }
517}566}
518567
519pub fn trim(buf: []const u8) -> []const u8 {568pub fn trim(buf: []const u8) -> []const u8 {
std/special/build_runner.zig+32-7
...@@ -69,6 +69,18 @@ pub fn main() -> %void {...@@ -69,6 +69,18 @@ pub fn main() -> %void {
69 %%io.stderr.printf("Expected argument after --prefix\n\n");69 %%io.stderr.printf("Expected argument after --prefix\n\n");
70 return usage(&builder, false, &io.stderr);70 return usage(&builder, false, &io.stderr);
71 });71 });
72 } else if (mem.eql(u8, arg, "--verbose-tokenize")) {
73 builder.verbose_tokenize = true;
74 } else if (mem.eql(u8, arg, "--verbose-ast")) {
75 builder.verbose_ast = true;
76 } else if (mem.eql(u8, arg, "--verbose-link")) {
77 builder.verbose_link = true;
78 } else if (mem.eql(u8, arg, "--verbose-ir")) {
79 builder.verbose_ir = true;
80 } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {
81 builder.verbose_llvm_ir = true;
82 } else if (mem.eql(u8, arg, "--verbose-cimport")) {
83 builder.verbose_cimport = true;
72 } else {84 } else {
73 %%io.stderr.printf("Unrecognized argument: {}\n\n", arg);85 %%io.stderr.printf("Unrecognized argument: {}\n\n", arg);
74 return usage(&builder, false, &io.stderr);86 return usage(&builder, false, &io.stderr);
...@@ -116,27 +128,40 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream)...@@ -116,27 +128,40 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream)
116 \\128 \\
117 \\General Options:129 \\General Options:
118 \\ --help Print this help and exit130 \\ --help Print this help and exit
119 \\ --build-file [file] Override path to build.zig
120 \\ --cache-dir [path] Override path to cache directory
121 \\ --verbose Print commands before executing them131 \\ --verbose Print commands before executing them
122 \\ --debug-build-verbose Print verbose debugging information for the build system itself132 \\ --prefix $path Override default install prefix
123 \\ --prefix [prefix] Override default install prefix
124 \\133 \\
125 \\Project-Specific Options:134 \\Project-Specific Options:
126 \\135 \\
127 );136 );
128137
129 if (builder.available_options_list.len == 0) {138 if (builder.available_options_list.len == 0) {
130 %%out_stream.printf(" (none)\n");139 %%out_stream.print(" (none)\n");
131 } else {140 } else {
132 for (builder.available_options_list.toSliceConst()) |option| {141 for (builder.available_options_list.toSliceConst()) |option| {
133 const name = %%fmt.allocPrint(allocator,142 const name = %%fmt.allocPrint(allocator,
134 " -D{}=({})", option.name, Builder.typeIdName(option.type_id));143 " -D{}=${}", option.name, Builder.typeIdName(option.type_id));
135 defer allocator.free(name);144 defer allocator.free(name);
136 %%out_stream.printf("{s24} {}\n", name, option.description);145 %%out_stream.print("{s24} {}\n", name, option.description);
137 }146 }
138 }147 }
139148
149 %%out_stream.write(
150 \\
151 \\Advanced Options:
152 \\ --build-file $file Override path to build.zig
153 \\ --cache-dir $path Override path to zig cache directory
154 \\ --verbose-tokenize Enable compiler debug output for tokenization
155 \\ --verbose-ast Enable compiler debug output for parsing into an AST
156 \\ --verbose-link Enable compiler debug output for linking
157 \\ --verbose-ir Enable compiler debug output for Zig IR
158 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
159 \\ --verbose-cimport Enable compiler debug output for C imports
160 \\
161 );
162
163 %%out_stream.flush();
164
140 if (out_stream == &io.stderr)165 if (out_stream == &io.stderr)
141 return error.InvalidArgs;166 return error.InvalidArgs;
142}167}
std/special/compiler_rt/comparetf2.zig+1-1
...@@ -20,7 +20,7 @@ const infRep = exponentMask;...@@ -20,7 +20,7 @@ const infRep = exponentMask;
2020
21const builtin = @import("builtin");21const builtin = @import("builtin");
22const is_test = builtin.is_test;22const is_test = builtin.is_test;
23const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;23const linkage = @import("index.zig").linkage;
2424
25export fn __letf2(a: f128, b: f128) -> c_int {25export fn __letf2(a: f128, b: f128) -> c_int {
26 @setDebugSafety(this, is_test);26 @setDebugSafety(this, is_test);
std/special/compiler_rt/fixunsdfdi.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;3const linkage = @import("index.zig").linkage;
44
5export fn __fixunsdfdi(a: f64) -> u64 {5export fn __fixunsdfdi(a: f64) -> u64 {
6 @setDebugSafety(this, builtin.is_test);6 @setDebugSafety(this, builtin.is_test);
std/special/compiler_rt/fixunsdfsi.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;3const linkage = @import("index.zig").linkage;
44
5export fn __fixunsdfsi(a: f64) -> u32 {5export fn __fixunsdfsi(a: f64) -> u32 {
6 @setDebugSafety(this, builtin.is_test);6 @setDebugSafety(this, builtin.is_test);
std/special/compiler_rt/fixunsdfti.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;3const linkage = @import("index.zig").linkage;
44
5export fn __fixunsdfti(a: f64) -> u128 {5export fn __fixunsdfti(a: f64) -> u128 {
6 @setDebugSafety(this, builtin.is_test);6 @setDebugSafety(this, builtin.is_test);
std/special/compiler_rt/fixunssfdi.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;3const linkage = @import("index.zig").linkage;
44
5export fn __fixunssfdi(a: f32) -> u64 {5export fn __fixunssfdi(a: f32) -> u64 {
6 @setDebugSafety(this, builtin.is_test);6 @setDebugSafety(this, builtin.is_test);
std/special/compiler_rt/fixunssfsi.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;3const linkage = @import("index.zig").linkage;
44
5export fn __fixunssfsi(a: f32) -> u32 {5export fn __fixunssfsi(a: f32) -> u32 {
6 @setDebugSafety(this, builtin.is_test);6 @setDebugSafety(this, builtin.is_test);
std/special/compiler_rt/fixunssfti.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;3const linkage = @import("index.zig").linkage;
44
5export fn __fixunssfti(a: f32) -> u128 {5export fn __fixunssfti(a: f32) -> u128 {
6 @setDebugSafety(this, builtin.is_test);6 @setDebugSafety(this, builtin.is_test);
std/special/compiler_rt/fixunstfdi.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;3const linkage = @import("index.zig").linkage;
44
5export fn __fixunstfdi(a: f128) -> u64 {5export fn __fixunstfdi(a: f128) -> u64 {
6 @setDebugSafety(this, builtin.is_test);6 @setDebugSafety(this, builtin.is_test);
std/special/compiler_rt/fixunstfsi.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;3const linkage = @import("index.zig").linkage;
44
5export fn __fixunstfsi(a: f128) -> u32 {5export fn __fixunstfsi(a: f128) -> u32 {
6 @setDebugSafety(this, builtin.is_test);6 @setDebugSafety(this, builtin.is_test);
std/special/compiler_rt/fixunstfti.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;3const linkage = @import("index.zig").linkage;
44
5export fn __fixunstfti(a: f128) -> u128 {5export fn __fixunstfti(a: f128) -> u128 {
6 @setDebugSafety(this, builtin.is_test);6 @setDebugSafety(this, builtin.is_test);
std/special/compiler_rt/index.zig+1-5
...@@ -26,7 +26,7 @@ const win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch....@@ -26,7 +26,7 @@ const win32 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.
26const win64 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.x86_64;26const win64 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.x86_64;
27const win32_nocrt = win32 and !builtin.link_libc;27const win32_nocrt = win32 and !builtin.link_libc;
28const win64_nocrt = win64 and !builtin.link_libc;28const win64_nocrt = win64 and !builtin.link_libc;
29const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;29pub const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak;
30const strong_linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;30const strong_linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong;
3131
32const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;32const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
...@@ -152,10 +152,6 @@ export nakedcc fn _chkstk() align(4) {...@@ -152,10 +152,6 @@ export nakedcc fn _chkstk() align(4) {
152 @setGlobalLinkage(_chkstk, builtin.GlobalLinkage.Internal);152 @setGlobalLinkage(_chkstk, builtin.GlobalLinkage.Internal);
153}153}
154154
155// TODO The implementation from compiler-rt causes crashes and
156// the implementation from disassembled ntdll seems to depend on
157// thread local storage. So we have given up this safety check
158// and simply have `ret`.
159export nakedcc fn __chkstk() align(4) {155export nakedcc fn __chkstk() align(4) {
160 @setDebugSafety(this, false);156 @setDebugSafety(this, false);
161157
std/special/compiler_rt/udivmoddi4.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const udivmod = @import("udivmod.zig").udivmod;1const udivmod = @import("udivmod.zig").udivmod;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;3const linkage = @import("index.zig").linkage;
44
5export fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 {5export fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 {
6 @setDebugSafety(this, builtin.is_test);6 @setDebugSafety(this, builtin.is_test);
std/special/compiler_rt/udivmodti4.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const udivmod = @import("udivmod.zig").udivmod;1const udivmod = @import("udivmod.zig").udivmod;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;3const linkage = @import("index.zig").linkage;
44
5export fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 {5export fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 {
6 @setDebugSafety(this, builtin.is_test);6 @setDebugSafety(this, builtin.is_test);
std/special/compiler_rt/udivti3.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;3const linkage = @import("index.zig").linkage;
44
5export fn __udivti3(a: u128, b: u128) -> u128 {5export fn __udivti3(a: u128, b: u128) -> u128 {
6 @setDebugSafety(this, builtin.is_test);6 @setDebugSafety(this, builtin.is_test);
std/special/compiler_rt/umodti3.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce;3const linkage = @import("index.zig").linkage;
44
5export fn __umodti3(a: u128, b: u128) -> u128 {5export fn __umodti3(a: u128, b: u128) -> u128 {
6 @setDebugSafety(this, builtin.is_test);6 @setDebugSafety(this, builtin.is_test);
test/behavior.zig+1
...@@ -40,6 +40,7 @@ comptime {...@@ -40,6 +40,7 @@ comptime {
40 _ = @import("cases/this.zig");40 _ = @import("cases/this.zig");
41 _ = @import("cases/try.zig");41 _ = @import("cases/try.zig");
42 _ = @import("cases/undefined.zig");42 _ = @import("cases/undefined.zig");
43 _ = @import("cases/union.zig");
43 _ = @import("cases/var_args.zig");44 _ = @import("cases/var_args.zig");
44 _ = @import("cases/void.zig");45 _ = @import("cases/void.zig");
45 _ = @import("cases/while.zig");46 _ = @import("cases/while.zig");
test/cases/align.zig+1-1
...@@ -188,6 +188,6 @@ test "alignstack" {...@@ -188,6 +188,6 @@ test "alignstack" {
188}188}
189189
190fn fnWithAlignedStack() -> i32 {190fn fnWithAlignedStack() -> i32 {
191 @setAlignStack(1024);191 @setAlignStack(256);
192 return 1234;192 return 1234;
193}193}
test/cases/union.zig created+33
...@@ -0,0 +1,33 @@
1const assert = @import("std").debug.assert;
2
3const Value = enum {
4 Int: u64,
5 Array: [9]u8,
6};
7
8const Agg = struct {
9 val1: Value,
10 val2: Value,
11};
12
13const v1 = Value.Int { 1234 };
14const v2 = Value.Array { []u8{3} ** 9 };
15
16const err = (%Agg)(Agg {
17 .val1 = v1,
18 .val2 = v2,
19});
20
21const array = []Value { v1, v2, v1, v2};
22
23
24test "unions embedded in aggregate types" {
25 switch (array[1]) {
26 Value.Array => |arr| assert(arr[4] == 3),
27 else => unreachable,
28 }
29 switch((%%err).val1) {
30 Value.Int => |x| assert(x == 1234),
31 else => unreachable,
32 }
33}
test/compile_errors.zig+44
...@@ -2187,6 +2187,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2187,6 +2187,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2187 ".tmp_source.zig:3:5: error: alignstack set twice",2187 ".tmp_source.zig:3:5: error: alignstack set twice",
2188 ".tmp_source.zig:2:5: note: first set here");2188 ".tmp_source.zig:2:5: note: first set here");
21892189
2190 cases.add("@setAlignStack too big",
2191 \\export fn entry() {
2192 \\ @setAlignStack(511 + 1);
2193 \\}
2194 ,
2195 ".tmp_source.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256");
2196
2190 cases.add("storing runtime value in compile time variable then using it",2197 cases.add("storing runtime value in compile time variable then using it",
2191 \\const Mode = @import("builtin").Mode;2198 \\const Mode = @import("builtin").Mode;
2192 \\2199 \\
...@@ -2231,4 +2238,41 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2231,4 +2238,41 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2231 \\}2238 \\}
2232 ,2239 ,
2233 ".tmp_source.zig:37:16: error: cannot store runtime value in compile time variable");2240 ".tmp_source.zig:37:16: error: cannot store runtime value in compile time variable");
2241
2242 cases.add("field access of opaque type",
2243 \\const MyType = @OpaqueType();
2244 \\
2245 \\export fn entry() -> bool {
2246 \\ var x: i32 = 1;
2247 \\ return bar(@ptrCast(&MyType, &x));
2248 \\}
2249 \\
2250 \\fn bar(x: &MyType) -> bool {
2251 \\ return x.blah;
2252 \\}
2253 ,
2254 ".tmp_source.zig:9:13: error: type '&MyType' does not support field access");
2255
2256 cases.add("carriage return special case",
2257 "fn test() -> bool {\r\n" ++
2258 " true\r\n" ++
2259 "}\r\n"
2260 ,
2261 ".tmp_source.zig:1:20: error: invalid carriage return, only '\\n' line endings are supported");
2262
2263 cases.add("non-printable invalid character",
2264 "\xff\xfe" ++
2265 \\fn test() -> bool {\r
2266 \\ true\r
2267 \\}
2268 ,
2269 ".tmp_source.zig:1:1: error: invalid character: '\\xff'");
2270
2271 cases.add("non-printable invalid character with escape alternative",
2272 "fn test() -> bool {\n" ++
2273 "\ttrue\n" ++
2274 "}\n"
2275 ,
2276 ".tmp_source.zig:2:1: error: invalid character: '\\t'");
2277
2234}2278}