authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-03-31 05:48:15-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-03-31 05:55:41-04:00
log3ca027ca8219dbdbb6467645944c4daada037f51
tree786a6c4ecac9f11d3a60f3c14c1b4276a3adc8d6
parent536c35136ab98f2f56d07937727b3c99c0e35c5c

first pass at zig build system

* `zig build --export [obj|lib|exe]` changed to `zig build_obj`, `zig build_lib` and `zig build_exe` respectively. * `--name` parameter is optional when it can be inferred from the root source filename. closes #207 * `zig build` now looks for `build.zig` which interacts with `std.build.Builder` to describe the targets, and then the zig build system prints TODO: build these targets. See #204 * add `@bitcast` which is mainly used for pointer reinterpret casting and make explicit casting not do pointer reinterpretation. Closes #290 * fix debug info for byval parameters * sort command line help options * `std.debug.panic` supports format string printing * add `std.mem.IncrementingAllocator` * fix const ptr to a variable with data changing at runtime. closes #289

27 files changed, 475 insertions(+), 188 deletions(-)

CMakeLists.txt+2
......@@ -204,6 +204,7 @@ install(TARGETS zig DESTINATION bin)
204204
205205install(FILES ${C_HEADERS} DESTINATION ${C_HEADERS_DEST})
206206
207install(FILES "${CMAKE_SOURCE_DIR}/std/build.zig" DESTINATION "${ZIG_STD_DEST}")
207208install(FILES "${CMAKE_SOURCE_DIR}/std/c/darwin.zig" DESTINATION "${ZIG_STD_DEST}/c")
208209install(FILES "${CMAKE_SOURCE_DIR}/std/c/index.zig" DESTINATION "${ZIG_STD_DEST}/c")
209210install(FILES "${CMAKE_SOURCE_DIR}/std/c/linux.zig" DESTINATION "${ZIG_STD_DEST}/c")
......@@ -234,6 +235,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}")
234235install(FILES "${CMAKE_SOURCE_DIR}/std/rand_test.zig" DESTINATION "${ZIG_STD_DEST}")
235236install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")
236237install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special")
238install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")
237239install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special")
238240install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}/special")
239241install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")
README.md+2-3
......@@ -82,13 +82,12 @@ the Zig compiler itself:
8282 * gcc >= 5.0.0 or clang >= 3.6.0
8383 * cmake >= 2.8.5
8484
85#### Runtime Dependencies
85#### Library Dependencies
8686
8787These libraries must be installed on your system, with the development files
8888available. The Zig compiler dynamically links against them.
8989
90 * LLVM == 4.x
91 * libclang == 4.x
90 * LLVM, Clang, and LLD libraries == 4.x
9291
9392### Debug / Development Build
9493
doc/langref.md+7
......@@ -633,3 +633,10 @@ Invokes the panic handler function. By default the panic handler function
633633calls the public `panic` function exposed in the root source file, or
634634if there is not one specified, invokes the one provided in
635635`std/special/panic.zig`.
636
637### @bitcast(comptime DestType: type, value: var) -> DestType
638
639Transmutes memory from one type to another without changing any bits.
640The source and destination types must have the same size. This function
641can be used to, for example, reinterpret a pointer, or convert a `f32` to a
642`u32`.
src/all_types.hpp+5-3
......@@ -1196,6 +1196,7 @@ enum BuiltinFnId {
11961196 BuiltinFnIdSetGlobalSection,
11971197 BuiltinFnIdSetGlobalLinkage,
11981198 BuiltinFnIdPanic,
1199 BuiltinFnIdBitCast,
11991200};
12001201
12011202struct BuiltinFnEntry {
......@@ -1719,7 +1720,7 @@ enum IrInstructionId {
17191720 IrInstructionIdFnProto,
17201721 IrInstructionIdTestComptime,
17211722 IrInstructionIdInitEnum,
1722 IrInstructionIdPointerReinterpret,
1723 IrInstructionIdBitCast,
17231724 IrInstructionIdWidenOrShorten,
17241725 IrInstructionIdIntToPtr,
17251726 IrInstructionIdPtrToInt,
......@@ -2369,10 +2370,11 @@ struct IrInstructionInitEnum {
23692370 LLVMValueRef tmp_ptr;
23702371};
23712372
2372struct IrInstructionPointerReinterpret {
2373struct IrInstructionBitCast {
23732374 IrInstruction base;
23742375
2375 IrInstruction *ptr;
2376 IrInstruction *dest_type;
2377 IrInstruction *target;
23762378};
23772379
23782380struct IrInstructionWidenOrShorten {
src/analyze.cpp+1-1
......@@ -3355,7 +3355,6 @@ bool type_has_bits(TypeTableEntry *type_entry) {
33553355bool type_requires_comptime(TypeTableEntry *type_entry) {
33563356 switch (get_underlying_type(type_entry)->id) {
33573357 case TypeTableEntryIdInvalid:
3358 case TypeTableEntryIdUnreachable:
33593358 case TypeTableEntryIdVar:
33603359 case TypeTableEntryIdTypeDecl:
33613360 zig_unreachable();
......@@ -3383,6 +3382,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
33833382 case TypeTableEntryIdPointer:
33843383 case TypeTableEntryIdEnumTag:
33853384 case TypeTableEntryIdVoid:
3385 case TypeTableEntryIdUnreachable:
33863386 return false;
33873387 }
33883388 zig_unreachable();
src/codegen.cpp+15-8
......@@ -47,7 +47,7 @@ static void init_darwin_native(CodeGen *g) {
4747 }
4848}
4949
50static PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path) {
50PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path) {
5151 PackageTableEntry *entry = allocate<PackageTableEntry>(1);
5252 entry->package_table.init(4);
5353 buf_init_from_str(&entry->root_src_dir, root_src_dir);
......@@ -1345,12 +1345,12 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
13451345 zig_unreachable();
13461346}
13471347
1348static LLVMValueRef ir_render_pointer_reinterpret(CodeGen *g, IrExecutable *executable,
1349 IrInstructionPointerReinterpret *instruction)
1348static LLVMValueRef ir_render_bitcast(CodeGen *g, IrExecutable *executable,
1349 IrInstructionBitCast *instruction)
13501350{
13511351 TypeTableEntry *wanted_type = instruction->base.value.type;
1352 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
1353 return LLVMBuildBitCast(g->builder, ptr, wanted_type->type_ref, "");
1352 LLVMValueRef target = ir_llvm_value(g, instruction->target);
1353 return LLVMBuildBitCast(g->builder, target, wanted_type->type_ref, "");
13541354}
13551355
13561356static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable,
......@@ -2776,8 +2776,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
27762776 return ir_render_init_enum(g, executable, (IrInstructionInitEnum *)instruction);
27772777 case IrInstructionIdStructInit:
27782778 return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction);
2779 case IrInstructionIdPointerReinterpret:
2780 return ir_render_pointer_reinterpret(g, executable, (IrInstructionPointerReinterpret *)instruction);
2779 case IrInstructionIdBitCast:
2780 return ir_render_bitcast(g, executable, (IrInstructionBitCast *)instruction);
27812781 case IrInstructionIdWidenOrShorten:
27822782 return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction);
27832783 case IrInstructionIdPtrToInt:
......@@ -3638,8 +3638,14 @@ static void do_code_gen(CodeGen *g) {
36383638 } else {
36393639 assert(var->gen_arg_index != SIZE_MAX);
36403640 TypeTableEntry *gen_type;
3641 FnGenParamInfo *gen_info = &fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index];
3642
36413643 if (handle_is_ptr(var->value->type)) {
3642 gen_type = fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index].type;
3644 if (gen_info->is_byval) {
3645 gen_type = var->value->type;
3646 } else {
3647 gen_type = gen_info->type;
3648 }
36433649 var->value_ref = LLVMGetParam(fn, var->gen_arg_index);
36443650 } else {
36453651 gen_type = var->value->type;
......@@ -4254,6 +4260,7 @@ static void define_builtin_fns(CodeGen *g) {
42544260 create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
42554261 create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2);
42564262 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
4263 create_builtin_fn(g, BuiltinFnIdBitCast, "bitcast", 2);
42574264}
42584265
42594266static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) {
src/codegen.hpp+1
......@@ -45,6 +45,7 @@ void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min);
4545void codegen_set_linker_script(CodeGen *g, const char *linker_script);
4646void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt);
4747
48PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path);
4849void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);
4950
5051void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code);
src/ir.cpp+76-59
......@@ -480,8 +480,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionInitEnum *) {
480480 return IrInstructionIdInitEnum;
481481}
482482
483static constexpr IrInstructionId ir_instruction_id(IrInstructionPointerReinterpret *) {
484 return IrInstructionIdPointerReinterpret;
483static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) {
484 return IrInstructionIdBitCast;
485485}
486486
487487static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) {
......@@ -1940,14 +1940,16 @@ static IrInstruction *ir_build_init_enum_from(IrBuilder *irb, IrInstruction *old
19401940 return new_instruction;
19411941}
19421942
1943static IrInstruction *ir_build_pointer_reinterpret(IrBuilder *irb, Scope *scope, AstNode *source_node,
1944 IrInstruction *ptr)
1943static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
1944 IrInstruction *dest_type, IrInstruction *target)
19451945{
1946 IrInstructionPointerReinterpret *instruction = ir_build_instruction<IrInstructionPointerReinterpret>(
1946 IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>(
19471947 irb, scope, source_node);
1948 instruction->ptr = ptr;
1948 instruction->dest_type = dest_type;
1949 instruction->target = target;
19491950
1950 ir_ref_instruction(ptr, irb->current_basic_block);
1951 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block);
1952 ir_ref_instruction(target, irb->current_basic_block);
19511953
19521954 return &instruction->base;
19531955}
......@@ -2664,11 +2666,12 @@ static IrInstruction *ir_instruction_initenum_get_dep(IrInstructionInitEnum *ins
26642666 }
26652667}
26662668
2667static IrInstruction *ir_instruction_pointerreinterpret_get_dep(IrInstructionPointerReinterpret *instruction,
2669static IrInstruction *ir_instruction_bitcast_get_dep(IrInstructionBitCast *instruction,
26682670 size_t index)
26692671{
26702672 switch (index) {
2671 case 0: return instruction->ptr;
2673 case 0: return instruction->dest_type;
2674 case 1: return instruction->target;
26722675 default: return nullptr;
26732676 }
26742677}
......@@ -2925,8 +2928,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
29252928 return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index);
29262929 case IrInstructionIdInitEnum:
29272930 return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index);
2928 case IrInstructionIdPointerReinterpret:
2929 return ir_instruction_pointerreinterpret_get_dep((IrInstructionPointerReinterpret *) instruction, index);
2931 case IrInstructionIdBitCast:
2932 return ir_instruction_bitcast_get_dep((IrInstructionBitCast *) instruction, index);
29302933 case IrInstructionIdWidenOrShorten:
29312934 return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index);
29322935 case IrInstructionIdIntToPtr:
......@@ -4197,6 +4200,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41974200
41984201 return ir_build_panic(irb, scope, node, arg0_value);
41994202 }
4203 case BuiltinFnIdBitCast:
4204 {
4205 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4206 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4207 if (arg0_value == irb->codegen->invalid_instruction)
4208 return arg0_value;
4209
4210 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4211 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4212 if (arg1_value == irb->codegen->invalid_instruction)
4213 return arg1_value;
4214
4215 return ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value);
4216 }
42004217 }
42014218 zig_unreachable();
42024219}
......@@ -6364,34 +6381,6 @@ static IrInstruction *ir_analyze_maybe_wrap(IrAnalyze *ira, IrInstruction *sourc
63646381 return result;
63656382}
63666383
6367static IrInstruction *ir_analyze_pointer_reinterpret(IrAnalyze *ira, IrInstruction *source_instr,
6368 IrInstruction *ptr, TypeTableEntry *wanted_type)
6369{
6370 if (ptr->value.type->id != TypeTableEntryIdPointer &&
6371 ptr->value.type->id != TypeTableEntryIdMaybe)
6372 {
6373 ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&ptr->value.type->name)));
6374 return ira->codegen->invalid_instruction;
6375 }
6376
6377 if (instr_is_comptime(ptr)) {
6378 ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk);
6379 if (!val)
6380 return ira->codegen->invalid_instruction;
6381
6382 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
6383 source_instr->scope, source_instr->source_node);
6384 const_instruction->base.value = *val;
6385 const_instruction->base.value.type = wanted_type;
6386 return &const_instruction->base;
6387 }
6388
6389 IrInstruction *result = ir_build_pointer_reinterpret(&ira->new_irb, source_instr->scope,
6390 source_instr->source_node, ptr);
6391 result->value.type = wanted_type;
6392 return result;
6393}
6394
63956384static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr,
63966385 IrInstruction *value, TypeTableEntry *wanted_type)
63976386{
......@@ -6829,24 +6818,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
68296818 }
68306819 }
68316820
6832 // explicit cast from pointer to another pointer
6833 if ((actual_type->id == TypeTableEntryIdPointer || actual_type->id == TypeTableEntryIdFn) &&
6834 (wanted_type->id == TypeTableEntryIdPointer || wanted_type->id == TypeTableEntryIdFn))
6835 {
6836 return ir_analyze_pointer_reinterpret(ira, source_instr, value, wanted_type);
6837 }
6838
6839 // explicit cast from maybe pointer to another maybe pointer
6840 if (actual_type->id == TypeTableEntryIdMaybe &&
6841 (actual_type->data.maybe.child_type->id == TypeTableEntryIdPointer ||
6842 actual_type->data.maybe.child_type->id == TypeTableEntryIdFn) &&
6843 wanted_type->id == TypeTableEntryIdMaybe &&
6844 (wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer ||
6845 wanted_type->data.maybe.child_type->id == TypeTableEntryIdFn))
6846 {
6847 return ir_analyze_pointer_reinterpret(ira, source_instr, value, wanted_type);
6848 }
6849
68506821 // explicit cast from child type of maybe type to maybe type
68516822 if (wanted_type->id == TypeTableEntryIdMaybe) {
68526823 if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) {
......@@ -8986,6 +8957,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
89868957
89878958 ConstExprValue *array_ptr_val;
89888959 if (array_ptr->value.special != ConstValSpecialRuntime &&
8960 array_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar &&
89898961 (array_ptr_val = const_ptr_pointee(&array_ptr->value)) &&
89908962 array_ptr_val->special != ConstValSpecialRuntime &&
89918963 (array_type->id != TypeTableEntryIdPointer ||
......@@ -12210,6 +12182,50 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio
1221012182 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
1221112183}
1221212184
12185static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) {
12186 IrInstruction *dest_type_value = instruction->dest_type->other;
12187 TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value);
12188 if (type_is_invalid(dest_type))
12189 return ira->codegen->builtin_types.entry_invalid;
12190
12191 IrInstruction *target = instruction->target->other;
12192 TypeTableEntry *src_type = target->value.type;
12193 if (type_is_invalid(src_type))
12194 return ira->codegen->builtin_types.entry_invalid;
12195
12196 ensure_complete_type(ira->codegen, dest_type);
12197 ensure_complete_type(ira->codegen, src_type);
12198
12199 uint64_t dest_size_bytes = type_size(ira->codegen, dest_type);
12200 uint64_t src_size_bytes = type_size(ira->codegen, src_type);
12201 if (dest_size_bytes != src_size_bytes) {
12202 ir_add_error(ira, &instruction->base,
12203 buf_sprintf("destination type '%s' has size %" PRIu64 " but source type '%s' has size %" PRIu64,
12204 buf_ptr(&dest_type->name), dest_size_bytes,
12205 buf_ptr(&src_type->name), src_size_bytes));
12206 return ira->codegen->builtin_types.entry_invalid;
12207 }
12208
12209 if (instr_is_comptime(target) && src_type->id == dest_type->id &&
12210 (src_type->id == TypeTableEntryIdPointer || src_type->id == TypeTableEntryIdMaybe))
12211 {
12212 ConstExprValue *val = ir_resolve_const(ira, target, UndefOk);
12213 if (!val)
12214 return ira->codegen->builtin_types.entry_invalid;
12215
12216 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
12217 *out_val = *val;
12218 out_val->type = dest_type;
12219 return dest_type;
12220 }
12221
12222 IrInstruction *result = ir_build_bit_cast(&ira->new_irb, instruction->base.scope,
12223 instruction->base.source_node, nullptr, target);
12224 ir_link_new_instruction(result, &instruction->base);
12225 result->value.type = dest_type;
12226 return dest_type;
12227}
12228
1221312229static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
1221412230 IrInstructionDeclRef *instruction)
1221512231{
......@@ -12283,7 +12299,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
1228312299static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
1228412300 switch (instruction->id) {
1228512301 case IrInstructionIdInvalid:
12286 case IrInstructionIdPointerReinterpret:
1228712302 case IrInstructionIdWidenOrShorten:
1228812303 case IrInstructionIdIntToPtr:
1228912304 case IrInstructionIdPtrToInt:
......@@ -12449,6 +12464,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1244912464 return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction);
1245012465 case IrInstructionIdPanic:
1245112466 return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);
12467 case IrInstructionIdBitCast:
12468 return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction);
1245212469 case IrInstructionIdMaybeWrap:
1245312470 case IrInstructionIdErrWrapCode:
1245412471 case IrInstructionIdErrWrapPayload:
......@@ -12620,7 +12637,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1262012637 case IrInstructionIdFnProto:
1262112638 case IrInstructionIdTestComptime:
1262212639 case IrInstructionIdInitEnum:
12623 case IrInstructionIdPointerReinterpret:
12640 case IrInstructionIdBitCast:
1262412641 case IrInstructionIdWidenOrShorten:
1262512642 case IrInstructionIdPtrToInt:
1262612643 case IrInstructionIdIntToPtr:
src/ir_print.cpp+5-5
......@@ -765,9 +765,9 @@ static void ir_print_init_enum(IrPrint *irp, IrInstructionInitEnum *instruction)
765765 fprintf(irp->f, "}");
766766}
767767
768static void ir_print_pointer_reinterpret(IrPrint *irp, IrInstructionPointerReinterpret *instruction) {
769 fprintf(irp->f, "@pointerReinterpret(");
770 ir_print_other_instruction(irp, instruction->ptr);
768static void ir_print_bit_cast(IrPrint *irp, IrInstructionBitCast *instruction) {
769 fprintf(irp->f, "@bitcast(");
770 ir_print_other_instruction(irp, instruction->target);
771771 fprintf(irp->f, ")");
772772}
773773
......@@ -1098,8 +1098,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
10981098 case IrInstructionIdInitEnum:
10991099 ir_print_init_enum(irp, (IrInstructionInitEnum *)instruction);
11001100 break;
1101 case IrInstructionIdPointerReinterpret:
1102 ir_print_pointer_reinterpret(irp, (IrInstructionPointerReinterpret *)instruction);
1101 case IrInstructionIdBitCast:
1102 ir_print_bit_cast(irp, (IrInstructionBitCast *)instruction);
11031103 break;
11041104 case IrInstructionIdWidenOrShorten:
11051105 ir_print_widen_or_shorten(irp, (IrInstructionWidenOrShorten *)instruction);
src/main.cpp+110-52
......@@ -19,46 +19,48 @@
1919static int usage(const char *arg0) {
2020 fprintf(stderr, "Usage: %s [command] [options]\n"
2121 "Commands:\n"
22 " build [sources] create executable, object, or library from source\n"
23 " test [sources] create and run a test build\n"
22 " build build project from build.zig\n"
23 " build_exe [source] create executable from source\n"
24 " build_lib [source] create library from source\n"
25 " build_obj [source] create object from source\n"
2426 " parseh [source] convert a c header file to zig extern declarations\n"
25 " version print version number and exit\n"
2627 " targets list available compilation targets\n"
28 " test [source] create and run a test build\n"
29 " version print version number and exit\n"
2730 "Options:\n"
28 " --release build with optimizations on and debug protection off\n"
29 " --static output will be statically linked\n"
30 " --strip exclude debug symbols\n"
31 " --export [exe|lib|obj] override output type\n"
32 " --name [name] override output name\n"
33 " --output [file] override destination path\n"
34 " --verbose turn on compiler debug output\n"
31 " --ar-path [path] set the path to ar\n"
3532 " --color [auto|off|on] enable or disable colored error messages\n"
36 " --libc-lib-dir [path] directory where libc crt1.o resides\n"
37 " --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n"
38 " --libc-include-dir [path] directory where libc stdlib.h resides\n"
39 " --zig-std-dir [path] directory where zig standard library resides\n"
4033 " --dynamic-linker [path] set the path to ld.so\n"
34 " --each-lib-rpath add rpath for each used dynamic library\n"
4135 " --ld-path [path] set the path to the linker\n"
42 " --ar-path [path] set the path to ar\n"
43 " -isystem [dir] add additional search path for other .h files\n"
44 " -dirafter [dir] same as -isystem but do it last\n"
45 " --library-path [dir] add a directory to the library search path\n"
46 " -L[dir] alias for --library-path\n"
36 " --libc-include-dir [path] directory where libc stdlib.h resides\n"
37 " --libc-lib-dir [path] directory where libc crt1.o resides\n"
38 " --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n"
4739 " --library [lib] link against lib\n"
40 " --library-path [dir] add a directory to the library search path\n"
41 " --linker-script [path] use a custom linker script\n"
42 " --name [name] override output name\n"
43 " --output [file] override destination path\n"
44 " --release build with optimizations on and debug protection off\n"
45 " --static output will be statically linked\n"
46 " --strip exclude debug symbols\n"
4847 " --target-arch [name] specify target architecture\n"
49 " --target-os [name] specify target operating system\n"
5048 " --target-environ [name] specify target environment\n"
51 " -mwindows (windows only) --subsystem windows to the linker\n"
49 " --target-os [name] specify target operating system\n"
50 " --verbose turn on compiler debug output\n"
51 " --zig-std-dir [path] directory where zig standard library resides\n"
52 " -L[dir] alias for --library-path\n"
53 " -dirafter [dir] same as -isystem but do it last\n"
54 " -framework [name] (darwin only) link against framework\n"
55 " -isystem [dir] add additional search path for other .h files\n"
5256 " -mconsole (windows only) --subsystem console to the linker\n"
53 " -municode (windows only) link with unicode\n"
57 " -mios-version-min [ver] (darwin only) set iOS deployment target\n"
5458 " -mlinker-version [ver] (darwin only) override linker version\n"
55 " -rdynamic add all symbols to the dynamic symbol table\n"
5659 " -mmacosx-version-min [ver] (darwin only) set Mac OS X deployment target\n"
57 " -mios-version-min [ver] (darwin only) set iOS deployment target\n"
58 " -framework [name] (darwin only) link against framework\n"
59 " --linker-script [path] use a custom linker script\n"
60 " -municode (windows only) link with unicode\n"
61 " -mwindows (windows only) --subsystem windows to the linker\n"
62 " -rdynamic add all symbols to the dynamic symbol table\n"
6063 " -rpath [path] add directory to the runtime library search path\n"
61 " --each-lib-rpath add rpath for each used dynamic library\n"
6264 , arg0);
6365 return EXIT_FAILURE;
6466}
......@@ -144,6 +146,62 @@ int main(int argc, char **argv) {
144146 ZigList<const char *> rpath_list = {0};
145147 bool each_lib_rpath = false;
146148
149 if (argc >= 2 && strcmp(argv[1], "build") == 0) {
150 const char *zig_exe_path = arg0;
151
152 init_all_targets();
153
154 Buf *zig_std_dir = buf_create_from_str(ZIG_STD_DIR);
155 Buf *special_dir = buf_alloc();
156 os_path_join(zig_std_dir, buf_sprintf("special"), special_dir);
157
158 Buf *build_runner_path = buf_alloc();
159 os_path_join(special_dir, buf_create_from_str("build_runner.zig"), build_runner_path);
160
161 ZigList<const char *> args = {0};
162 args.append(zig_exe_path);
163 for (int i = 2; i < argc; i += 1) {
164 if (strcmp(argv[i], "--verbose") == 0) {
165 verbose = true;
166 args.append(argv[i]);
167 } else {
168 args.append(argv[i]);
169 }
170 }
171
172
173 Buf root_source_dir = BUF_INIT;
174 Buf root_source_code = BUF_INIT;
175 Buf root_source_name = BUF_INIT;
176 os_path_split(build_runner_path, &root_source_dir, &root_source_name);
177 if ((err = os_fetch_file_path(build_runner_path, &root_source_code))) {
178 fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(build_runner_path), err_str(err));
179 return 1;
180 }
181 CodeGen *g = codegen_create(&root_source_dir, nullptr);
182 codegen_set_out_name(g, buf_create_from_str("build"));
183 codegen_set_out_type(g, OutTypeExe);
184 codegen_set_verbose(g, verbose);
185
186 PackageTableEntry *build_pkg = new_package(".", "build.zig");
187 build_pkg->package_table.put(buf_create_from_str("std"), g->std_package);
188 g->root_package->package_table.put(buf_create_from_str("@build"), build_pkg);
189 codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code);
190 codegen_link(g, "build");
191
192 Termination term;
193 os_spawn_process("./build", args, &term);
194 if (term.how != TerminationIdClean || term.code != 0) {
195 fprintf(stderr, "\nBuild failed. Use the following command to reproduce the failure:\n");
196 fprintf(stderr, "./build");
197 for (size_t i = 0; i < args.length; i += 1) {
198 fprintf(stderr, " \"%s\"", args.at(i));
199 }
200 fprintf(stderr, "\n");
201 }
202 return (term.how == TerminationIdClean) ? term.code : -1;
203 }
204
147205 for (int i = 1; i < argc; i += 1) {
148206 char *arg = argv[i];
149207
......@@ -177,16 +235,6 @@ int main(int argc, char **argv) {
177235 return usage(arg0);
178236 } else if (strcmp(arg, "--output") == 0) {
179237 out_file = argv[i];
180 } else if (strcmp(arg, "--export") == 0) {
181 if (strcmp(argv[i], "exe") == 0) {
182 out_type = OutTypeExe;
183 } else if (strcmp(argv[i], "lib") == 0) {
184 out_type = OutTypeLib;
185 } else if (strcmp(argv[i], "obj") == 0) {
186 out_type = OutTypeObj;
187 } else {
188 return usage(arg0);
189 }
190238 } else if (strcmp(arg, "--color") == 0) {
191239 if (strcmp(argv[i], "auto") == 0) {
192240 color = ErrColorAuto;
......@@ -243,8 +291,15 @@ int main(int argc, char **argv) {
243291 }
244292 }
245293 } else if (cmd == CmdInvalid) {
246 if (strcmp(arg, "build") == 0) {
294 if (strcmp(arg, "build_exe") == 0) {
295 cmd = CmdBuild;
296 out_type = OutTypeExe;
297 } else if (strcmp(arg, "build_obj") == 0) {
247298 cmd = CmdBuild;
299 out_type = OutTypeObj;
300 } else if (strcmp(arg, "build_lib") == 0) {
301 cmd = CmdBuild;
302 out_type = OutTypeLib;
248303 } else if (strcmp(arg, "version") == 0) {
249304 cmd = CmdVersion;
250305 } else if (strcmp(arg, "parseh") == 0) {
......@@ -285,15 +340,7 @@ int main(int argc, char **argv) {
285340 if (!in_file)
286341 return usage(arg0);
287342
288 if (cmd == CmdBuild && !out_name) {
289 fprintf(stderr, "--name [name] not provided\n\n");
290 return usage(arg0);
291 }
292
293 if (cmd == CmdBuild && out_type == OutTypeUnknown) {
294 fprintf(stderr, "--export [exe|lib|obj] not provided\n\n");
295 return usage(arg0);
296 }
343 assert(cmd != CmdBuild || out_type != OutTypeUnknown);
297344
298345 init_all_targets();
299346
......@@ -331,6 +378,9 @@ int main(int argc, char **argv) {
331378 Buf root_source_dir = BUF_INIT;
332379 Buf root_source_code = BUF_INIT;
333380 Buf root_source_name = BUF_INIT;
381
382 Buf *buf_out_name = (cmd == CmdTest) ? buf_create_from_str("test") :
383 (out_name == nullptr) ? nullptr : buf_create_from_str(out_name);
334384 if (buf_eql_str(&in_file_buf, "-")) {
335385 os_get_cwd(&root_source_dir);
336386 if ((err = os_fetch_file(stdin, &root_source_code))) {
......@@ -338,12 +388,24 @@ int main(int argc, char **argv) {
338388 return 1;
339389 }
340390 buf_init_from_str(&root_source_name, "");
391
341392 } else {
342393 os_path_split(&in_file_buf, &root_source_dir, &root_source_name);
343394 if ((err = os_fetch_file_path(buf_create_from_str(in_file), &root_source_code))) {
344395 fprintf(stderr, "unable to open '%s': %s\n", in_file, err_str(err));
345396 return 1;
346397 }
398
399 if (cmd == CmdBuild && buf_out_name == nullptr) {
400 buf_out_name = buf_alloc();
401 Buf ext_name = BUF_INIT;
402 os_path_extname(&root_source_name, buf_out_name, &ext_name);
403 }
404 }
405
406 if (cmd == CmdBuild && buf_out_name == nullptr) {
407 fprintf(stderr, "--name [name] not provided and unable to infer\n\n");
408 return usage(arg0);
347409 }
348410
349411 CodeGen *g = codegen_create(&root_source_dir, target);
......@@ -361,11 +423,7 @@ int main(int argc, char **argv) {
361423 } else if (cmd == CmdTest) {
362424 codegen_set_out_type(g, OutTypeExe);
363425 }
364 if (out_name) {
365 codegen_set_out_name(g, buf_create_from_str(out_name));
366 } else if (cmd == CmdTest) {
367 codegen_set_out_name(g, buf_create_from_str("test"));
368 }
426 codegen_set_out_name(g, buf_out_name);
369427 if (libc_lib_dir)
370428 codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir));
371429 if (libc_static_lib_dir)
src/os.cpp+26
......@@ -139,6 +139,32 @@ void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename) {
139139 if (out_basename) buf_init_from_buf(out_basename, full_path);
140140}
141141
142void os_path_extname(Buf *full_path, Buf *out_basename, Buf *out_extname) {
143 if (buf_len(full_path) == 0) {
144 buf_init_from_str(out_basename, "");
145 buf_init_from_str(out_extname, "");
146 return;
147 }
148 size_t i = buf_len(full_path) - 1;
149 while (true) {
150 if (buf_ptr(full_path)[i] == '.') {
151 buf_resize(out_basename, 0);
152 buf_append_mem(out_basename, buf_ptr(full_path), i);
153
154 buf_resize(out_extname, 0);
155 buf_append_mem(out_extname, buf_ptr(full_path) + i, buf_len(full_path) - i);
156 return;
157 }
158
159 if (i == 0) {
160 buf_init_from_buf(out_basename, full_path);
161 buf_init_from_str(out_extname, "");
162 return;
163 }
164 i -= 1;
165 }
166}
167
142168void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path) {
143169 buf_init_from_buf(out_full_path, dirname);
144170 uint8_t c = *(buf_ptr(out_full_path) + buf_len(out_full_path) - 1);
src/os.hpp+1
......@@ -34,6 +34,7 @@ int os_exec_process(const char *exe, ZigList<const char *> &args,
3434
3535void os_path_dirname(Buf *full_path, Buf *out_dirname);
3636void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename);
37void os_path_extname(Buf *full_path, Buf *out_basename, Buf *out_extname);
3738void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path);
3839int os_path_real(Buf *rel_path, Buf *out_abs_path);
3940void os_path_resolve(Buf *ref_path, Buf *target_path, Buf *out_abs_path);
std/build.zig created+59
......@@ -0,0 +1,59 @@
1const io = @import("io.zig");
2const mem = @import("mem.zig");
3const debug = @import("debug.zig");
4const List = @import("list.zig").List;
5const Allocator = @import("mem.zig").Allocator;
6
7error ExtraArg;
8
9pub const Builder = struct {
10 zig_exe: []const u8,
11 allocator: &Allocator,
12 exe_list: List(&Exe),
13
14 pub fn init(zig_exe: []const u8, allocator: &Allocator) -> Builder {
15 Builder {
16 .zig_exe = zig_exe,
17 .allocator = allocator,
18 .exe_list = List(&Exe).init(allocator),
19 }
20 }
21
22 pub fn addExe(self: &Builder, root_src: []const u8, name: []const u8) -> &Exe {
23 return self.addExeErr(root_src, name) %% |err| handleErr(err);
24 }
25
26 pub fn addExeErr(self: &Builder, root_src: []const u8, name: []const u8) -> %&Exe {
27 const exe = %return self.allocator.create(Exe);
28 *exe = Exe {
29 .root_src = root_src,
30 .name = name,
31 };
32 %return self.exe_list.append(exe);
33 return exe;
34 }
35
36 pub fn make(self: &Builder, args: []const []const u8) -> %void {
37 var verbose = false;
38 for (args) |arg| {
39 if (mem.eql(u8, arg, "--verbose")) {
40 verbose = true;
41 } else {
42 %%io.stderr.printf("Unrecognized argument: '{}'\n", arg);
43 return error.ExtraArg;
44 }
45 }
46 for (self.exe_list.toSlice()) |exe| {
47 %%io.stderr.printf("TODO: invoke this command:\nzig build_exe {} --name {}\n", exe.root_src, exe.name);
48 }
49 }
50};
51
52const Exe = struct {
53 root_src: []const u8,
54 name: []const u8,
55};
56
57fn handleErr(err: error) -> noreturn {
58 debug.panic("error: {}\n", @errorName(err));
59}
std/debug.zig+3-4
......@@ -15,7 +15,7 @@ pub fn assert(ok: bool) {
1515
1616var panicking = false;
1717/// This is the default panic implementation.
18pub coldcc fn panic(message: []const u8) -> noreturn {
18pub coldcc fn panic(comptime format: []const u8, args: ...) -> noreturn {
1919 // TODO
2020 // if (@atomicRmw(AtomicOp.XChg, &panicking, true, AtomicOrder.SeqCst)) { }
2121 if (panicking) {
......@@ -28,7 +28,7 @@ pub coldcc fn panic(message: []const u8) -> noreturn {
2828 panicking = true;
2929 }
3030
31 %%io.stderr.printf("{}\n", message);
31 %%io.stderr.printf(format, args);
3232 %%printStackTrace();
3333
3434 os.abort();
......@@ -74,7 +74,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void {
7474 const name = %return compile_unit.die.getAttrString(st, DW.AT_name);
7575
7676 %return out_stream.printf("{} -> {}\n", return_address, name);
77 maybe_fp = *(&const ?&const u8)(fp);
77 maybe_fp = *@bitcast(&const ?&const u8, fp);
7878 }
7979 },
8080 ObjectFormat.coff => {
......@@ -511,7 +511,6 @@ pub var global_allocator = mem.Allocator {
511511 .allocFn = globalAlloc,
512512 .reallocFn = globalRealloc,
513513 .freeFn = globalFree,
514 .context = null,
515514};
516515
517516var some_mem: [100 * 1024]u8 = undefined;
std/hash_map.zig+1-1
......@@ -236,7 +236,7 @@ test "basicHashMapTest" {
236236}
237237
238238fn hash_i32(x: i32) -> u32 {
239 *(&u32)(&x)
239 *@bitcast(&u32, &x)
240240}
241241fn eql_i32(a: i32, b: i32) -> bool {
242242 a == b
std/index.zig+1
......@@ -1,3 +1,4 @@
1pub const build = @import("build.zig");
12pub const c = @import("c/index.zig");
23pub const cstr = @import("cstr.zig");
34pub const debug = @import("debug.zig");
std/mem.zig+64-2
......@@ -7,12 +7,10 @@ pub const Cmp = math.Cmp;
77
88error NoMem;
99
10pub type Context = u8;
1110pub const Allocator = struct {
1211 allocFn: fn (self: &Allocator, n: usize) -> %[]u8,
1312 reallocFn: fn (self: &Allocator, old_mem: []u8, new_size: usize) -> %[]u8,
1413 freeFn: fn (self: &Allocator, mem: []u8),
15 context: ?&Context,
1614
1715 /// Aborts the program if an allocation fails.
1816 fn checkedAlloc(self: &Allocator, comptime T: type, n: usize) -> []T {
......@@ -22,6 +20,14 @@ pub const Allocator = struct {
2220 }
2321 }
2422
23 fn create(self: &Allocator, comptime T: type) -> %&T {
24 &(%return self.alloc(T, 1))[0]
25 }
26
27 fn destroy(self: &Allocator, ptr: var) {
28 self.free(ptr[0...1]);
29 }
30
2531 fn alloc(self: &Allocator, comptime T: type, n: usize) -> %[]T {
2632 const byte_count = %return math.mulOverflow(usize, @sizeOf(T), n);
2733 ([]T)(%return self.allocFn(self, byte_count))
......@@ -37,6 +43,62 @@ pub const Allocator = struct {
3743 }
3844};
3945
46pub const IncrementingAllocator = struct {
47 allocator: Allocator,
48 bytes: []u8,
49 end_index: usize,
50
51 fn init(capacity: usize) -> %IncrementingAllocator {
52 switch (@compileVar("os")) {
53 Os.linux, Os.darwin, Os.macosx, Os.ios => {
54 const p = os.posix;
55 const addr = p.mmap(null, capacity, p.PROT_READ|p.PROT_WRITE,
56 p.MAP_PRIVATE|p.MAP_ANONYMOUS|p.MAP_NORESERVE, -1, 0);
57 if (addr == p.MAP_FAILED) {
58 return error.NoMem;
59 }
60 return IncrementingAllocator {
61 .allocator = Allocator {
62 .allocFn = alloc,
63 .reallocFn = realloc,
64 .freeFn = free,
65 },
66 .bytes = (&u8)(addr)[0...capacity],
67 .end_index = 0,
68 };
69 },
70 else => @compileError("Unsupported OS"),
71 }
72 }
73
74 fn deinit(self: &IncrementingAllocator) {
75 _ = os.posix.munmap(self.bytes.ptr, self.bytes.len);
76 }
77
78 fn alloc(allocator: &Allocator, n: usize) -> %[]u8 {
79 // TODO
80 //const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator);
81 const self = @bitcast(&IncrementingAllocator, allocator);
82 const new_end_index = self.end_index + n;
83 if (new_end_index > self.bytes.len) {
84 return error.NoMem;
85 }
86 const result = self.bytes[self.end_index...new_end_index];
87 self.end_index = new_end_index;
88 return result;
89 }
90
91 fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize) -> %[]u8 {
92 const result = %return alloc(allocator, new_size);
93 copy(u8, result, old_mem);
94 return result;
95 }
96
97 fn free(allocator: &Allocator, bytes: []u8) {
98 // Do nothing. That's the point of an incrementing allocator.
99 }
100};
101
40102/// Copy all of source into dest at position 0.
41103/// dest.len must be >= source.len.
42104pub fn copy(comptime T: type, dest: []T, source: []const T) {
std/os/linux.zig+24-11
......@@ -5,16 +5,29 @@ const arch = switch (@compileVar("arch")) {
55};
66const errno = @import("errno.zig");
77
8pub const MMAP_PROT_NONE = 0;
9pub const MMAP_PROT_READ = 1;
10pub const MMAP_PROT_WRITE = 2;
11pub const MMAP_PROT_EXEC = 4;
12
13pub const MMAP_MAP_FILE = 0;
14pub const MMAP_MAP_SHARED = 1;
15pub const MMAP_MAP_PRIVATE = 2;
16pub const MMAP_MAP_FIXED = 16;
17pub const MMAP_MAP_ANON = 32;
8pub const PROT_NONE = 0;
9pub const PROT_READ = 1;
10pub const PROT_WRITE = 2;
11pub const PROT_EXEC = 4;
12pub const PROT_GROWSDOWN = 0x01000000;
13pub const PROT_GROWSUP = 0x02000000;
14
15pub const MAP_FAILED = @maxValue(usize);
16pub const MAP_SHARED = 0x01;
17pub const MAP_PRIVATE = 0x02;
18pub const MAP_TYPE = 0x0f;
19pub const MAP_FIXED = 0x10;
20pub const MAP_ANONYMOUS = 0x20;
21pub const MAP_NORESERVE = 0x4000;
22pub const MAP_GROWSDOWN = 0x0100;
23pub const MAP_DENYWRITE = 0x0800;
24pub const MAP_EXECUTABLE = 0x1000;
25pub const MAP_LOCKED = 0x2000;
26pub const MAP_POPULATE = 0x8000;
27pub const MAP_NONBLOCK = 0x10000;
28pub const MAP_STACK = 0x20000;
29pub const MAP_HUGETLB = 0x40000;
30pub const MAP_FILE = 0;
1831
1932pub const SIGHUP = 1;
2033pub const SIGINT = 2;
......@@ -226,7 +239,7 @@ pub const AF_MAX = PF_MAX;
226239
227240/// Get the errno from a syscall return value, or 0 for no error.
228241pub fn getErrno(r: usize) -> usize {
229 const signed_r = *(&isize)(&r);
242 const signed_r = *@bitcast(&isize, &r);
230243 if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0
231244}
232245
std/special/build_runner.zig created+18
......@@ -0,0 +1,18 @@
1const root = @import("@build");
2const std = @import("std");
3const io = std.io;
4const Builder = std.build.Builder;
5const mem = std.mem;
6
7pub fn main(args: [][]u8) -> %void {
8 const zig_exe = args[1];
9 const leftover_args = args[2...];
10
11 // TODO use a more general purpose allocator here
12 var inc_allocator = %%mem.IncrementingAllocator.init(10 * 1024 * 1024);
13 defer inc_allocator.deinit();
14
15 var builder = Builder.init(zig_exe, &inc_allocator.allocator);
16 root.build(&builder);
17 %return builder.make(leftover_args);
18}
std/special/compiler_rt.zig+12-12
......@@ -15,7 +15,7 @@ export fn __udivdi3(a: du_int, b: du_int) -> du_int {
1515
1616fn du_int_to_udwords(x: du_int) -> udwords {
1717 @setDebugSafety(this, false);
18 return *(&udwords)(&x);
18 return *@bitcast(&udwords, &x);
1919}
2020
2121export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
......@@ -66,7 +66,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
6666 if (var rem ?= maybe_rem) {
6767 r[high] = n[high] % d[high];
6868 r[low] = 0;
69 *rem = *(&du_int)(&r[0]);
69 *rem = *@bitcast(&du_int, &r[0]);
7070 }
7171 return n[high] / d[high];
7272 }
......@@ -78,7 +78,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
7878 if (var rem ?= maybe_rem) {
7979 r[low] = n[low];
8080 r[high] = n[high] & (d[high] - 1);
81 *rem = *(&du_int)(&r[0]);
81 *rem = *@bitcast(&du_int, &r[0]);
8282 }
8383 return n[high] >> @ctz(d[high]);
8484 }
......@@ -89,7 +89,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
8989 // 0 <= sr <= n_uword_bits - 2 or sr large
9090 if (sr > n_uword_bits - 2) {
9191 if (var rem ?= maybe_rem) {
92 *rem = *(&du_int)(&n[0]);
92 *rem = *@bitcast(&du_int, &n[0]);
9393 }
9494 return 0;
9595 }
......@@ -113,12 +113,12 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
113113 *rem = n[low] & (d[low] - 1);
114114 }
115115 if (d[low] == 1) {
116 return *(&du_int)(&n[0]);
116 return *@bitcast(&du_int, &n[0]);
117117 }
118118 sr = @ctz(d[low]);
119119 q[high] = n[high] >> sr;
120120 q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
121 return *(&du_int)(&q[0]);
121 return *@bitcast(&du_int, &q[0]);
122122 }
123123 // K X
124124 // ---
......@@ -154,7 +154,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
154154 // 0 <= sr <= n_uword_bits - 1 or sr large
155155 if (sr > n_uword_bits - 1) {
156156 if (var rem ?= maybe_rem) {
157 *rem = *(&du_int)(&n[0]);
157 *rem = *@bitcast(&du_int, &n[0]);
158158 }
159159 return 0;
160160 }
......@@ -191,17 +191,17 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
191191 // r.all -= d.all;
192192 // carry = 1;
193193 // }
194 const s: di_int = (di_int)(*(&du_int)(&d[0]) - *(&du_int)(&r[0]) - 1) >> (n_udword_bits - 1);
194 const s: di_int = (di_int)(*@bitcast(&du_int, &d[0]) - *@bitcast(&du_int, &r[0]) - 1) >> (n_udword_bits - 1);
195195 carry = su_int(s & 1);
196 *(&du_int)(&r[0]) -= *(&du_int)(&d[0]) & u64(s);
196 *@bitcast(&du_int, &r[0]) -= *@bitcast(&du_int, &d[0]) & u64(s);
197197
198198 sr -= 1;
199199 }
200 *(&du_int)(&q[0]) = (*(&du_int)(&q[0]) << 1) | u64(carry);
200 *@bitcast(&du_int, &q[0]) = (*@bitcast(&du_int, &q[0]) << 1) | u64(carry);
201201 if (var rem ?= maybe_rem) {
202 *rem = *(&du_int)(&r[0]);
202 *rem = *@bitcast(&du_int, &r[0]);
203203 }
204 return *(&du_int)(&q[0]);
204 return *@bitcast(&du_int, &q[0]);
205205}
206206
207207export fn __umoddi3(a: du_int, b: du_int) -> du_int {
std/special/zigrt.zig+2-2
......@@ -1,5 +1,5 @@
11// This file contains functions that zig depends on to coordinate between
2// multiple .o files. The symbols are defined LinkOnce so that multiple
2// multiple .o files. The symbols are defined Weak so that multiple
33// instances of zig_rt.zig do not conflict with each other.
44
55export coldcc fn __zig_panic(message_ptr: &const u8, message_len: usize) -> noreturn {
......@@ -11,6 +11,6 @@ export coldcc fn __zig_panic(message_ptr: &const u8, message_len: usize) -> nore
1111 } else if (@compileVar("os") == Os.freestanding) {
1212 while (true) {}
1313 } else {
14 @import("std").debug.panic(message_ptr[0...message_len]);
14 @import("std").debug.panic("{}\n", message_ptr[0...message_len]);
1515 }
1616}
test/cases/cast.zig+12-1
......@@ -15,7 +15,18 @@ test "numLitIntToPtrCast" {
1515test "pointerReinterpretConstFloatToInt" {
1616 const float: f64 = 5.99999999999994648725e-01;
1717 const float_ptr = &float;
18 const int_ptr = (&i32)(float_ptr);
18 const int_ptr = @bitcast(&i32, float_ptr);
1919 const int_val = *int_ptr;
2020 assert(int_val == 858993411);
2121}
22
23test "implicitly cast a pointer to a const pointer of it" {
24 var x: i32 = 1;
25 const xp = &x;
26 funcWithConstPtrPtr(xp);
27 assert(x == 2);
28}
29
30fn funcWithConstPtrPtr(x: &const &i32) {
31 **x += 1;
32}
test/cases/eval.zig+15
......@@ -284,3 +284,18 @@ fn testCompTimeUIntComparisons(x: u32) {
284284 @compileError("this condition should be comptime known");
285285 }
286286}
287
288
289
290test "const ptr to variable data changes at runtime" {
291 assert(foo_ref.name[0] == 'a');
292 foo_ref.name = "b";
293 assert(foo_ref.name[0] == 'b');
294}
295
296const Foo = struct {
297 name: []const u8,
298};
299
300var foo_contents = Foo { .name = "a", };
301const foo_ref = &foo_contents;
test/cases/generics.zig+1-1
......@@ -121,5 +121,5 @@ test "genericFnWithImplicitCast" {
121121}
122122fn getByte(ptr: ?&const u8) -> u8 {*??ptr}
123123fn getFirstByte(comptime T: type, mem: []const T) -> u8 {
124 getByte((&const u8)(&mem[0]))
124 getByte(@bitcast(&const u8, &mem[0]))
125125}
test/cases/misc.zig+4-4
......@@ -246,15 +246,15 @@ test "typeEquality" {
246246
247247const global_a: i32 = 1234;
248248const global_b: &const i32 = &global_a;
249const global_c: &const f32 = (&const f32)(global_b);
249const global_c: &const f32 = @bitcast(&const f32, global_b);
250250test "compileTimeGlobalReinterpret" {
251 const d = (&const i32)(global_c);
251 const d = @bitcast(&const i32, global_c);
252252 assert(*d == 1234);
253253}
254254
255255test "explicitCastMaybePointers" {
256256 const a: ?&i32 = undefined;
257 const b: ?&f32 = (?&f32)(a);
257 const b: ?&f32 = @bitcast(?&f32, a);
258258}
259259
260260test "genericMallocFree" {
......@@ -263,7 +263,7 @@ test "genericMallocFree" {
263263}
264264const some_mem : [100]u8 = undefined;
265265fn memAlloc(comptime T: type, n: usize) -> %[]T {
266 return (&T)(&some_mem[0])[0...n];
266 return @bitcast(&T, &some_mem[0])[0...n];
267267}
268268fn memFree(comptime T: type, memory: []T) { }
269269
test/cases/struct.zig+1-1
......@@ -41,7 +41,7 @@ const VoidStructFieldsFoo = struct {
4141
4242test "fn" {
4343 var foo: StructFoo = undefined;
44 @memset((&u8)(&foo), 0, @sizeOf(StructFoo));
44 @memset(@bitcast(&u8, &foo), 0, @sizeOf(StructFoo));
4545 foo.a += 1;
4646 foo.b = foo.a == 1;
4747 testFoo(foo);
test/run_tests.cpp+7-18
......@@ -73,10 +73,8 @@ static TestCase *add_simple_case(const char *case_name, const char *source, cons
7373 test_case->source_files.at(0).relative_path = tmp_source_path;
7474 test_case->source_files.at(0).source_code = source;
7575
76 test_case->compiler_args.append("build");
76 test_case->compiler_args.append("build_exe");
7777 test_case->compiler_args.append(tmp_source_path);
78 test_case->compiler_args.append("--export");
79 test_case->compiler_args.append("exe");
8078 test_case->compiler_args.append("--name");
8179 test_case->compiler_args.append("test");
8280 test_case->compiler_args.append("--output");
......@@ -113,15 +111,12 @@ static TestCase *add_compile_fail_case(const char *case_name, const char *source
113111 test_case->compile_errors.append(arg);
114112 }
115113
116 test_case->compiler_args.append("build");
114 test_case->compiler_args.append("build_obj");
117115 test_case->compiler_args.append(tmp_source_path);
118116
119117 test_case->compiler_args.append("--name");
120118 test_case->compiler_args.append("test");
121119
122 test_case->compiler_args.append("--export");
123 test_case->compiler_args.append("obj");
124
125120 test_case->compiler_args.append("--output");
126121 test_case->compiler_args.append(tmp_exe_path);
127122
......@@ -142,15 +137,12 @@ static void add_debug_safety_case(const char *case_name, const char *source) {
142137 test_case->source_files.at(0).relative_path = tmp_source_path;
143138 test_case->source_files.at(0).source_code = source;
144139
145 test_case->compiler_args.append("build");
140 test_case->compiler_args.append("build_exe");
146141 test_case->compiler_args.append(tmp_source_path);
147142
148143 test_case->compiler_args.append("--name");
149144 test_case->compiler_args.append("test");
150145
151 test_case->compiler_args.append("--export");
152 test_case->compiler_args.append("exe");
153
154146 test_case->compiler_args.append("--output");
155147 test_case->compiler_args.append(tmp_exe_path);
156148
......@@ -164,15 +156,12 @@ static void add_debug_safety_case(const char *case_name, const char *source) {
164156 test_case->source_files.at(0).source_code = source;
165157 test_case->output = "";
166158
167 test_case->compiler_args.append("build");
159 test_case->compiler_args.append("build_exe");
168160 test_case->compiler_args.append(tmp_source_path);
169161
170162 test_case->compiler_args.append("--name");
171163 test_case->compiler_args.append("test");
172164
173 test_case->compiler_args.append("--export");
174 test_case->compiler_args.append("exe");
175
176165 test_case->compiler_args.append("--output");
177166 test_case->compiler_args.append(tmp_exe_path);
178167
......@@ -471,8 +460,8 @@ const foo : i32 = 0;
471460const c = @cImport(@cInclude("stdlib.h"));
472461
473462export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {
474 const a_int = (&i32)(a ?? unreachable);
475 const b_int = (&i32)(b ?? unreachable);
463 const a_int = @bitcast(&i32, a ?? unreachable);
464 const b_int = @bitcast(&i32, b ?? unreachable);
476465 if (*a_int < *b_int) {
477466 -1
478467 } else if (*a_int > *b_int) {
......@@ -485,7 +474,7 @@ export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {
485474export fn main(args: c_int, argv: &&u8) -> c_int {
486475 var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
487476
488 c.qsort((&c_void)(&array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn);
477 c.qsort(@bitcast(&c_void, &array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn);
489478
490479 for (array) |item, i| {
491480 if (item != i) {