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)...@@ -204,6 +204,7 @@ install(TARGETS zig DESTINATION bin)
204204
205install(FILES ${C_HEADERS} DESTINATION ${C_HEADERS_DEST})205install(FILES ${C_HEADERS} DESTINATION ${C_HEADERS_DEST})
206206
207install(FILES "${CMAKE_SOURCE_DIR}/std/build.zig" DESTINATION "${ZIG_STD_DEST}")
207install(FILES "${CMAKE_SOURCE_DIR}/std/c/darwin.zig" DESTINATION "${ZIG_STD_DEST}/c")208install(FILES "${CMAKE_SOURCE_DIR}/std/c/darwin.zig" DESTINATION "${ZIG_STD_DEST}/c")
208install(FILES "${CMAKE_SOURCE_DIR}/std/c/index.zig" DESTINATION "${ZIG_STD_DEST}/c")209install(FILES "${CMAKE_SOURCE_DIR}/std/c/index.zig" DESTINATION "${ZIG_STD_DEST}/c")
209install(FILES "${CMAKE_SOURCE_DIR}/std/c/linux.zig" DESTINATION "${ZIG_STD_DEST}/c")210install(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}")...@@ -234,6 +235,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}")
234install(FILES "${CMAKE_SOURCE_DIR}/std/rand_test.zig" DESTINATION "${ZIG_STD_DEST}")235install(FILES "${CMAKE_SOURCE_DIR}/std/rand_test.zig" DESTINATION "${ZIG_STD_DEST}")
235install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")236install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")
236install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special")237install(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")
237install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special")239install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special")
238install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}/special")240install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}/special")
239install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")241install(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:...@@ -82,13 +82,12 @@ the Zig compiler itself:
82 * gcc >= 5.0.0 or clang >= 3.6.082 * gcc >= 5.0.0 or clang >= 3.6.0
83 * cmake >= 2.8.583 * cmake >= 2.8.5
8484
85#### Runtime Dependencies85#### Library Dependencies
8686
87These libraries must be installed on your system, with the development files87These libraries must be installed on your system, with the development files
88available. The Zig compiler dynamically links against them.88available. The Zig compiler dynamically links against them.
8989
90 * LLVM == 4.x90 * LLVM, Clang, and LLD libraries == 4.x
91 * libclang == 4.x
9291
93### Debug / Development Build92### Debug / Development Build
9493
doc/langref.md+7
...@@ -633,3 +633,10 @@ Invokes the panic handler function. By default the panic handler function...@@ -633,3 +633,10 @@ Invokes the panic handler function. By default the panic handler function
633calls the public `panic` function exposed in the root source file, or633calls the public `panic` function exposed in the root source file, or
634if there is not one specified, invokes the one provided in634if there is not one specified, invokes the one provided in
635`std/special/panic.zig`.635`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 {...@@ -1196,6 +1196,7 @@ enum BuiltinFnId {
1196 BuiltinFnIdSetGlobalSection,1196 BuiltinFnIdSetGlobalSection,
1197 BuiltinFnIdSetGlobalLinkage,1197 BuiltinFnIdSetGlobalLinkage,
1198 BuiltinFnIdPanic,1198 BuiltinFnIdPanic,
1199 BuiltinFnIdBitCast,
1199};1200};
12001201
1201struct BuiltinFnEntry {1202struct BuiltinFnEntry {
...@@ -1719,7 +1720,7 @@ enum IrInstructionId {...@@ -1719,7 +1720,7 @@ enum IrInstructionId {
1719 IrInstructionIdFnProto,1720 IrInstructionIdFnProto,
1720 IrInstructionIdTestComptime,1721 IrInstructionIdTestComptime,
1721 IrInstructionIdInitEnum,1722 IrInstructionIdInitEnum,
1722 IrInstructionIdPointerReinterpret,1723 IrInstructionIdBitCast,
1723 IrInstructionIdWidenOrShorten,1724 IrInstructionIdWidenOrShorten,
1724 IrInstructionIdIntToPtr,1725 IrInstructionIdIntToPtr,
1725 IrInstructionIdPtrToInt,1726 IrInstructionIdPtrToInt,
...@@ -2369,10 +2370,11 @@ struct IrInstructionInitEnum {...@@ -2369,10 +2370,11 @@ struct IrInstructionInitEnum {
2369 LLVMValueRef tmp_ptr;2370 LLVMValueRef tmp_ptr;
2370};2371};
23712372
2372struct IrInstructionPointerReinterpret {2373struct IrInstructionBitCast {
2373 IrInstruction base;2374 IrInstruction base;
23742375
2375 IrInstruction *ptr;2376 IrInstruction *dest_type;
2377 IrInstruction *target;
2376};2378};
23772379
2378struct IrInstructionWidenOrShorten {2380struct IrInstructionWidenOrShorten {
src/analyze.cpp+1-1
...@@ -3355,7 +3355,6 @@ bool type_has_bits(TypeTableEntry *type_entry) {...@@ -3355,7 +3355,6 @@ bool type_has_bits(TypeTableEntry *type_entry) {
3355bool type_requires_comptime(TypeTableEntry *type_entry) {3355bool type_requires_comptime(TypeTableEntry *type_entry) {
3356 switch (get_underlying_type(type_entry)->id) {3356 switch (get_underlying_type(type_entry)->id) {
3357 case TypeTableEntryIdInvalid:3357 case TypeTableEntryIdInvalid:
3358 case TypeTableEntryIdUnreachable:
3359 case TypeTableEntryIdVar:3358 case TypeTableEntryIdVar:
3360 case TypeTableEntryIdTypeDecl:3359 case TypeTableEntryIdTypeDecl:
3361 zig_unreachable();3360 zig_unreachable();
...@@ -3383,6 +3382,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {...@@ -3383,6 +3382,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
3383 case TypeTableEntryIdPointer:3382 case TypeTableEntryIdPointer:
3384 case TypeTableEntryIdEnumTag:3383 case TypeTableEntryIdEnumTag:
3385 case TypeTableEntryIdVoid:3384 case TypeTableEntryIdVoid:
3385 case TypeTableEntryIdUnreachable:
3386 return false;3386 return false;
3387 }3387 }
3388 zig_unreachable();3388 zig_unreachable();
src/codegen.cpp+15-8
...@@ -47,7 +47,7 @@ static void init_darwin_native(CodeGen *g) {...@@ -47,7 +47,7 @@ static void init_darwin_native(CodeGen *g) {
47 }47 }
48}48}
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) {
51 PackageTableEntry *entry = allocate<PackageTableEntry>(1);51 PackageTableEntry *entry = allocate<PackageTableEntry>(1);
52 entry->package_table.init(4);52 entry->package_table.init(4);
53 buf_init_from_str(&entry->root_src_dir, root_src_dir);53 buf_init_from_str(&entry->root_src_dir, root_src_dir);
...@@ -1345,12 +1345,12 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,...@@ -1345,12 +1345,12 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
1345 zig_unreachable();1345 zig_unreachable();
1346}1346}
13471347
1348static LLVMValueRef ir_render_pointer_reinterpret(CodeGen *g, IrExecutable *executable,1348static LLVMValueRef ir_render_bitcast(CodeGen *g, IrExecutable *executable,
1349 IrInstructionPointerReinterpret *instruction)1349 IrInstructionBitCast *instruction)
1350{1350{
1351 TypeTableEntry *wanted_type = instruction->base.value.type;1351 TypeTableEntry *wanted_type = instruction->base.value.type;
1352 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);1352 LLVMValueRef target = ir_llvm_value(g, instruction->target);
1353 return LLVMBuildBitCast(g->builder, ptr, wanted_type->type_ref, "");1353 return LLVMBuildBitCast(g->builder, target, wanted_type->type_ref, "");
1354}1354}
13551355
1356static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable,1356static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable,
...@@ -2776,8 +2776,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -2776,8 +2776,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
2776 return ir_render_init_enum(g, executable, (IrInstructionInitEnum *)instruction);2776 return ir_render_init_enum(g, executable, (IrInstructionInitEnum *)instruction);
2777 case IrInstructionIdStructInit:2777 case IrInstructionIdStructInit:
2778 return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction);2778 return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction);
2779 case IrInstructionIdPointerReinterpret:2779 case IrInstructionIdBitCast:
2780 return ir_render_pointer_reinterpret(g, executable, (IrInstructionPointerReinterpret *)instruction);2780 return ir_render_bitcast(g, executable, (IrInstructionBitCast *)instruction);
2781 case IrInstructionIdWidenOrShorten:2781 case IrInstructionIdWidenOrShorten:
2782 return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction);2782 return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction);
2783 case IrInstructionIdPtrToInt:2783 case IrInstructionIdPtrToInt:
...@@ -3638,8 +3638,14 @@ static void do_code_gen(CodeGen *g) {...@@ -3638,8 +3638,14 @@ static void do_code_gen(CodeGen *g) {
3638 } else {3638 } else {
3639 assert(var->gen_arg_index != SIZE_MAX);3639 assert(var->gen_arg_index != SIZE_MAX);
3640 TypeTableEntry *gen_type;3640 TypeTableEntry *gen_type;
3641 FnGenParamInfo *gen_info = &fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index];
3642
3641 if (handle_is_ptr(var->value->type)) {3643 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 }
3643 var->value_ref = LLVMGetParam(fn, var->gen_arg_index);3649 var->value_ref = LLVMGetParam(fn, var->gen_arg_index);
3644 } else {3650 } else {
3645 gen_type = var->value->type;3651 gen_type = var->value->type;
...@@ -4254,6 +4260,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -4254,6 +4260,7 @@ static void define_builtin_fns(CodeGen *g) {
4254 create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);4260 create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
4255 create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2);4261 create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2);
4256 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);4262 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
4263 create_builtin_fn(g, BuiltinFnIdBitCast, "bitcast", 2);
4257}4264}
42584265
4259static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) {4266static 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);...@@ -45,6 +45,7 @@ void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min);
45void codegen_set_linker_script(CodeGen *g, const char *linker_script);45void codegen_set_linker_script(CodeGen *g, const char *linker_script);
46void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt);46void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt);
4747
48PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path);
48void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);49void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);
4950
50void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code);51void 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 *) {...@@ -480,8 +480,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionInitEnum *) {
480 return IrInstructionIdInitEnum;480 return IrInstructionIdInitEnum;
481}481}
482482
483static constexpr IrInstructionId ir_instruction_id(IrInstructionPointerReinterpret *) {483static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) {
484 return IrInstructionIdPointerReinterpret;484 return IrInstructionIdBitCast;
485}485}
486486
487static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) {487static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) {
...@@ -1940,14 +1940,16 @@ static IrInstruction *ir_build_init_enum_from(IrBuilder *irb, IrInstruction *old...@@ -1940,14 +1940,16 @@ static IrInstruction *ir_build_init_enum_from(IrBuilder *irb, IrInstruction *old
1940 return new_instruction;1940 return new_instruction;
1941}1941}
19421942
1943static IrInstruction *ir_build_pointer_reinterpret(IrBuilder *irb, Scope *scope, AstNode *source_node,1943static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
1944 IrInstruction *ptr)1944 IrInstruction *dest_type, IrInstruction *target)
1945{1945{
1946 IrInstructionPointerReinterpret *instruction = ir_build_instruction<IrInstructionPointerReinterpret>(1946 IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>(
1947 irb, scope, source_node);1947 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
1952 return &instruction->base;1954 return &instruction->base;
1953}1955}
...@@ -2664,11 +2666,12 @@ static IrInstruction *ir_instruction_initenum_get_dep(IrInstructionInitEnum *ins...@@ -2664,11 +2666,12 @@ static IrInstruction *ir_instruction_initenum_get_dep(IrInstructionInitEnum *ins
2664 }2666 }
2665}2667}
26662668
2667static IrInstruction *ir_instruction_pointerreinterpret_get_dep(IrInstructionPointerReinterpret *instruction,2669static IrInstruction *ir_instruction_bitcast_get_dep(IrInstructionBitCast *instruction,
2668 size_t index)2670 size_t index)
2669{2671{
2670 switch (index) {2672 switch (index) {
2671 case 0: return instruction->ptr;2673 case 0: return instruction->dest_type;
2674 case 1: return instruction->target;
2672 default: return nullptr;2675 default: return nullptr;
2673 }2676 }
2674}2677}
...@@ -2925,8 +2928,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t...@@ -2925,8 +2928,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
2925 return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index);2928 return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index);
2926 case IrInstructionIdInitEnum:2929 case IrInstructionIdInitEnum:
2927 return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index);2930 return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index);
2928 case IrInstructionIdPointerReinterpret:2931 case IrInstructionIdBitCast:
2929 return ir_instruction_pointerreinterpret_get_dep((IrInstructionPointerReinterpret *) instruction, index);2932 return ir_instruction_bitcast_get_dep((IrInstructionBitCast *) instruction, index);
2930 case IrInstructionIdWidenOrShorten:2933 case IrInstructionIdWidenOrShorten:
2931 return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index);2934 return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index);
2932 case IrInstructionIdIntToPtr:2935 case IrInstructionIdIntToPtr:
...@@ -4197,6 +4200,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4197,6 +4200,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
41974200
4198 return ir_build_panic(irb, scope, node, arg0_value);4201 return ir_build_panic(irb, scope, node, arg0_value);
4199 }4202 }
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 }
4200 }4217 }
4201 zig_unreachable();4218 zig_unreachable();
4202}4219}
...@@ -6364,34 +6381,6 @@ static IrInstruction *ir_analyze_maybe_wrap(IrAnalyze *ira, IrInstruction *sourc...@@ -6364,34 +6381,6 @@ static IrInstruction *ir_analyze_maybe_wrap(IrAnalyze *ira, IrInstruction *sourc
6364 return result;6381 return result;
6365}6382}
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
6395static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr,6384static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr,
6396 IrInstruction *value, TypeTableEntry *wanted_type)6385 IrInstruction *value, TypeTableEntry *wanted_type)
6397{6386{
...@@ -6829,24 +6818,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -6829,24 +6818,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
6829 }6818 }
6830 }6819 }
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
6850 // explicit cast from child type of maybe type to maybe type6821 // explicit cast from child type of maybe type to maybe type
6851 if (wanted_type->id == TypeTableEntryIdMaybe) {6822 if (wanted_type->id == TypeTableEntryIdMaybe) {
6852 if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) {6823 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...@@ -8986,6 +8957,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
89868957
8987 ConstExprValue *array_ptr_val;8958 ConstExprValue *array_ptr_val;
8988 if (array_ptr->value.special != ConstValSpecialRuntime &&8959 if (array_ptr->value.special != ConstValSpecialRuntime &&
8960 array_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar &&
8989 (array_ptr_val = const_ptr_pointee(&array_ptr->value)) &&8961 (array_ptr_val = const_ptr_pointee(&array_ptr->value)) &&
8990 array_ptr_val->special != ConstValSpecialRuntime &&8962 array_ptr_val->special != ConstValSpecialRuntime &&
8991 (array_type->id != TypeTableEntryIdPointer ||8963 (array_type->id != TypeTableEntryIdPointer ||
...@@ -12210,6 +12182,50 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio...@@ -12210,6 +12182,50 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio
12210 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);12182 return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
12211}12183}
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
12213static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,12229static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
12214 IrInstructionDeclRef *instruction)12230 IrInstructionDeclRef *instruction)
12215{12231{
...@@ -12283,7 +12299,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,...@@ -12283,7 +12299,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
12283static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {12299static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
12284 switch (instruction->id) {12300 switch (instruction->id) {
12285 case IrInstructionIdInvalid:12301 case IrInstructionIdInvalid:
12286 case IrInstructionIdPointerReinterpret:
12287 case IrInstructionIdWidenOrShorten:12302 case IrInstructionIdWidenOrShorten:
12288 case IrInstructionIdIntToPtr:12303 case IrInstructionIdIntToPtr:
12289 case IrInstructionIdPtrToInt:12304 case IrInstructionIdPtrToInt:
...@@ -12449,6 +12464,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -12449,6 +12464,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
12449 return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction);12464 return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction);
12450 case IrInstructionIdPanic:12465 case IrInstructionIdPanic:
12451 return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);12466 return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);
12467 case IrInstructionIdBitCast:
12468 return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction);
12452 case IrInstructionIdMaybeWrap:12469 case IrInstructionIdMaybeWrap:
12453 case IrInstructionIdErrWrapCode:12470 case IrInstructionIdErrWrapCode:
12454 case IrInstructionIdErrWrapPayload:12471 case IrInstructionIdErrWrapPayload:
...@@ -12620,7 +12637,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -12620,7 +12637,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
12620 case IrInstructionIdFnProto:12637 case IrInstructionIdFnProto:
12621 case IrInstructionIdTestComptime:12638 case IrInstructionIdTestComptime:
12622 case IrInstructionIdInitEnum:12639 case IrInstructionIdInitEnum:
12623 case IrInstructionIdPointerReinterpret:12640 case IrInstructionIdBitCast:
12624 case IrInstructionIdWidenOrShorten:12641 case IrInstructionIdWidenOrShorten:
12625 case IrInstructionIdPtrToInt:12642 case IrInstructionIdPtrToInt:
12626 case IrInstructionIdIntToPtr:12643 case IrInstructionIdIntToPtr:
src/ir_print.cpp+5-5
...@@ -765,9 +765,9 @@ static void ir_print_init_enum(IrPrint *irp, IrInstructionInitEnum *instruction)...@@ -765,9 +765,9 @@ static void ir_print_init_enum(IrPrint *irp, IrInstructionInitEnum *instruction)
765 fprintf(irp->f, "}");765 fprintf(irp->f, "}");
766}766}
767767
768static void ir_print_pointer_reinterpret(IrPrint *irp, IrInstructionPointerReinterpret *instruction) {768static void ir_print_bit_cast(IrPrint *irp, IrInstructionBitCast *instruction) {
769 fprintf(irp->f, "@pointerReinterpret(");769 fprintf(irp->f, "@bitcast(");
770 ir_print_other_instruction(irp, instruction->ptr);770 ir_print_other_instruction(irp, instruction->target);
771 fprintf(irp->f, ")");771 fprintf(irp->f, ")");
772}772}
773773
...@@ -1098,8 +1098,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1098,8 +1098,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1098 case IrInstructionIdInitEnum:1098 case IrInstructionIdInitEnum:
1099 ir_print_init_enum(irp, (IrInstructionInitEnum *)instruction);1099 ir_print_init_enum(irp, (IrInstructionInitEnum *)instruction);
1100 break;1100 break;
1101 case IrInstructionIdPointerReinterpret:1101 case IrInstructionIdBitCast:
1102 ir_print_pointer_reinterpret(irp, (IrInstructionPointerReinterpret *)instruction);1102 ir_print_bit_cast(irp, (IrInstructionBitCast *)instruction);
1103 break;1103 break;
1104 case IrInstructionIdWidenOrShorten:1104 case IrInstructionIdWidenOrShorten:
1105 ir_print_widen_or_shorten(irp, (IrInstructionWidenOrShorten *)instruction);1105 ir_print_widen_or_shorten(irp, (IrInstructionWidenOrShorten *)instruction);
src/main.cpp+110-52
...@@ -19,46 +19,48 @@...@@ -19,46 +19,48 @@
19static int usage(const char *arg0) {19static int usage(const char *arg0) {
20 fprintf(stderr, "Usage: %s [command] [options]\n"20 fprintf(stderr, "Usage: %s [command] [options]\n"
21 "Commands:\n"21 "Commands:\n"
22 " build [sources] create executable, object, or library from source\n"22 " build build project from build.zig\n"
23 " test [sources] create and run a test build\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"
24 " parseh [source] convert a c header file to zig extern declarations\n"26 " parseh [source] convert a c header file to zig extern declarations\n"
25 " version print version number and exit\n"
26 " targets list available compilation targets\n"27 " targets list available compilation targets\n"
28 " test [source] create and run a test build\n"
29 " version print version number and exit\n"
27 "Options:\n"30 "Options:\n"
28 " --release build with optimizations on and debug protection off\n"31 " --ar-path [path] set the path to ar\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"
35 " --color [auto|off|on] enable or disable colored error messages\n"32 " --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"
40 " --dynamic-linker [path] set the path to ld.so\n"33 " --dynamic-linker [path] set the path to ld.so\n"
34 " --each-lib-rpath add rpath for each used dynamic library\n"
41 " --ld-path [path] set the path to the linker\n"35 " --ld-path [path] set the path to the linker\n"
42 " --ar-path [path] set the path to ar\n"36 " --libc-include-dir [path] directory where libc stdlib.h resides\n"
43 " -isystem [dir] add additional search path for other .h files\n"37 " --libc-lib-dir [path] directory where libc crt1.o resides\n"
44 " -dirafter [dir] same as -isystem but do it last\n"38 " --libc-static-lib-dir [path] directory where libc crtbegin.o resides\n"
45 " --library-path [dir] add a directory to the library search path\n"
46 " -L[dir] alias for --library-path\n"
47 " --library [lib] link against lib\n"39 " --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"
48 " --target-arch [name] specify target architecture\n"47 " --target-arch [name] specify target architecture\n"
49 " --target-os [name] specify target operating system\n"
50 " --target-environ [name] specify target environment\n"48 " --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"
52 " -mconsole (windows only) --subsystem console to the linker\n"56 " -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"
54 " -mlinker-version [ver] (darwin only) override linker version\n"58 " -mlinker-version [ver] (darwin only) override linker version\n"
55 " -rdynamic add all symbols to the dynamic symbol table\n"
56 " -mmacosx-version-min [ver] (darwin only) set Mac OS X deployment target\n"59 " -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"60 " -municode (windows only) link with unicode\n"
58 " -framework [name] (darwin only) link against framework\n"61 " -mwindows (windows only) --subsystem windows to the linker\n"
59 " --linker-script [path] use a custom linker script\n"62 " -rdynamic add all symbols to the dynamic symbol table\n"
60 " -rpath [path] add directory to the runtime library search path\n"63 " -rpath [path] add directory to the runtime library search path\n"
61 " --each-lib-rpath add rpath for each used dynamic library\n"
62 , arg0);64 , arg0);
63 return EXIT_FAILURE;65 return EXIT_FAILURE;
64}66}
...@@ -144,6 +146,62 @@ int main(int argc, char **argv) {...@@ -144,6 +146,62 @@ int main(int argc, char **argv) {
144 ZigList<const char *> rpath_list = {0};146 ZigList<const char *> rpath_list = {0};
145 bool each_lib_rpath = false;147 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
147 for (int i = 1; i < argc; i += 1) {205 for (int i = 1; i < argc; i += 1) {
148 char *arg = argv[i];206 char *arg = argv[i];
149207
...@@ -177,16 +235,6 @@ int main(int argc, char **argv) {...@@ -177,16 +235,6 @@ int main(int argc, char **argv) {
177 return usage(arg0);235 return usage(arg0);
178 } else if (strcmp(arg, "--output") == 0) {236 } else if (strcmp(arg, "--output") == 0) {
179 out_file = argv[i];237 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 }
190 } else if (strcmp(arg, "--color") == 0) {238 } else if (strcmp(arg, "--color") == 0) {
191 if (strcmp(argv[i], "auto") == 0) {239 if (strcmp(argv[i], "auto") == 0) {
192 color = ErrColorAuto;240 color = ErrColorAuto;
...@@ -243,8 +291,15 @@ int main(int argc, char **argv) {...@@ -243,8 +291,15 @@ int main(int argc, char **argv) {
243 }291 }
244 }292 }
245 } else if (cmd == CmdInvalid) {293 } 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) {
247 cmd = CmdBuild;298 cmd = CmdBuild;
299 out_type = OutTypeObj;
300 } else if (strcmp(arg, "build_lib") == 0) {
301 cmd = CmdBuild;
302 out_type = OutTypeLib;
248 } else if (strcmp(arg, "version") == 0) {303 } else if (strcmp(arg, "version") == 0) {
249 cmd = CmdVersion;304 cmd = CmdVersion;
250 } else if (strcmp(arg, "parseh") == 0) {305 } else if (strcmp(arg, "parseh") == 0) {
...@@ -285,15 +340,7 @@ int main(int argc, char **argv) {...@@ -285,15 +340,7 @@ int main(int argc, char **argv) {
285 if (!in_file)340 if (!in_file)
286 return usage(arg0);341 return usage(arg0);
287342
288 if (cmd == CmdBuild && !out_name) {343 assert(cmd != CmdBuild || out_type != OutTypeUnknown);
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 }
297344
298 init_all_targets();345 init_all_targets();
299346
...@@ -331,6 +378,9 @@ int main(int argc, char **argv) {...@@ -331,6 +378,9 @@ int main(int argc, char **argv) {
331 Buf root_source_dir = BUF_INIT;378 Buf root_source_dir = BUF_INIT;
332 Buf root_source_code = BUF_INIT;379 Buf root_source_code = BUF_INIT;
333 Buf root_source_name = BUF_INIT;380 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);
334 if (buf_eql_str(&in_file_buf, "-")) {384 if (buf_eql_str(&in_file_buf, "-")) {
335 os_get_cwd(&root_source_dir);385 os_get_cwd(&root_source_dir);
336 if ((err = os_fetch_file(stdin, &root_source_code))) {386 if ((err = os_fetch_file(stdin, &root_source_code))) {
...@@ -338,12 +388,24 @@ int main(int argc, char **argv) {...@@ -338,12 +388,24 @@ int main(int argc, char **argv) {
338 return 1;388 return 1;
339 }389 }
340 buf_init_from_str(&root_source_name, "");390 buf_init_from_str(&root_source_name, "");
391
341 } else {392 } else {
342 os_path_split(&in_file_buf, &root_source_dir, &root_source_name);393 os_path_split(&in_file_buf, &root_source_dir, &root_source_name);
343 if ((err = os_fetch_file_path(buf_create_from_str(in_file), &root_source_code))) {394 if ((err = os_fetch_file_path(buf_create_from_str(in_file), &root_source_code))) {
344 fprintf(stderr, "unable to open '%s': %s\n", in_file, err_str(err));395 fprintf(stderr, "unable to open '%s': %s\n", in_file, err_str(err));
345 return 1;396 return 1;
346 }397 }
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);
347 }409 }
348410
349 CodeGen *g = codegen_create(&root_source_dir, target);411 CodeGen *g = codegen_create(&root_source_dir, target);
...@@ -361,11 +423,7 @@ int main(int argc, char **argv) {...@@ -361,11 +423,7 @@ int main(int argc, char **argv) {
361 } else if (cmd == CmdTest) {423 } else if (cmd == CmdTest) {
362 codegen_set_out_type(g, OutTypeExe);424 codegen_set_out_type(g, OutTypeExe);
363 }425 }
364 if (out_name) {426 codegen_set_out_name(g, buf_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 }
369 if (libc_lib_dir)427 if (libc_lib_dir)
370 codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir));428 codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir));
371 if (libc_static_lib_dir)429 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) {...@@ -139,6 +139,32 @@ void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename) {
139 if (out_basename) buf_init_from_buf(out_basename, full_path);139 if (out_basename) buf_init_from_buf(out_basename, full_path);
140}140}
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
142void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path) {168void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path) {
143 buf_init_from_buf(out_full_path, dirname);169 buf_init_from_buf(out_full_path, dirname);
144 uint8_t c = *(buf_ptr(out_full_path) + buf_len(out_full_path) - 1);170 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,...@@ -34,6 +34,7 @@ int os_exec_process(const char *exe, ZigList<const char *> &args,
3434
35void os_path_dirname(Buf *full_path, Buf *out_dirname);35void os_path_dirname(Buf *full_path, Buf *out_dirname);
36void os_path_split(Buf *full_path, Buf *out_dirname, Buf *out_basename);36void 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);
37void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path);38void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path);
38int os_path_real(Buf *rel_path, Buf *out_abs_path);39int os_path_real(Buf *rel_path, Buf *out_abs_path);
39void os_path_resolve(Buf *ref_path, Buf *target_path, Buf *out_abs_path);40void 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) {...@@ -15,7 +15,7 @@ pub fn assert(ok: bool) {
1515
16var panicking = false;16var panicking = false;
17/// This is the default panic implementation.17/// This is the default panic implementation.
18pub coldcc fn panic(message: []const u8) -> noreturn {18pub coldcc fn panic(comptime format: []const u8, args: ...) -> noreturn {
19 // TODO19 // TODO
20 // if (@atomicRmw(AtomicOp.XChg, &panicking, true, AtomicOrder.SeqCst)) { }20 // if (@atomicRmw(AtomicOp.XChg, &panicking, true, AtomicOrder.SeqCst)) { }
21 if (panicking) {21 if (panicking) {
...@@ -28,7 +28,7 @@ pub coldcc fn panic(message: []const u8) -> noreturn {...@@ -28,7 +28,7 @@ pub coldcc fn panic(message: []const u8) -> noreturn {
28 panicking = true;28 panicking = true;
29 }29 }
3030
31 %%io.stderr.printf("{}\n", message);31 %%io.stderr.printf(format, args);
32 %%printStackTrace();32 %%printStackTrace();
3333
34 os.abort();34 os.abort();
...@@ -74,7 +74,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void {...@@ -74,7 +74,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void {
74 const name = %return compile_unit.die.getAttrString(st, DW.AT_name);74 const name = %return compile_unit.die.getAttrString(st, DW.AT_name);
7575
76 %return out_stream.printf("{} -> {}\n", return_address, name);76 %return out_stream.printf("{} -> {}\n", return_address, name);
77 maybe_fp = *(&const ?&const u8)(fp);77 maybe_fp = *@bitcast(&const ?&const u8, fp);
78 }78 }
79 },79 },
80 ObjectFormat.coff => {80 ObjectFormat.coff => {
...@@ -511,7 +511,6 @@ pub var global_allocator = mem.Allocator {...@@ -511,7 +511,6 @@ pub var global_allocator = mem.Allocator {
511 .allocFn = globalAlloc,511 .allocFn = globalAlloc,
512 .reallocFn = globalRealloc,512 .reallocFn = globalRealloc,
513 .freeFn = globalFree,513 .freeFn = globalFree,
514 .context = null,
515};514};
516515
517var some_mem: [100 * 1024]u8 = undefined;516var some_mem: [100 * 1024]u8 = undefined;
std/hash_map.zig+1-1
...@@ -236,7 +236,7 @@ test "basicHashMapTest" {...@@ -236,7 +236,7 @@ test "basicHashMapTest" {
236}236}
237237
238fn hash_i32(x: i32) -> u32 {238fn hash_i32(x: i32) -> u32 {
239 *(&u32)(&x)239 *@bitcast(&u32, &x)
240}240}
241fn eql_i32(a: i32, b: i32) -> bool {241fn eql_i32(a: i32, b: i32) -> bool {
242 a == b242 a == b
std/index.zig+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1pub const build = @import("build.zig");
1pub const c = @import("c/index.zig");2pub const c = @import("c/index.zig");
2pub const cstr = @import("cstr.zig");3pub const cstr = @import("cstr.zig");
3pub const debug = @import("debug.zig");4pub const debug = @import("debug.zig");
std/mem.zig+64-2
...@@ -7,12 +7,10 @@ pub const Cmp = math.Cmp;...@@ -7,12 +7,10 @@ pub const Cmp = math.Cmp;
77
8error NoMem;8error NoMem;
99
10pub type Context = u8;
11pub const Allocator = struct {10pub const Allocator = struct {
12 allocFn: fn (self: &Allocator, n: usize) -> %[]u8,11 allocFn: fn (self: &Allocator, n: usize) -> %[]u8,
13 reallocFn: fn (self: &Allocator, old_mem: []u8, new_size: usize) -> %[]u8,12 reallocFn: fn (self: &Allocator, old_mem: []u8, new_size: usize) -> %[]u8,
14 freeFn: fn (self: &Allocator, mem: []u8),13 freeFn: fn (self: &Allocator, mem: []u8),
15 context: ?&Context,
1614
17 /// Aborts the program if an allocation fails.15 /// Aborts the program if an allocation fails.
18 fn checkedAlloc(self: &Allocator, comptime T: type, n: usize) -> []T {16 fn checkedAlloc(self: &Allocator, comptime T: type, n: usize) -> []T {
...@@ -22,6 +20,14 @@ pub const Allocator = struct {...@@ -22,6 +20,14 @@ pub const Allocator = struct {
22 }20 }
23 }21 }
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
25 fn alloc(self: &Allocator, comptime T: type, n: usize) -> %[]T {31 fn alloc(self: &Allocator, comptime T: type, n: usize) -> %[]T {
26 const byte_count = %return math.mulOverflow(usize, @sizeOf(T), n);32 const byte_count = %return math.mulOverflow(usize, @sizeOf(T), n);
27 ([]T)(%return self.allocFn(self, byte_count))33 ([]T)(%return self.allocFn(self, byte_count))
...@@ -37,6 +43,62 @@ pub const Allocator = struct {...@@ -37,6 +43,62 @@ pub const Allocator = struct {
37 }43 }
38};44};
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
40/// Copy all of source into dest at position 0.102/// Copy all of source into dest at position 0.
41/// dest.len must be >= source.len.103/// dest.len must be >= source.len.
42pub fn copy(comptime T: type, dest: []T, source: []const T) {104pub 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")) {...@@ -5,16 +5,29 @@ const arch = switch (@compileVar("arch")) {
5};5};
6const errno = @import("errno.zig");6const errno = @import("errno.zig");
77
8pub const MMAP_PROT_NONE = 0;8pub const PROT_NONE = 0;
9pub const MMAP_PROT_READ = 1;9pub const PROT_READ = 1;
10pub const MMAP_PROT_WRITE = 2;10pub const PROT_WRITE = 2;
11pub const MMAP_PROT_EXEC = 4;11pub const PROT_EXEC = 4;
1212pub const PROT_GROWSDOWN = 0x01000000;
13pub const MMAP_MAP_FILE = 0;13pub const PROT_GROWSUP = 0x02000000;
14pub const MMAP_MAP_SHARED = 1;14
15pub const MMAP_MAP_PRIVATE = 2;15pub const MAP_FAILED = @maxValue(usize);
16pub const MMAP_MAP_FIXED = 16;16pub const MAP_SHARED = 0x01;
17pub const MMAP_MAP_ANON = 32;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
19pub const SIGHUP = 1;32pub const SIGHUP = 1;
20pub const SIGINT = 2;33pub const SIGINT = 2;
...@@ -226,7 +239,7 @@ pub const AF_MAX = PF_MAX;...@@ -226,7 +239,7 @@ pub const AF_MAX = PF_MAX;
226239
227/// Get the errno from a syscall return value, or 0 for no error.240/// Get the errno from a syscall return value, or 0 for no error.
228pub fn getErrno(r: usize) -> usize {241pub fn getErrno(r: usize) -> usize {
229 const signed_r = *(&isize)(&r);242 const signed_r = *@bitcast(&isize, &r);
230 if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0243 if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0
231}244}
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 {...@@ -15,7 +15,7 @@ export fn __udivdi3(a: du_int, b: du_int) -> du_int {
1515
16fn du_int_to_udwords(x: du_int) -> udwords {16fn du_int_to_udwords(x: du_int) -> udwords {
17 @setDebugSafety(this, false);17 @setDebugSafety(this, false);
18 return *(&udwords)(&x);18 return *@bitcast(&udwords, &x);
19}19}
2020
21export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {21export 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 {...@@ -66,7 +66,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
66 if (var rem ?= maybe_rem) {66 if (var rem ?= maybe_rem) {
67 r[high] = n[high] % d[high];67 r[high] = n[high] % d[high];
68 r[low] = 0;68 r[low] = 0;
69 *rem = *(&du_int)(&r[0]);69 *rem = *@bitcast(&du_int, &r[0]);
70 }70 }
71 return n[high] / d[high];71 return n[high] / d[high];
72 }72 }
...@@ -78,7 +78,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {...@@ -78,7 +78,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
78 if (var rem ?= maybe_rem) {78 if (var rem ?= maybe_rem) {
79 r[low] = n[low];79 r[low] = n[low];
80 r[high] = n[high] & (d[high] - 1);80 r[high] = n[high] & (d[high] - 1);
81 *rem = *(&du_int)(&r[0]);81 *rem = *@bitcast(&du_int, &r[0]);
82 }82 }
83 return n[high] >> @ctz(d[high]);83 return n[high] >> @ctz(d[high]);
84 }84 }
...@@ -89,7 +89,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {...@@ -89,7 +89,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
89 // 0 <= sr <= n_uword_bits - 2 or sr large89 // 0 <= sr <= n_uword_bits - 2 or sr large
90 if (sr > n_uword_bits - 2) {90 if (sr > n_uword_bits - 2) {
91 if (var rem ?= maybe_rem) {91 if (var rem ?= maybe_rem) {
92 *rem = *(&du_int)(&n[0]);92 *rem = *@bitcast(&du_int, &n[0]);
93 }93 }
94 return 0;94 return 0;
95 }95 }
...@@ -113,12 +113,12 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {...@@ -113,12 +113,12 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
113 *rem = n[low] & (d[low] - 1);113 *rem = n[low] & (d[low] - 1);
114 }114 }
115 if (d[low] == 1) {115 if (d[low] == 1) {
116 return *(&du_int)(&n[0]);116 return *@bitcast(&du_int, &n[0]);
117 }117 }
118 sr = @ctz(d[low]);118 sr = @ctz(d[low]);
119 q[high] = n[high] >> sr;119 q[high] = n[high] >> sr;
120 q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);120 q[low] = (n[high] << (n_uword_bits - sr)) | (n[low] >> sr);
121 return *(&du_int)(&q[0]);121 return *@bitcast(&du_int, &q[0]);
122 }122 }
123 // K X123 // K X
124 // ---124 // ---
...@@ -154,7 +154,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {...@@ -154,7 +154,7 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
154 // 0 <= sr <= n_uword_bits - 1 or sr large154 // 0 <= sr <= n_uword_bits - 1 or sr large
155 if (sr > n_uword_bits - 1) {155 if (sr > n_uword_bits - 1) {
156 if (var rem ?= maybe_rem) {156 if (var rem ?= maybe_rem) {
157 *rem = *(&du_int)(&n[0]);157 *rem = *@bitcast(&du_int, &n[0]);
158 }158 }
159 return 0;159 return 0;
160 }160 }
...@@ -191,17 +191,17 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {...@@ -191,17 +191,17 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
191 // r.all -= d.all;191 // r.all -= d.all;
192 // carry = 1;192 // carry = 1;
193 // }193 // }
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);
195 carry = su_int(s & 1);195 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
198 sr -= 1;198 sr -= 1;
199 }199 }
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);
201 if (var rem ?= maybe_rem) {201 if (var rem ?= maybe_rem) {
202 *rem = *(&du_int)(&r[0]);202 *rem = *@bitcast(&du_int, &r[0]);
203 }203 }
204 return *(&du_int)(&q[0]);204 return *@bitcast(&du_int, &q[0]);
205}205}
206206
207export fn __umoddi3(a: du_int, b: du_int) -> du_int {207export fn __umoddi3(a: du_int, b: du_int) -> du_int {
std/special/zigrt.zig+2-2
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1// This file contains functions that zig depends on to coordinate between1// This file contains functions that zig depends on to coordinate between
2// multiple .o files. The symbols are defined LinkOnce so that multiple2// multiple .o files. The symbols are defined Weak so that multiple
3// instances of zig_rt.zig do not conflict with each other.3// instances of zig_rt.zig do not conflict with each other.
44
5export coldcc fn __zig_panic(message_ptr: &const u8, message_len: usize) -> noreturn {5export 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...@@ -11,6 +11,6 @@ export coldcc fn __zig_panic(message_ptr: &const u8, message_len: usize) -> nore
11 } else if (@compileVar("os") == Os.freestanding) {11 } else if (@compileVar("os") == Os.freestanding) {
12 while (true) {}12 while (true) {}
13 } else {13 } else {
14 @import("std").debug.panic(message_ptr[0...message_len]);14 @import("std").debug.panic("{}\n", message_ptr[0...message_len]);
15 }15 }
16}16}
test/cases/cast.zig+12-1
...@@ -15,7 +15,18 @@ test "numLitIntToPtrCast" {...@@ -15,7 +15,18 @@ test "numLitIntToPtrCast" {
15test "pointerReinterpretConstFloatToInt" {15test "pointerReinterpretConstFloatToInt" {
16 const float: f64 = 5.99999999999994648725e-01;16 const float: f64 = 5.99999999999994648725e-01;
17 const float_ptr = &float;17 const float_ptr = &float;
18 const int_ptr = (&i32)(float_ptr);18 const int_ptr = @bitcast(&i32, float_ptr);
19 const int_val = *int_ptr;19 const int_val = *int_ptr;
20 assert(int_val == 858993411);20 assert(int_val == 858993411);
21}21}
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) {...@@ -284,3 +284,18 @@ fn testCompTimeUIntComparisons(x: u32) {
284 @compileError("this condition should be comptime known");284 @compileError("this condition should be comptime known");
285 }285 }
286}286}
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" {...@@ -121,5 +121,5 @@ test "genericFnWithImplicitCast" {
121}121}
122fn getByte(ptr: ?&const u8) -> u8 {*??ptr}122fn getByte(ptr: ?&const u8) -> u8 {*??ptr}
123fn getFirstByte(comptime T: type, mem: []const T) -> u8 {123fn getFirstByte(comptime T: type, mem: []const T) -> u8 {
124 getByte((&const u8)(&mem[0]))124 getByte(@bitcast(&const u8, &mem[0]))
125}125}
test/cases/misc.zig+4-4
...@@ -246,15 +246,15 @@ test "typeEquality" {...@@ -246,15 +246,15 @@ test "typeEquality" {
246246
247const global_a: i32 = 1234;247const global_a: i32 = 1234;
248const global_b: &const i32 = &global_a;248const 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);
250test "compileTimeGlobalReinterpret" {250test "compileTimeGlobalReinterpret" {
251 const d = (&const i32)(global_c);251 const d = @bitcast(&const i32, global_c);
252 assert(*d == 1234);252 assert(*d == 1234);
253}253}
254254
255test "explicitCastMaybePointers" {255test "explicitCastMaybePointers" {
256 const a: ?&i32 = undefined;256 const a: ?&i32 = undefined;
257 const b: ?&f32 = (?&f32)(a);257 const b: ?&f32 = @bitcast(?&f32, a);
258}258}
259259
260test "genericMallocFree" {260test "genericMallocFree" {
...@@ -263,7 +263,7 @@ test "genericMallocFree" {...@@ -263,7 +263,7 @@ test "genericMallocFree" {
263}263}
264const some_mem : [100]u8 = undefined;264const some_mem : [100]u8 = undefined;
265fn memAlloc(comptime T: type, n: usize) -> %[]T {265fn memAlloc(comptime T: type, n: usize) -> %[]T {
266 return (&T)(&some_mem[0])[0...n];266 return @bitcast(&T, &some_mem[0])[0...n];
267}267}
268fn memFree(comptime T: type, memory: []T) { }268fn memFree(comptime T: type, memory: []T) { }
269269
test/cases/struct.zig+1-1
...@@ -41,7 +41,7 @@ const VoidStructFieldsFoo = struct {...@@ -41,7 +41,7 @@ const VoidStructFieldsFoo = struct {
4141
42test "fn" {42test "fn" {
43 var foo: StructFoo = undefined;43 var foo: StructFoo = undefined;
44 @memset((&u8)(&foo), 0, @sizeOf(StructFoo));44 @memset(@bitcast(&u8, &foo), 0, @sizeOf(StructFoo));
45 foo.a += 1;45 foo.a += 1;
46 foo.b = foo.a == 1;46 foo.b = foo.a == 1;
47 testFoo(foo);47 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...@@ -73,10 +73,8 @@ static TestCase *add_simple_case(const char *case_name, const char *source, cons
73 test_case->source_files.at(0).relative_path = tmp_source_path;73 test_case->source_files.at(0).relative_path = tmp_source_path;
74 test_case->source_files.at(0).source_code = source;74 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");
77 test_case->compiler_args.append(tmp_source_path);77 test_case->compiler_args.append(tmp_source_path);
78 test_case->compiler_args.append("--export");
79 test_case->compiler_args.append("exe");
80 test_case->compiler_args.append("--name");78 test_case->compiler_args.append("--name");
81 test_case->compiler_args.append("test");79 test_case->compiler_args.append("test");
82 test_case->compiler_args.append("--output");80 test_case->compiler_args.append("--output");
...@@ -113,15 +111,12 @@ static TestCase *add_compile_fail_case(const char *case_name, const char *source...@@ -113,15 +111,12 @@ static TestCase *add_compile_fail_case(const char *case_name, const char *source
113 test_case->compile_errors.append(arg);111 test_case->compile_errors.append(arg);
114 }112 }
115113
116 test_case->compiler_args.append("build");114 test_case->compiler_args.append("build_obj");
117 test_case->compiler_args.append(tmp_source_path);115 test_case->compiler_args.append(tmp_source_path);
118116
119 test_case->compiler_args.append("--name");117 test_case->compiler_args.append("--name");
120 test_case->compiler_args.append("test");118 test_case->compiler_args.append("test");
121119
122 test_case->compiler_args.append("--export");
123 test_case->compiler_args.append("obj");
124
125 test_case->compiler_args.append("--output");120 test_case->compiler_args.append("--output");
126 test_case->compiler_args.append(tmp_exe_path);121 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) {...@@ -142,15 +137,12 @@ static void add_debug_safety_case(const char *case_name, const char *source) {
142 test_case->source_files.at(0).relative_path = tmp_source_path;137 test_case->source_files.at(0).relative_path = tmp_source_path;
143 test_case->source_files.at(0).source_code = source;138 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");
146 test_case->compiler_args.append(tmp_source_path);141 test_case->compiler_args.append(tmp_source_path);
147142
148 test_case->compiler_args.append("--name");143 test_case->compiler_args.append("--name");
149 test_case->compiler_args.append("test");144 test_case->compiler_args.append("test");
150145
151 test_case->compiler_args.append("--export");
152 test_case->compiler_args.append("exe");
153
154 test_case->compiler_args.append("--output");146 test_case->compiler_args.append("--output");
155 test_case->compiler_args.append(tmp_exe_path);147 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) {...@@ -164,15 +156,12 @@ static void add_debug_safety_case(const char *case_name, const char *source) {
164 test_case->source_files.at(0).source_code = source;156 test_case->source_files.at(0).source_code = source;
165 test_case->output = "";157 test_case->output = "";
166158
167 test_case->compiler_args.append("build");159 test_case->compiler_args.append("build_exe");
168 test_case->compiler_args.append(tmp_source_path);160 test_case->compiler_args.append(tmp_source_path);
169161
170 test_case->compiler_args.append("--name");162 test_case->compiler_args.append("--name");
171 test_case->compiler_args.append("test");163 test_case->compiler_args.append("test");
172164
173 test_case->compiler_args.append("--export");
174 test_case->compiler_args.append("exe");
175
176 test_case->compiler_args.append("--output");165 test_case->compiler_args.append("--output");
177 test_case->compiler_args.append(tmp_exe_path);166 test_case->compiler_args.append(tmp_exe_path);
178167
...@@ -471,8 +460,8 @@ const foo : i32 = 0;...@@ -471,8 +460,8 @@ const foo : i32 = 0;
471const c = @cImport(@cInclude("stdlib.h"));460const c = @cImport(@cInclude("stdlib.h"));
472461
473export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {462export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {
474 const a_int = (&i32)(a ?? unreachable);463 const a_int = @bitcast(&i32, a ?? unreachable);
475 const b_int = (&i32)(b ?? unreachable);464 const b_int = @bitcast(&i32, b ?? unreachable);
476 if (*a_int < *b_int) {465 if (*a_int < *b_int) {
477 -1466 -1
478 } else if (*a_int > *b_int) {467 } else if (*a_int > *b_int) {
...@@ -485,7 +474,7 @@ export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {...@@ -485,7 +474,7 @@ export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {
485export fn main(args: c_int, argv: &&u8) -> c_int {474export fn main(args: c_int, argv: &&u8) -> c_int {
486 var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };475 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
490 for (array) |item, i| {479 for (array) |item, i| {
491 if (item != i) {480 if (item != i) {