| author | |
| committer | |
| log | 540bac09280dc9511145f44fda49d3a84b699820 |
| tree | 1443e18d6e54093366615789ae36e1e0f3fb04bd |
| parent | 4f4da3c10c56eb1d60fdb2a98a46634d4dc608fe |
| parent | 4c306af4eb79071c966b99e877970f0a4582d891 |
37 files changed, 498 insertions(+), 204 deletions(-)
c_headers/stdarg.h+4| ... | ... | @@ -26,10 +26,14 @@ |
| 26 | 26 | #ifndef __STDARG_H |
| 27 | 27 | #define __STDARG_H |
| 28 | 28 | |
| 29 | /* zig: added because macos _va_list.h was duplicately defining va_list | |
| 30 | */ | |
| 29 | 31 | #ifndef _VA_LIST |
| 32 | #ifndef _VA_LIST_T | |
| 30 | 33 | typedef __builtin_va_list va_list; |
| 31 | 34 | #define _VA_LIST |
| 32 | 35 | #endif |
| 36 | #endif | |
| 33 | 37 | #define va_start(ap, param) __builtin_va_start(ap, param) |
| 34 | 38 | #define va_end(ap) __builtin_va_end(ap) |
| 35 | 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 | 5 | |
| 6 | 6 | // TODO: OutSteam and InStream interface |
| 7 | 7 | // TODO: move allocator to heap namespace |
| 8 | // TODO: sync up CLI with c++ code | |
| 8 | 9 | |
| 9 | 10 | error InvalidArgument; |
| 10 | 11 | error MissingArg0; |
src/all_types.hpp+7-1| ... | ... | @@ -1008,6 +1008,9 @@ struct TypeTableEntryEnum { |
| 1008 | 1008 | |
| 1009 | 1009 | size_t gen_union_index; |
| 1010 | 1010 | size_t gen_tag_index; |
| 1011 | ||
| 1012 | uint32_t union_size_bytes; | |
| 1013 | TypeTableEntry *most_aligned_union_member; | |
| 1011 | 1014 | }; |
| 1012 | 1015 | |
| 1013 | 1016 | struct TypeTableEntryEnumTag { |
| ... | ... | @@ -1514,9 +1517,12 @@ struct CodeGen { |
| 1514 | 1517 | size_t version_major; |
| 1515 | 1518 | size_t version_minor; |
| 1516 | 1519 | size_t version_patch; |
| 1517 | bool verbose; | |
| 1520 | bool verbose_tokenize; | |
| 1521 | bool verbose_ast; | |
| 1518 | 1522 | bool verbose_link; |
| 1519 | 1523 | bool verbose_ir; |
| 1524 | bool verbose_llvm_ir; | |
| 1525 | bool verbose_cimport; | |
| 1520 | 1526 | ErrColor err_color; |
| 1521 | 1527 | ImportTableEntry *root_import; |
| 1522 | 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 | 27 | static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type); |
| 28 | 28 | |
| 29 | 29 | ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) { |
| 30 | // if this assert fails, then parsec generated code that | |
| 31 | // failed semantic analysis, which isn't supposed to happen | |
| 32 | assert(!node->owner->c_import_node); | |
| 30 | if (node->owner->c_import_node != nullptr) { | |
| 31 | // if this happens, then parsec generated code that | |
| 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 | } | |
| 33 | 41 | |
| 34 | 42 | ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column, |
| 35 | 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 | 47 | } |
| 40 | 48 | |
| 41 | 49 | ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg) { |
| 42 | // if this assert fails, then parsec generated code that | |
| 43 | // failed semantic analysis, which isn't supposed to happen | |
| 44 | assert(!node->owner->c_import_node); | |
| 50 | if (node->owner->c_import_node != nullptr) { | |
| 51 | // if this happens, then parsec generated code that | |
| 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 | } | |
| 45 | 64 | |
| 46 | 65 | ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column, |
| 47 | 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 | 1363 | // unset temporary flag |
| 1345 | 1364 | enum_type->data.enumeration.embedded_in_current = false; |
| 1346 | 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; | |
| 1347 | 1368 | |
| 1348 | 1369 | if (!enum_type->data.enumeration.is_invalid) { |
| 1349 | 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 | 1386 | }; |
| 1366 | 1387 | union_type_ref = LLVMStructType(union_element_types, 2, false); |
| 1367 | 1388 | } else { |
| 1368 | LLVMTypeRef union_element_types[] = { | |
| 1369 | most_aligned_union_member->type_ref, | |
| 1370 | }; | |
| 1371 | union_type_ref = LLVMStructType(union_element_types, 1, false); | |
| 1389 | union_type_ref = most_aligned_union_member->type_ref; | |
| 1372 | 1390 | } |
| 1373 | 1391 | enum_type->data.enumeration.union_type_ref = union_type_ref; |
| 1374 | 1392 | |
| ... | ... | @@ -2804,7 +2822,6 @@ static bool is_container(TypeTableEntry *type_entry) { |
| 2804 | 2822 | switch (type_entry->id) { |
| 2805 | 2823 | case TypeTableEntryIdInvalid: |
| 2806 | 2824 | case TypeTableEntryIdVar: |
| 2807 | case TypeTableEntryIdOpaque: | |
| 2808 | 2825 | zig_unreachable(); |
| 2809 | 2826 | case TypeTableEntryIdStruct: |
| 2810 | 2827 | case TypeTableEntryIdEnum: |
| ... | ... | @@ -2831,6 +2848,7 @@ static bool is_container(TypeTableEntry *type_entry) { |
| 2831 | 2848 | case TypeTableEntryIdBoundFn: |
| 2832 | 2849 | case TypeTableEntryIdEnumTag: |
| 2833 | 2850 | case TypeTableEntryIdArgTuple: |
| 2851 | case TypeTableEntryIdOpaque: | |
| 2834 | 2852 | return false; |
| 2835 | 2853 | } |
| 2836 | 2854 | zig_unreachable(); |
| ... | ... | @@ -2982,7 +3000,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ |
| 2982 | 3000 | return; |
| 2983 | 3001 | } |
| 2984 | 3002 | |
| 2985 | if (g->verbose) { | |
| 3003 | if (g->verbose_ir) { | |
| 2986 | 3004 | fprintf(stderr, "{ // (analyzed)\n"); |
| 2987 | 3005 | ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4); |
| 2988 | 3006 | fprintf(stderr, "}\n"); |
| ... | ... | @@ -3015,7 +3033,7 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 3015 | 3033 | fn_table_entry->anal_state = FnAnalStateInvalid; |
| 3016 | 3034 | return; |
| 3017 | 3035 | } |
| 3018 | if (g->verbose) { | |
| 3036 | if (g->verbose_ir) { | |
| 3019 | 3037 | fprintf(stderr, "\n"); |
| 3020 | 3038 | ast_render(g, stderr, fn_table_entry->body_node, 4); |
| 3021 | 3039 | fprintf(stderr, "\n{ // (IR)\n"); |
| ... | ... | @@ -3115,7 +3133,7 @@ void preview_use_decl(CodeGen *g, AstNode *node) { |
| 3115 | 3133 | } |
| 3116 | 3134 | |
| 3117 | 3135 | ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code) { |
| 3118 | if (g->verbose) { | |
| 3136 | if (g->verbose_tokenize) { | |
| 3119 | 3137 | fprintf(stderr, "\nOriginal Source (%s):\n", buf_ptr(abs_full_path)); |
| 3120 | 3138 | fprintf(stderr, "----------------\n"); |
| 3121 | 3139 | fprintf(stderr, "%s\n", buf_ptr(source_code)); |
| ... | ... | @@ -3135,7 +3153,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a |
| 3135 | 3153 | exit(1); |
| 3136 | 3154 | } |
| 3137 | 3155 | |
| 3138 | if (g->verbose) { | |
| 3156 | if (g->verbose_tokenize) { | |
| 3139 | 3157 | print_tokens(source_code, tokenization.tokens); |
| 3140 | 3158 | |
| 3141 | 3159 | fprintf(stderr, "\nAST:\n"); |
| ... | ... | @@ -3150,7 +3168,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a |
| 3150 | 3168 | |
| 3151 | 3169 | import_entry->root = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color); |
| 3152 | 3170 | assert(import_entry->root); |
| 3153 | if (g->verbose) { | |
| 3171 | if (g->verbose_ast) { | |
| 3154 | 3172 | ast_print(stderr, import_entry->root, 0); |
| 3155 | 3173 | } |
| 3156 | 3174 |
src/codegen.cpp+73-34| ... | ... | @@ -196,10 +196,6 @@ void codegen_set_is_static(CodeGen *g, bool is_static) { |
| 196 | 196 | g->is_static = is_static; |
| 197 | 197 | } |
| 198 | 198 | |
| 199 | void codegen_set_verbose(CodeGen *g, bool verbose) { | |
| 200 | g->verbose = verbose; | |
| 201 | } | |
| 202 | ||
| 203 | 199 | void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) { |
| 204 | 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 | 448 | LLVMSetLinkage(fn_table_entry->llvm_value, LLVMExternalLinkage); |
| 453 | 449 | break; |
| 454 | 450 | case GlobalLinkageIdWeak: |
| 455 | LLVMSetLinkage(fn_table_entry->llvm_value, LLVMWeakAnyLinkage); | |
| 451 | LLVMSetLinkage(fn_table_entry->llvm_value, LLVMWeakODRLinkage); | |
| 456 | 452 | break; |
| 457 | 453 | case GlobalLinkageIdLinkOnce: |
| 458 | LLVMSetLinkage(fn_table_entry->llvm_value, LLVMLinkOnceAnyLinkage); | |
| 454 | LLVMSetLinkage(fn_table_entry->llvm_value, LLVMLinkOnceODRLinkage); | |
| 459 | 455 | break; |
| 460 | 456 | } |
| 461 | 457 | |
| ... | ... | @@ -3665,6 +3661,12 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con |
| 3665 | 3661 | zig_unreachable(); |
| 3666 | 3662 | } |
| 3667 | 3663 | |
| 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 | |
| 3666 | static bool is_llvm_value_unnamed_type(TypeTableEntry *type_entry, LLVMValueRef val) { | |
| 3667 | return LLVMTypeOf(val) != type_entry->type_ref; | |
| 3668 | } | |
| 3669 | ||
| 3668 | 3670 | static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3669 | 3671 | TypeTableEntry *type_entry = const_val->type; |
| 3670 | 3672 | assert(!type_entry->zero_bits); |
| ... | ... | @@ -3726,24 +3728,34 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3726 | 3728 | } else { |
| 3727 | 3729 | LLVMValueRef child_val; |
| 3728 | 3730 | LLVMValueRef maybe_val; |
| 3731 | bool make_unnamed_struct; | |
| 3729 | 3732 | if (const_val->data.x_maybe) { |
| 3730 | 3733 | child_val = gen_const_val(g, const_val->data.x_maybe); |
| 3731 | 3734 | maybe_val = LLVMConstAllOnes(LLVMInt1Type()); |
| 3735 | ||
| 3736 | make_unnamed_struct = is_llvm_value_unnamed_type(const_val->type, child_val); | |
| 3732 | 3737 | } else { |
| 3733 | child_val = LLVMConstNull(child_type->type_ref); | |
| 3738 | child_val = LLVMGetUndef(child_type->type_ref); | |
| 3734 | 3739 | maybe_val = LLVMConstNull(LLVMInt1Type()); |
| 3740 | ||
| 3741 | make_unnamed_struct = false; | |
| 3735 | 3742 | } |
| 3736 | 3743 | LLVMValueRef fields[] = { |
| 3737 | 3744 | child_val, |
| 3738 | 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 | 3754 | case TypeTableEntryIdStruct: |
| 3744 | 3755 | { |
| 3745 | 3756 | LLVMValueRef *fields = allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count); |
| 3746 | 3757 | size_t src_field_count = type_entry->data.structure.src_field_count; |
| 3758 | bool make_unnamed_struct = false; | |
| 3747 | 3759 | if (type_entry->data.structure.layout == ContainerLayoutPacked) { |
| 3748 | 3760 | size_t src_field_index = 0; |
| 3749 | 3761 | while (src_field_index < src_field_count) { |
| ... | ... | @@ -3761,8 +3773,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3761 | 3773 | } |
| 3762 | 3774 | |
| 3763 | 3775 | if (src_field_index + 1 == src_field_index_end) { |
| 3764 | fields[type_struct_field->gen_index] = | |
| 3765 | gen_const_val(g, &const_val->data.x_struct.fields[src_field_index]); | |
| 3776 | ConstExprValue *field_val = &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 | 3780 | } else { |
| 3767 | 3781 | LLVMTypeRef big_int_type_ref = LLVMStructGetTypeAtIndex(type_entry->type_ref, |
| 3768 | 3782 | (unsigned)type_struct_field->gen_index); |
| ... | ... | @@ -3790,11 +3804,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3790 | 3804 | if (type_struct_field->gen_index == SIZE_MAX) { |
| 3791 | 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, | |
| 3797 | type_entry->data.structure.layout == ContainerLayoutPacked); | |
| 3813 | if (make_unnamed_struct) { | |
| 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 | 3820 | case TypeTableEntryIdUnion: |
| 3800 | 3821 | { |
| ... | ... | @@ -3808,11 +3829,19 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3808 | 3829 | } |
| 3809 | 3830 | |
| 3810 | 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 | 3834 | for (uint64_t i = 0; i < len; i += 1) { |
| 3812 | 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 | 3846 | case TypeTableEntryIdEnum: |
| 3818 | 3847 | { |
| ... | ... | @@ -3825,14 +3854,20 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3825 | 3854 | TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag]; |
| 3826 | 3855 | assert(enum_field->value == const_val->data.x_enum.tag); |
| 3827 | 3856 | LLVMValueRef union_value; |
| 3857 | ||
| 3858 | bool make_unnamed_struct; | |
| 3859 | ||
| 3828 | 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 | 3861 | uint64_t field_type_bytes = LLVMStoreSizeOfType(g->target_data_ref, |
| 3832 | 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; | |
| 3834 | 3870 | |
| 3835 | LLVMValueRef correctly_typed_value = gen_const_val(g, const_val->data.x_enum.payload); | |
| 3836 | 3871 | if (pad_bytes == 0) { |
| 3837 | 3872 | union_value = correctly_typed_value; |
| 3838 | 3873 | } else { |
| ... | ... | @@ -3843,12 +3878,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3843 | 3878 | union_value = LLVMConstStruct(fields, 2, false); |
| 3844 | 3879 | } |
| 3845 | 3880 | } else { |
| 3881 | make_unnamed_struct = false; | |
| 3846 | 3882 | union_value = LLVMGetUndef(union_type_ref); |
| 3847 | 3883 | } |
| 3848 | 3884 | LLVMValueRef fields[2]; |
| 3849 | 3885 | fields[type_entry->data.enumeration.gen_tag_index] = tag_value; |
| 3850 | 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 | 3895 | case TypeTableEntryIdFn: |
| ... | ... | @@ -3932,18 +3973,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { |
| 3932 | 3973 | } else { |
| 3933 | 3974 | LLVMValueRef err_tag_value; |
| 3934 | 3975 | LLVMValueRef err_payload_value; |
| 3976 | bool make_unnamed_struct; | |
| 3935 | 3977 | if (const_val->data.x_err_union.err) { |
| 3936 | 3978 | err_tag_value = LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err_union.err->value, false); |
| 3937 | 3979 | err_payload_value = LLVMConstNull(child_type->type_ref); |
| 3980 | make_unnamed_struct = false; | |
| 3938 | 3981 | } else { |
| 3939 | 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 | 3987 | LLVMValueRef fields[] = { |
| 3943 | 3988 | err_tag_value, |
| 3944 | 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 | 3998 | case TypeTableEntryIdVoid: |
| ... | ... | @@ -4159,10 +4208,6 @@ static void validate_inline_fns(CodeGen *g) { |
| 4159 | 4208 | } |
| 4160 | 4209 | |
| 4161 | 4210 | static void do_code_gen(CodeGen *g) { |
| 4162 | if (g->verbose) { | |
| 4163 | fprintf(stderr, "\nCode Generation:\n"); | |
| 4164 | fprintf(stderr, "------------------\n"); | |
| 4165 | } | |
| 4166 | 4211 | assert(!g->errors.length); |
| 4167 | 4212 | |
| 4168 | 4213 | codegen_add_time_event(g, "Code Generation"); |
| ... | ... | @@ -4439,7 +4484,8 @@ static void do_code_gen(CodeGen *g) { |
| 4439 | 4484 | |
| 4440 | 4485 | ZigLLVMDIBuilderFinalize(g->dbuilder); |
| 4441 | 4486 | |
| 4442 | if (g->verbose || g->verbose_ir) { | |
| 4487 | if (g->verbose_llvm_ir) { | |
| 4488 | fflush(stderr); | |
| 4443 | 4489 | LLVMDumpModule(g->module); |
| 4444 | 4490 | } |
| 4445 | 4491 | |
| ... | ... | @@ -5269,10 +5315,6 @@ static void gen_root_source(CodeGen *g) { |
| 5269 | 5315 | resolve_top_level_decl(g, panic_tld, false, nullptr); |
| 5270 | 5316 | } |
| 5271 | 5317 | |
| 5272 | if (g->verbose) { | |
| 5273 | fprintf(stderr, "\nIR Generation and Semantic Analysis:\n"); | |
| 5274 | fprintf(stderr, "--------------------------------------\n"); | |
| 5275 | } | |
| 5276 | 5318 | if (!g->error_during_imports) { |
| 5277 | 5319 | semantic_analyze(g); |
| 5278 | 5320 | } |
| ... | ... | @@ -5286,9 +5328,6 @@ static void gen_root_source(CodeGen *g) { |
| 5286 | 5328 | } |
| 5287 | 5329 | |
| 5288 | 5330 | report_errors_and_maybe_exit(g); |
| 5289 | if (g->verbose) { | |
| 5290 | fprintf(stderr, "OK\n"); | |
| 5291 | } | |
| 5292 | 5331 | |
| 5293 | 5332 | } |
| 5294 | 5333 |
src/codegen.hpp-1| ... | ... | @@ -25,7 +25,6 @@ void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath); |
| 25 | 25 | |
| 26 | 26 | void codegen_set_is_static(CodeGen *codegen, bool is_static); |
| 27 | 27 | void codegen_set_strip(CodeGen *codegen, bool strip); |
| 28 | void codegen_set_verbose(CodeGen *codegen, bool verbose); | |
| 29 | 28 | void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color); |
| 30 | 29 | void codegen_set_out_name(CodeGen *codegen, Buf *out_name); |
| 31 | 30 | void codegen_set_libc_lib_dir(CodeGen *codegen, Buf *libc_lib_dir); |
src/config.h.in-1| ... | ... | @@ -20,7 +20,6 @@ |
| 20 | 20 | #define ZIG_DYNAMIC_LINKER "@ZIG_DYNAMIC_LINKER@" |
| 21 | 21 | |
| 22 | 22 | #cmakedefine ZIG_EACH_LIB_RPATH |
| 23 | #cmakedefine ZIG_LLVM_OLD_CXX_ABI | |
| 24 | 23 | |
| 25 | 24 | // Only used for running tests before installing. |
| 26 | 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 | 123 | size_t end_line = line + 1; |
| 124 | 124 | size_t line_end_offset = (end_line >= line_offsets->length) ? buf_len(source) : line_offsets->at(line + 1); |
| 125 | 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; | |
| 126 | 127 | |
| 127 | 128 | buf_init_from_mem(&err_msg->line_buf, buf_ptr(source) + line_start_offset, len); |
| 128 | 129 |
src/ir.cpp+8-3| ... | ... | @@ -7849,7 +7849,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node |
| 7849 | 7849 | if (ir_executable.invalid) |
| 7850 | 7850 | return codegen->invalid_instruction; |
| 7851 | 7851 | |
| 7852 | if (codegen->verbose) { | |
| 7852 | if (codegen->verbose_ir) { | |
| 7853 | 7853 | fprintf(stderr, "\nSource: "); |
| 7854 | 7854 | ast_render(codegen, stderr, node, 4); |
| 7855 | 7855 | fprintf(stderr, "\n{ // (IR)\n"); |
| ... | ... | @@ -7870,7 +7870,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node |
| 7870 | 7870 | if (type_is_invalid(result_type)) |
| 7871 | 7871 | return codegen->invalid_instruction; |
| 7872 | 7872 | |
| 7873 | if (codegen->verbose) { | |
| 7873 | if (codegen->verbose_ir) { | |
| 7874 | 7874 | fprintf(stderr, "{ // (analyzed)\n"); |
| 7875 | 7875 | ir_print(codegen, stderr, &analyzed_executable, 4); |
| 7876 | 7876 | fprintf(stderr, "}\n"); |
| ... | ... | @@ -13514,7 +13514,7 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc |
| 13514 | 13514 | return ira->codegen->builtin_types.entry_invalid; |
| 13515 | 13515 | } |
| 13516 | 13516 | |
| 13517 | if (ira->codegen->verbose) { | |
| 13517 | if (ira->codegen->verbose_cimport) { | |
| 13518 | 13518 | fprintf(stderr, "\nC imports:\n"); |
| 13519 | 13519 | fprintf(stderr, "-----------\n"); |
| 13520 | 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 | 15312 | if (!ir_resolve_align(ira, align_bytes_inst, &align_bytes)) |
| 15313 | 15313 | return ira->codegen->builtin_types.entry_invalid; |
| 15314 | 15314 | |
| 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 | 15320 | FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 15316 | 15321 | if (fn_entry == nullptr) { |
| 15317 | 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 | 37 | parent_gen->zig_lib_dir); |
| 38 | 38 | |
| 39 | 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 | 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; | |
| 41 | 46 | |
| 42 | 47 | codegen_set_cache_dir(child_gen, parent_gen->cache_dir); |
| 43 | 48 | |
| ... | ... | @@ -46,7 +51,6 @@ static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path) |
| 46 | 51 | |
| 47 | 52 | codegen_set_out_name(child_gen, buf_create_from_str(oname)); |
| 48 | 53 | |
| 49 | codegen_set_verbose(child_gen, parent_gen->verbose); | |
| 50 | 54 | codegen_set_errmsg_color(child_gen, parent_gen->err_color); |
| 51 | 55 | |
| 52 | 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 | 862 | buf_resize(&lj.out_file, 0); |
| 859 | 863 | } |
| 860 | 864 | |
| 861 | if (g->verbose || g->verbose_ir) { | |
| 865 | if (g->verbose_llvm_ir) { | |
| 862 | 866 | fprintf(stderr, "\nOptimization:\n"); |
| 863 | 867 | fprintf(stderr, "---------------\n"); |
| 868 | fflush(stderr); | |
| 864 | 869 | LLVMDumpModule(g->module); |
| 865 | 870 | } |
| 866 | if (g->verbose || g->verbose_link) { | |
| 867 | fprintf(stderr, "\nLink:\n"); | |
| 868 | fprintf(stderr, "-------\n"); | |
| 869 | } | |
| 870 | 871 | |
| 871 | 872 | bool override_out_file = (buf_len(&lj.out_file) != 0); |
| 872 | 873 | if (!override_out_file) { |
| ... | ... | @@ -887,9 +888,6 @@ void codegen_link(CodeGen *g, const char *out_file) { |
| 887 | 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 | 891 | return; |
| 894 | 892 | } |
| 895 | 893 | |
| ... | ... | @@ -907,7 +905,7 @@ void codegen_link(CodeGen *g, const char *out_file) { |
| 907 | 905 | construct_linker_job(&lj); |
| 908 | 906 | |
| 909 | 907 | |
| 910 | if (g->verbose || g->verbose_link) { | |
| 908 | if (g->verbose_link) { | |
| 911 | 909 | for (size_t i = 0; i < lj.args.length; i += 1) { |
| 912 | 910 | const char *space = (i != 0) ? " " : ""; |
| 913 | 911 | fprintf(stderr, "%s%s", space, lj.args.at(i)); |
| ... | ... | @@ -924,8 +922,4 @@ void codegen_link(CodeGen *g, const char *out_file) { |
| 924 | 922 | } |
| 925 | 923 | |
| 926 | 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 | 20 | fprintf(stderr, "Usage: %s [command] [options]\n" |
| 21 | 21 | "Commands:\n" |
| 22 | 22 | " build build project from build.zig\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" | |
| 25 | " build-obj [source] create object from source or assembly\n" | |
| 26 | " parsec [source] convert c code to zig code\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" | |
| 25 | " build-obj $source create object from source or assembly\n" | |
| 26 | " parsec $source convert c code to zig code\n" | |
| 27 | 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 | 29 | " version print version number and exit\n" |
| 30 | 30 | " zen print zen of zig and exit\n" |
| 31 | 31 | "Compile Options:\n" |
| 32 | " --assembly [source] add assembly file to build\n" | |
| 33 | " --cache-dir [path] override the cache directory\n" | |
| 34 | " --color [auto|off|on] enable or disable colored error messages\n" | |
| 32 | " --assembly $source add assembly file to build\n" | |
| 33 | " --cache-dir $path override the cache directory\n" | |
| 34 | " --color $auto|off|on enable or disable colored error messages\n" | |
| 35 | 35 | " --enable-timing-info print timing diagnostics\n" |
| 36 | " --libc-include-dir [path] directory where libc stdlib.h resides\n" | |
| 37 | " --name [name] override output name\n" | |
| 38 | " --output [file] override destination 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" | |
| 36 | " --libc-include-dir $path directory where libc stdlib.h resides\n" | |
| 37 | " --name $name override output name\n" | |
| 38 | " --output $file override destination 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" | |
| 41 | 41 | " --pkg-end pop current pkg\n" |
| 42 | 42 | " --release-fast build with optimizations on and safety off\n" |
| 43 | 43 | " --release-safe build with optimizations on and safety on\n" |
| 44 | 44 | " --static output will be statically linked\n" |
| 45 | 45 | " --strip exclude debug symbols\n" |
| 46 | " --target-arch [name] specify target architecture\n" | |
| 47 | " --target-environ [name] specify target environment\n" | |
| 48 | " --target-os [name] specify target operating system\n" | |
| 49 | " --verbose turn on compiler debug output\n" | |
| 50 | " --verbose-link turn on compiler debug output for linking only\n" | |
| 51 | " --verbose-ir turn on compiler debug output for IR only\n" | |
| 52 | " --zig-install-prefix [path] override directory where zig thinks it is installed\n" | |
| 53 | " -dirafter [dir] same as -isystem but do it last\n" | |
| 54 | " -isystem [dir] add additional search path for other .h files\n" | |
| 55 | " -mllvm [arg] additional arguments to forward to LLVM's option processing\n" | |
| 46 | " --target-arch $name specify target architecture\n" | |
| 47 | " --target-environ $name specify target environment\n" | |
| 48 | " --target-os $name specify target operating system\n" | |
| 49 | " --verbose-tokenize turn on compiler debug output for tokenization\n" | |
| 50 | " --verbose-ast turn on compiler debug output for parsing into an AST\n" | |
| 51 | " --verbose-link turn on compiler debug output for linking\n" | |
| 52 | " --verbose-ir turn on compiler debug output for Zig IR\n" | |
| 53 | " --verbose-llvm-ir turn on compiler debug output for LLVM IR\n" | |
| 54 | " --verbose-cimport turn on compiler debug output for C imports\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 | 59 | "Link Options:\n" |
| 57 | " --ar-path [path] set the path to ar\n" | |
| 58 | " --dynamic-linker [path] set the path to ld.so\n" | |
| 60 | " --ar-path $path set the path to ar\n" | |
| 61 | " --dynamic-linker $path set the path to ld.so\n" | |
| 59 | 62 | " --each-lib-rpath add rpath for each used dynamic library\n" |
| 60 | " --libc-lib-dir [path] directory where libc crt1.o resides\n" | |
| 61 | " --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n" | |
| 62 | " --msvc-lib-dir [path] (windows) directory where vcruntime.lib resides\n" | |
| 63 | " --kernel32-lib-dir [path] (windows) directory where kernel32.lib resides\n" | |
| 64 | " --library [lib] link against lib\n" | |
| 65 | " --library-path [dir] add a directory to the library search path\n" | |
| 66 | " --linker-script [path] use a custom linker script\n" | |
| 67 | " --object [obj] add object file to build\n" | |
| 68 | " -L[dir] alias for --library-path\n" | |
| 63 | " --libc-lib-dir $path directory where libc crt1.o resides\n" | |
| 64 | " --libc-static-lib-dir $path directory where libc crtbegin.o resides\n" | |
| 65 | " --msvc-lib-dir $path (windows) directory where vcruntime.lib resides\n" | |
| 66 | " --kernel32-lib-dir $path (windows) directory where kernel32.lib resides\n" | |
| 67 | " --library $lib link against lib\n" | |
| 68 | " --library-path $dir add a directory to the library search path\n" | |
| 69 | " --linker-script $path use a custom linker script\n" | |
| 70 | " --object $obj add object file to build\n" | |
| 71 | " -L$dir alias for --library-path\n" | |
| 69 | 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 | 74 | " -mconsole (windows) --subsystem console to the linker\n" |
| 72 | 75 | " -mwindows (windows) --subsystem windows to the linker\n" |
| 73 | " -framework [name] (darwin) link against framework\n" | |
| 74 | " -mios-version-min [ver] (darwin) set iOS deployment target\n" | |
| 75 | " -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target\n" | |
| 76 | " --ver-major [ver] dynamic library semver major version\n" | |
| 77 | " --ver-minor [ver] dynamic library semver minor version\n" | |
| 78 | " --ver-patch [ver] dynamic library semver patch version\n" | |
| 76 | " -framework $name (darwin) link against framework\n" | |
| 77 | " -mios-version-min $ver (darwin) set iOS deployment target\n" | |
| 78 | " -mmacosx-version-min $ver (darwin) set Mac OS X deployment target\n" | |
| 79 | " --ver-major $ver dynamic library semver major version\n" | |
| 80 | " --ver-minor $ver dynamic library semver minor version\n" | |
| 81 | " --ver-patch $ver dynamic library semver patch version\n" | |
| 79 | 82 | "Test Options:\n" |
| 80 | " --test-filter [text] skip tests that do not match filter\n" | |
| 81 | " --test-name-prefix [text] add prefix to all tests\n" | |
| 82 | " --test-cmd [arg] specify test execution command one arg at a time\n" | |
| 83 | " --test-filter $text skip tests that do not match filter\n" | |
| 84 | " --test-name-prefix $text add prefix to all tests\n" | |
| 85 | " --test-cmd $arg specify test execution command one arg at a time\n" | |
| 83 | 86 | " --test-cmd-bin appends test binary path to test cmd args\n" |
| 84 | 87 | , arg0); |
| 85 | 88 | return EXIT_FAILURE; |
| ... | ... | @@ -273,9 +276,12 @@ int main(int argc, char **argv) { |
| 273 | 276 | bool is_static = false; |
| 274 | 277 | OutType out_type = OutTypeUnknown; |
| 275 | 278 | const char *out_name = nullptr; |
| 276 | bool verbose = false; | |
| 279 | bool verbose_tokenize = false; | |
| 280 | bool verbose_ast = false; | |
| 277 | 281 | bool verbose_link = false; |
| 278 | 282 | bool verbose_ir = false; |
| 283 | bool verbose_llvm_ir = false; | |
| 284 | bool verbose_cimport = false; | |
| 279 | 285 | ErrColor color = ErrColorAuto; |
| 280 | 286 | const char *libc_lib_dir = nullptr; |
| 281 | 287 | const char *libc_static_lib_dir = nullptr; |
| ... | ... | @@ -326,9 +332,7 @@ int main(int argc, char **argv) { |
| 326 | 332 | args.append(NULL); // placeholder |
| 327 | 333 | args.append(NULL); // placeholder |
| 328 | 334 | for (int i = 2; i < argc; i += 1) { |
| 329 | if (strcmp(argv[i], "--debug-build-verbose") == 0) { | |
| 330 | verbose = true; | |
| 331 | } else if (strcmp(argv[i], "--help") == 0) { | |
| 335 | if (strcmp(argv[i], "--help") == 0) { | |
| 332 | 336 | asked_for_help = true; |
| 333 | 337 | args.append(argv[i]); |
| 334 | 338 | } else if (i + 1 < argc && strcmp(argv[i], "--build-file") == 0) { |
| ... | ... | @@ -361,7 +365,6 @@ int main(int argc, char **argv) { |
| 361 | 365 | |
| 362 | 366 | CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, zig_lib_dir_buf); |
| 363 | 367 | codegen_set_out_name(g, buf_create_from_str("build")); |
| 364 | codegen_set_verbose(g, verbose); | |
| 365 | 368 | |
| 366 | 369 | Buf build_file_abs = BUF_INIT; |
| 367 | 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 | 399 | "\n" |
| 397 | 400 | "General Options:\n" |
| 398 | 401 | " --help Print this help and exit\n" |
| 399 | " --build-file [file] Override path to build.zig\n" | |
| 400 | " --cache-dir [path] Override path to cache directory\n" | |
| 402 | " --build-file $file Override path to build.zig\n" | |
| 403 | " --cache-dir $path Override path to cache directory\n" | |
| 401 | 404 | " --verbose Print commands before executing them\n" |
| 402 | " --debug-build-verbose Print verbose debugging information for the build system itself\n" | |
| 403 | " --prefix [prefix] Override default install prefix\n" | |
| 405 | " --verbose-tokenize Enable compiler debug output for tokenization\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 | 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 | 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 | 426 | , zig_exe_path); |
| 408 | 427 | return 0; |
| 409 | 428 | } |
| ... | ... | @@ -450,12 +469,18 @@ int main(int argc, char **argv) { |
| 450 | 469 | strip = true; |
| 451 | 470 | } else if (strcmp(arg, "--static") == 0) { |
| 452 | 471 | is_static = true; |
| 453 | } else if (strcmp(arg, "--verbose") == 0) { | |
| 454 | verbose = true; | |
| 472 | } else if (strcmp(arg, "--verbose-tokenize") == 0) { | |
| 473 | verbose_tokenize = true; | |
| 474 | } else if (strcmp(arg, "--verbose-ast") == 0) { | |
| 475 | verbose_ast = true; | |
| 455 | 476 | } else if (strcmp(arg, "--verbose-link") == 0) { |
| 456 | 477 | verbose_link = true; |
| 457 | 478 | } else if (strcmp(arg, "--verbose-ir") == 0) { |
| 458 | 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 | 484 | } else if (strcmp(arg, "-mwindows") == 0) { |
| 460 | 485 | mwindows = true; |
| 461 | 486 | } else if (strcmp(arg, "-mconsole") == 0) { |
| ... | ... | @@ -738,9 +763,12 @@ int main(int argc, char **argv) { |
| 738 | 763 | codegen_set_kernel32_lib_dir(g, buf_create_from_str(kernel32_lib_dir)); |
| 739 | 764 | if (dynamic_linker) |
| 740 | 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 | 768 | g->verbose_link = verbose_link; |
| 743 | 769 | g->verbose_ir = verbose_ir; |
| 770 | g->verbose_llvm_ir = verbose_llvm_ir; | |
| 771 | g->verbose_cimport = verbose_cimport; | |
| 744 | 772 | codegen_set_errmsg_color(g, color); |
| 745 | 773 | |
| 746 | 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 | 3167 | { |
| 3168 | 3168 | Context context = {0}; |
| 3169 | 3169 | Context *c = &context; |
| 3170 | c->warnings_on = codegen->verbose; | |
| 3170 | c->warnings_on = codegen->verbose_cimport; | |
| 3171 | 3171 | c->import = import; |
| 3172 | 3172 | c->errors = errors; |
| 3173 | 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 | 416 | } |
| 417 | 417 | } |
| 418 | 418 | |
| 419 | static 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 | ||
| 442 | static 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 | ||
| 419 | 457 | void tokenize(Buf *buf, Tokenization *out) { |
| 420 | 458 | Tokenize t = {0}; |
| 421 | 459 | t.out = out; |
| ... | ... | @@ -580,7 +618,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 580 | 618 | t.state = TokenizeStateSawQuestionMark; |
| 581 | 619 | break; |
| 582 | 620 | default: |
| 583 | tokenize_error(&t, "invalid character: '%c'", c); | |
| 621 | invalid_char_error(&t, c); | |
| 584 | 622 | } |
| 585 | 623 | break; |
| 586 | 624 | case TokenizeStateSawQuestionMark: |
| ... | ... | @@ -890,7 +928,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 890 | 928 | t.state = TokenizeStateLineString; |
| 891 | 929 | break; |
| 892 | 930 | default: |
| 893 | tokenize_error(&t, "invalid character: '%c'", c); | |
| 931 | invalid_char_error(&t, c); | |
| 894 | 932 | break; |
| 895 | 933 | } |
| 896 | 934 | break; |
| ... | ... | @@ -919,7 +957,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 919 | 957 | break; |
| 920 | 958 | case '\\': |
| 921 | 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 | 962 | t.state = TokenizeStateLineStringContinue; |
| 925 | 963 | break; |
| ... | ... | @@ -949,7 +987,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 949 | 987 | buf_append_char(&t.cur_tok->data.str_lit.str, '\n'); |
| 950 | 988 | break; |
| 951 | 989 | default: |
| 952 | tokenize_error(&t, "invalid character: '%c'", c); | |
| 990 | invalid_char_error(&t, c); | |
| 953 | 991 | break; |
| 954 | 992 | } |
| 955 | 993 | break; |
| ... | ... | @@ -1073,7 +1111,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 1073 | 1111 | handle_string_escape(&t, '\"'); |
| 1074 | 1112 | break; |
| 1075 | 1113 | default: |
| 1076 | tokenize_error(&t, "invalid character: '%c'", c); | |
| 1114 | invalid_char_error(&t, c); | |
| 1077 | 1115 | } |
| 1078 | 1116 | break; |
| 1079 | 1117 | case TokenizeStateCharCode: |
| ... | ... | @@ -1147,7 +1185,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 1147 | 1185 | t.state = TokenizeStateStart; |
| 1148 | 1186 | break; |
| 1149 | 1187 | default: |
| 1150 | tokenize_error(&t, "invalid character: '%c'", c); | |
| 1188 | invalid_char_error(&t, c); | |
| 1151 | 1189 | } |
| 1152 | 1190 | break; |
| 1153 | 1191 | case TokenizeStateZero: |
| ... | ... | @@ -1189,7 +1227,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 1189 | 1227 | uint32_t digit_value = get_digit_value(c); |
| 1190 | 1228 | if (digit_value >= t.radix) { |
| 1191 | 1229 | if (is_symbol_char(c)) { |
| 1192 | tokenize_error(&t, "invalid character: '%c'", c); | |
| 1230 | invalid_char_error(&t, c); | |
| 1193 | 1231 | } |
| 1194 | 1232 | // not my char |
| 1195 | 1233 | t.pos -= 1; |
| ... | ... | @@ -1233,7 +1271,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 1233 | 1271 | uint32_t digit_value = get_digit_value(c); |
| 1234 | 1272 | if (digit_value >= t.radix) { |
| 1235 | 1273 | if (is_symbol_char(c)) { |
| 1236 | tokenize_error(&t, "invalid character: '%c'", c); | |
| 1274 | invalid_char_error(&t, c); | |
| 1237 | 1275 | } |
| 1238 | 1276 | // not my char |
| 1239 | 1277 | t.pos -= 1; |
| ... | ... | @@ -1282,7 +1320,7 @@ void tokenize(Buf *buf, Tokenization *out) { |
| 1282 | 1320 | uint32_t digit_value = get_digit_value(c); |
| 1283 | 1321 | if (digit_value >= t.radix) { |
| 1284 | 1322 | if (is_symbol_char(c)) { |
| 1285 | tokenize_error(&t, "invalid character: '%c'", c); | |
| 1323 | invalid_char_error(&t, c); | |
| 1286 | 1324 | } |
| 1287 | 1325 | // not my char |
| 1288 | 1326 | t.pos -= 1; |
src/zig_llvm.cpp+2-9| ... | ... | @@ -5,15 +5,6 @@ |
| 5 | 5 | * See http://opensource.org/licenses/MIT |
| 6 | 6 | */ |
| 7 | 7 | |
| 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 | ||
| 17 | 8 | |
| 18 | 9 | /* |
| 19 | 10 | * The point of this file is to contain all the LLVM C++ API interaction so that: |
| ... | ... | @@ -22,6 +13,8 @@ |
| 22 | 13 | * 3. Prevent C++ from infecting the rest of the project. |
| 23 | 14 | */ |
| 24 | 15 | |
| 16 | #include "zig_llvm.hpp" | |
| 17 | ||
| 25 | 18 | #include <llvm/Analysis/TargetLibraryInfo.h> |
| 26 | 19 | #include <llvm/Analysis/TargetTransformInfo.h> |
| 27 | 20 | #include <llvm/IR/DIBuilder.h> |
std/build.zig+32-7| ... | ... | @@ -33,6 +33,12 @@ pub const Builder = struct { |
| 33 | 33 | available_options_map: AvailableOptionsMap, |
| 34 | 34 | available_options_list: ArrayList(AvailableOption), |
| 35 | 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 | 42 | invalid_user_input: bool, |
| 37 | 43 | zig_exe: []const u8, |
| 38 | 44 | default_step: &Step, |
| ... | ... | @@ -88,6 +94,12 @@ pub const Builder = struct { |
| 88 | 94 | .build_root = build_root, |
| 89 | 95 | .cache_root = %%os.path.relative(allocator, build_root, cache_root), |
| 90 | 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 | 103 | .invalid_user_input = false, |
| 92 | 104 | .allocator = allocator, |
| 93 | 105 | .lib_paths = ArrayList([]const u8).init(allocator), |
| ... | ... | @@ -536,15 +548,19 @@ pub const Builder = struct { |
| 536 | 548 | return self.spawnChildEnvMap(null, &self.env_map, argv); |
| 537 | 549 | } |
| 538 | 550 | |
| 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 | 559 | fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap, |
| 540 | 560 | argv: []const []const u8) -> %void |
| 541 | 561 | { |
| 542 | 562 | if (self.verbose) { |
| 543 | if (cwd) |yes_cwd| %%io.stderr.print("cd {}; ", yes_cwd); | |
| 544 | for (argv) |arg| { | |
| 545 | %%io.stderr.print("{} ", arg); | |
| 546 | } | |
| 547 | %%io.stderr.printf("\n"); | |
| 563 | printCmd(cwd, argv); | |
| 548 | 564 | } |
| 549 | 565 | |
| 550 | 566 | const child = %%os.ChildProcess.init(argv, self.allocator); |
| ... | ... | @@ -561,12 +577,15 @@ pub const Builder = struct { |
| 561 | 577 | switch (term) { |
| 562 | 578 | Term.Exited => |code| { |
| 563 | 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 | 582 | return error.UncleanExit; |
| 566 | 583 | } |
| 567 | 584 | }, |
| 568 | 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 | 589 | return error.UncleanExit; |
| 571 | 590 | }, |
| 572 | 591 | }; |
| ... | ... | @@ -1117,6 +1136,12 @@ pub const LibExeObjStep = struct { |
| 1117 | 1136 | if (self.verbose) { |
| 1118 | 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"); | |
| 1120 | 1145 | |
| 1121 | 1146 | if (self.strip) { |
| 1122 | 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 | 32 | fn errol3u(val: f64, buffer: []u8) -> FloatDecimal { |
| 33 | 33 | // check if in integer or fixed range |
| 34 | 34 | |
| 35 | if (val >= 9.007199254740992e15 and val < 3.40282366920938e+38) { | |
| 35 | if (val > 9.007199254740992e15 and val < 3.40282366920938e+38) { | |
| 36 | 36 | return errolInt(val, buffer); |
| 37 | 37 | } else if (val >= 16.0 and val < 9.007199254740992e15) { |
| 38 | 38 | return errolFixed(val, buffer); |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | ||
| 41 | ||
| 42 | 42 | // normalize the midpoint |
| 43 | 43 | |
| 44 | 44 | const e = math.frexp(val).exponent; |
| ... | ... | @@ -138,7 +138,7 @@ fn tableLowerBound(k: u64) -> usize { |
| 138 | 138 | |
| 139 | 139 | while (j < enum3.len) { |
| 140 | 140 | if (enum3[j] < k) { |
| 141 | j = 2 * k + 2; | |
| 141 | j = 2 * j + 2; | |
| 142 | 142 | } else { |
| 143 | 143 | i = j; |
| 144 | 144 | j = 2 * j + 1; |
| ... | ... | @@ -217,7 +217,7 @@ fn hpMul10(hp: &HP) { |
| 217 | 217 | |
| 218 | 218 | hp.val *= 10.0; |
| 219 | 219 | hp.off *= 10.0; |
| 220 | ||
| 220 | ||
| 221 | 221 | var off = hp.val; |
| 222 | 222 | off -= val * 8.0; |
| 223 | 223 | off -= val * 2.0; |
| ... | ... | @@ -235,13 +235,13 @@ fn hpMul10(hp: &HP) { |
| 235 | 235 | fn errolInt(val: f64, buffer: []u8) -> FloatDecimal { |
| 236 | 236 | const pow19 = u128(1e19); |
| 237 | 237 | |
| 238 | assert((val >= 9.007199254740992e15) and val < (3.40282366920938e38)); | |
| 238 | assert((val > 9.007199254740992e15) and val < (3.40282366920938e38)); | |
| 239 | 239 | |
| 240 | 240 | var mid = u128(val); |
| 241 | 241 | var low: u128 = mid - fpeint((fpnext(val) - val) / 2.0); |
| 242 | 242 | var high: u128 = mid + fpeint((val - fpprev(val)) / 2.0); |
| 243 | 243 | |
| 244 | if (@bitCast(u64, val) & 0x1 != 0) { | |
| 244 | if (@bitCast(u64, val) & 0x1 != 0) { | |
| 245 | 245 | high -= 1; |
| 246 | 246 | } else { |
| 247 | 247 | low -= 1; |
| ... | ... | @@ -347,11 +347,11 @@ fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal { |
| 347 | 347 | } |
| 348 | 348 | |
| 349 | 349 | fn fpnext(val: f64) -> f64 { |
| 350 | return @bitCast(f64, @bitCast(u64, val) + 1); | |
| 350 | return @bitCast(f64, @bitCast(u64, val) +% 1); | |
| 351 | 351 | } |
| 352 | 352 | |
| 353 | 353 | fn fpprev(val: f64) -> f64 { |
| 354 | return @bitCast(f64, @bitCast(u64, val) - 1); | |
| 354 | return @bitCast(f64, @bitCast(u64, val) -% 1); | |
| 355 | 355 | } |
| 356 | 356 | |
| 357 | 357 | pub const c_digits_lut = []u8 { |
| ... | ... | @@ -510,10 +510,6 @@ fn u64toa(value_param: u64, buffer: []u8) -> usize { |
| 510 | 510 | buf_index += 1; |
| 511 | 511 | buffer[buf_index] = c_digits_lut[d8]; |
| 512 | 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 | 513 | buffer[buf_index] = c_digits_lut[d8 + 1]; |
| 518 | 514 | buf_index += 1; |
| 519 | 515 | } else { |
| ... | ... | @@ -613,7 +609,7 @@ fn fpeint(from: f64) -> u128 { |
| 613 | 609 | const bits = @bitCast(u64, from); |
| 614 | 610 | assert((bits & ((1 << 52) - 1)) == 0); |
| 615 | 611 | |
| 616 | return u64(1) << u6(((bits >> 52) - 1023)); | |
| 612 | return u128(1) << @truncate(u7, (bits >> 52) -% 1023); | |
| 617 | 613 | } |
| 618 | 614 | |
| 619 | 615 |
std/fmt/index.zig+60-11| ... | ... | @@ -244,30 +244,47 @@ pub fn formatBuf(buf: []const u8, width: usize, |
| 244 | 244 | } |
| 245 | 245 | |
| 246 | 246 | pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)->bool) -> bool { |
| 247 | var buffer: [20]u8 = undefined; | |
| 248 | const float_decimal = errol3(f64(value), buffer[0..]); | |
| 249 | if (float_decimal.exp != 0) { | |
| 250 | if (!output(context, float_decimal.digits[0..1])) | |
| 251 | return false; | |
| 252 | } else { | |
| 253 | if (!output(context, "0")) | |
| 247 | var x = f64(value); | |
| 248 | ||
| 249 | // Errol doesn't handle these special cases. | |
| 250 | if (math.isNan(x)) { | |
| 251 | return output(context, "NaN"); | |
| 252 | } | |
| 253 | if (math.signbit(x)) { | |
| 254 | if (!output(context, "-")) | |
| 254 | 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 | 269 | if (!output(context, ".")) |
| 257 | 270 | return false; |
| 258 | 271 | if (float_decimal.digits.len > 1) { |
| 259 | const start = if (float_decimal.exp == 0) usize(0) else usize(1); | |
| 260 | if (!output(context, float_decimal.digits[start .. math.min(usize(7), float_decimal.digits.len)])) | |
| 272 | const num_digits = if (@typeOf(value) == f32) { | |
| 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 | 278 | return false; |
| 262 | 279 | } else { |
| 263 | 280 | if (!output(context, "0")) |
| 264 | 281 | return false; |
| 265 | 282 | } |
| 266 | 283 | |
| 267 | if (float_decimal.exp != 1 and float_decimal.exp != 0) { | |
| 284 | if (float_decimal.exp != 1) { | |
| 268 | 285 | if (!output(context, "e")) |
| 269 | 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 | 288 | return false; |
| 272 | 289 | } |
| 273 | 290 | return true; |
| ... | ... | @@ -514,6 +531,38 @@ test "fmt.format" { |
| 514 | 531 | const result = bufPrint(buf1[0..], "u3: {}\n", value); |
| 515 | 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 | } |
| 518 | 567 | |
| 519 | 568 | pub fn trim(buf: []const u8) -> []const u8 { |
std/special/build_runner.zig+32-7| ... | ... | @@ -69,6 +69,18 @@ pub fn main() -> %void { |
| 69 | 69 | %%io.stderr.printf("Expected argument after --prefix\n\n"); |
| 70 | 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 | 84 | } else { |
| 73 | 85 | %%io.stderr.printf("Unrecognized argument: {}\n\n", arg); |
| 74 | 86 | return usage(&builder, false, &io.stderr); |
| ... | ... | @@ -116,27 +128,40 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) |
| 116 | 128 | \\ |
| 117 | 129 | \\General Options: |
| 118 | 130 | \\ --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 | 131 | \\ --verbose Print commands before executing them |
| 122 | \\ --debug-build-verbose Print verbose debugging information for the build system itself | |
| 123 | \\ --prefix [prefix] Override default install prefix | |
| 132 | \\ --prefix $path Override default install prefix | |
| 124 | 133 | \\ |
| 125 | 134 | \\Project-Specific Options: |
| 126 | 135 | \\ |
| 127 | 136 | ); |
| 128 | 137 | |
| 129 | 138 | if (builder.available_options_list.len == 0) { |
| 130 | %%out_stream.printf(" (none)\n"); | |
| 139 | %%out_stream.print(" (none)\n"); | |
| 131 | 140 | } else { |
| 132 | 141 | for (builder.available_options_list.toSliceConst()) |option| { |
| 133 | 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 | 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 | } |
| 139 | 148 | |
| 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 | 165 | if (out_stream == &io.stderr) |
| 141 | 166 | return error.InvalidArgs; |
| 142 | 167 | } |
std/special/compiler_rt/comparetf2.zig+1-1| ... | ... | @@ -20,7 +20,7 @@ const infRep = exponentMask; |
| 20 | 20 | |
| 21 | 21 | const builtin = @import("builtin"); |
| 22 | 22 | const is_test = builtin.is_test; |
| 23 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 23 | const linkage = @import("index.zig").linkage; | |
| 24 | 24 | |
| 25 | 25 | export fn __letf2(a: f128, b: f128) -> c_int { |
| 26 | 26 | @setDebugSafety(this, is_test); |
std/special/compiler_rt/fixunsdfdi.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 4 | |
| 5 | 5 | export fn __fixunsdfdi(a: f64) -> u64 { |
| 6 | 6 | @setDebugSafety(this, builtin.is_test); |
std/special/compiler_rt/fixunsdfsi.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 4 | |
| 5 | 5 | export fn __fixunsdfsi(a: f64) -> u32 { |
| 6 | 6 | @setDebugSafety(this, builtin.is_test); |
std/special/compiler_rt/fixunsdfti.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 4 | |
| 5 | 5 | export fn __fixunsdfti(a: f64) -> u128 { |
| 6 | 6 | @setDebugSafety(this, builtin.is_test); |
std/special/compiler_rt/fixunssfdi.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 4 | |
| 5 | 5 | export fn __fixunssfdi(a: f32) -> u64 { |
| 6 | 6 | @setDebugSafety(this, builtin.is_test); |
std/special/compiler_rt/fixunssfsi.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 4 | |
| 5 | 5 | export fn __fixunssfsi(a: f32) -> u32 { |
| 6 | 6 | @setDebugSafety(this, builtin.is_test); |
std/special/compiler_rt/fixunssfti.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 4 | |
| 5 | 5 | export fn __fixunssfti(a: f32) -> u128 { |
| 6 | 6 | @setDebugSafety(this, builtin.is_test); |
std/special/compiler_rt/fixunstfdi.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 4 | |
| 5 | 5 | export fn __fixunstfdi(a: f128) -> u64 { |
| 6 | 6 | @setDebugSafety(this, builtin.is_test); |
std/special/compiler_rt/fixunstfsi.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 4 | |
| 5 | 5 | export fn __fixunstfsi(a: f128) -> u32 { |
| 6 | 6 | @setDebugSafety(this, builtin.is_test); |
std/special/compiler_rt/fixunstfti.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const fixuint = @import("fixuint.zig").fixuint; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 4 | |
| 5 | 5 | export fn __fixunstfti(a: f128) -> u128 { |
| 6 | 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 | 26 | const win64 = builtin.os == builtin.Os.windows and builtin.arch == builtin.Arch.x86_64; |
| 27 | 27 | const win32_nocrt = win32 and !builtin.link_libc; |
| 28 | 28 | const win64_nocrt = win64 and !builtin.link_libc; |
| 29 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 29 | pub const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak; | |
| 30 | 30 | const strong_linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong; |
| 31 | 31 | |
| 32 | 32 | const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4; |
| ... | ... | @@ -152,10 +152,6 @@ export nakedcc fn _chkstk() align(4) { |
| 152 | 152 | @setGlobalLinkage(_chkstk, builtin.GlobalLinkage.Internal); |
| 153 | 153 | } |
| 154 | 154 | |
| 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`. | |
| 159 | 155 | export nakedcc fn __chkstk() align(4) { |
| 160 | 156 | @setDebugSafety(this, false); |
| 161 | 157 |
std/special/compiler_rt/udivmoddi4.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const udivmod = @import("udivmod.zig").udivmod; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 4 | |
| 5 | 5 | export fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 { |
| 6 | 6 | @setDebugSafety(this, builtin.is_test); |
std/special/compiler_rt/udivmodti4.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const udivmod = @import("udivmod.zig").udivmod; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 4 | |
| 5 | 5 | export fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 { |
| 6 | 6 | @setDebugSafety(this, builtin.is_test); |
std/special/compiler_rt/udivti3.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 4 | |
| 5 | 5 | export fn __udivti3(a: u128, b: u128) -> u128 { |
| 6 | 6 | @setDebugSafety(this, builtin.is_test); |
std/special/compiler_rt/umodti3.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4; |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const linkage = if (builtin.is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.LinkOnce; | |
| 3 | const linkage = @import("index.zig").linkage; | |
| 4 | 4 | |
| 5 | 5 | export fn __umodti3(a: u128, b: u128) -> u128 { |
| 6 | 6 | @setDebugSafety(this, builtin.is_test); |
test/behavior.zig+1| ... | ... | @@ -40,6 +40,7 @@ comptime { |
| 40 | 40 | _ = @import("cases/this.zig"); |
| 41 | 41 | _ = @import("cases/try.zig"); |
| 42 | 42 | _ = @import("cases/undefined.zig"); |
| 43 | _ = @import("cases/union.zig"); | |
| 43 | 44 | _ = @import("cases/var_args.zig"); |
| 44 | 45 | _ = @import("cases/void.zig"); |
| 45 | 46 | _ = @import("cases/while.zig"); |
test/cases/align.zig+1-1| ... | ... | @@ -188,6 +188,6 @@ test "alignstack" { |
| 188 | 188 | } |
| 189 | 189 | |
| 190 | 190 | fn fnWithAlignedStack() -> i32 { |
| 191 | @setAlignStack(1024); | |
| 191 | @setAlignStack(256); | |
| 192 | 192 | return 1234; |
| 193 | 193 | } |
test/cases/union.zig created+33| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | const assert = @import("std").debug.assert; | |
| 2 | ||
| 3 | const Value = enum { | |
| 4 | Int: u64, | |
| 5 | Array: [9]u8, | |
| 6 | }; | |
| 7 | ||
| 8 | const Agg = struct { | |
| 9 | val1: Value, | |
| 10 | val2: Value, | |
| 11 | }; | |
| 12 | ||
| 13 | const v1 = Value.Int { 1234 }; | |
| 14 | const v2 = Value.Array { []u8{3} ** 9 }; | |
| 15 | ||
| 16 | const err = (%Agg)(Agg { | |
| 17 | .val1 = v1, | |
| 18 | .val2 = v2, | |
| 19 | }); | |
| 20 | ||
| 21 | const array = []Value { v1, v2, v1, v2}; | |
| 22 | ||
| 23 | ||
| 24 | test "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 | 2187 | ".tmp_source.zig:3:5: error: alignstack set twice", |
| 2188 | 2188 | ".tmp_source.zig:2:5: note: first set here"); |
| 2189 | 2189 | |
| 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 | 2197 | cases.add("storing runtime value in compile time variable then using it", |
| 2191 | 2198 | \\const Mode = @import("builtin").Mode; |
| 2192 | 2199 | \\ |
| ... | ... | @@ -2231,4 +2238,41 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 2231 | 2238 | \\} |
| 2232 | 2239 | , |
| 2233 | 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 | } |