Skip to content

Commit 3ca027c

Browse files
committed
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
1 parent 536c351 commit 3ca027c

27 files changed

+475
-188
lines changed

CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ install(TARGETS zig DESTINATION bin)
204204

205205
install(FILES ${C_HEADERS} DESTINATION ${C_HEADERS_DEST})
206206

207+
install(FILES "${CMAKE_SOURCE_DIR}/std/build.zig" DESTINATION "${ZIG_STD_DEST}")
207208
install(FILES "${CMAKE_SOURCE_DIR}/std/c/darwin.zig" DESTINATION "${ZIG_STD_DEST}/c")
208209
install(FILES "${CMAKE_SOURCE_DIR}/std/c/index.zig" DESTINATION "${ZIG_STD_DEST}/c")
209210
install(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}")
234235
install(FILES "${CMAKE_SOURCE_DIR}/std/rand_test.zig" DESTINATION "${ZIG_STD_DEST}")
235236
install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")
236237
install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special")
238+
install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")
237239
install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special")
238240
install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}/special")
239241
install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")

README.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -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

8787
These libraries must be installed on your system, with the development files
8888
available. 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
Original file line numberDiff line numberDiff line change
@@ -633,3 +633,10 @@ Invokes the panic handler function. By default the panic handler function
633633
calls the public `panic` function exposed in the root source file, or
634634
if 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+
639+
Transmutes memory from one type to another without changing any bits.
640+
The source and destination types must have the same size. This function
641+
can be used to, for example, reinterpret a pointer, or convert a `f32` to a
642+
`u32`.

src/all_types.hpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -1196,6 +1196,7 @@ enum BuiltinFnId {
11961196
BuiltinFnIdSetGlobalSection,
11971197
BuiltinFnIdSetGlobalLinkage,
11981198
BuiltinFnIdPanic,
1199+
BuiltinFnIdBitCast,
11991200
};
12001201

12011202
struct 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

2372-
struct IrInstructionPointerReinterpret {
2373+
struct IrInstructionBitCast {
23732374
IrInstruction base;
23742375

2375-
IrInstruction *ptr;
2376+
IrInstruction *dest_type;
2377+
IrInstruction *target;
23762378
};
23772379

23782380
struct IrInstructionWidenOrShorten {

src/analyze.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -3355,7 +3355,6 @@ bool type_has_bits(TypeTableEntry *type_entry) {
33553355
bool 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
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static void init_darwin_native(CodeGen *g) {
4747
}
4848
}
4949

50-
static PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path) {
50+
PackageTableEntry *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

1348-
static LLVMValueRef ir_render_pointer_reinterpret(CodeGen *g, IrExecutable *executable,
1349-
IrInstructionPointerReinterpret *instruction)
1348+
static 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

13561356
static 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

42594266
static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) {

src/codegen.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min);
4545
void codegen_set_linker_script(CodeGen *g, const char *linker_script);
4646
void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt);
4747

48+
PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path);
4849
void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);
4950

5051
void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code);

src/ir.cpp

+76-59
Original file line numberDiff line numberDiff line change
@@ -480,8 +480,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionInitEnum *) {
480480
return IrInstructionIdInitEnum;
481481
}
482482

483-
static constexpr IrInstructionId ir_instruction_id(IrInstructionPointerReinterpret *) {
484-
return IrInstructionIdPointerReinterpret;
483+
static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) {
484+
return IrInstructionIdBitCast;
485485
}
486486

487487
static 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

1943-
static IrInstruction *ir_build_pointer_reinterpret(IrBuilder *irb, Scope *scope, AstNode *source_node,
1944-
IrInstruction *ptr)
1943+
static 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

2667-
static IrInstruction *ir_instruction_pointerreinterpret_get_dep(IrInstructionPointerReinterpret *instruction,
2669+
static 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

6367-
static 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-
63956384
static 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

12185+
static 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+
1221312229
static 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,
1228312299
static 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:

0 commit comments

Comments
 (0)