Skip to content

Commit

Permalink
first pass at zig build system
Browse files Browse the repository at this point in the history
 * `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
  • Loading branch information
andrewrk committed Mar 31, 2017
1 parent 536c351 commit 3ca027c
Show file tree
Hide file tree
Showing 27 changed files with 475 additions and 188 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ install(TARGETS zig DESTINATION bin)

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

install(FILES "${CMAKE_SOURCE_DIR}/std/build.zig" DESTINATION "${ZIG_STD_DEST}")
install(FILES "${CMAKE_SOURCE_DIR}/std/c/darwin.zig" DESTINATION "${ZIG_STD_DEST}/c")
install(FILES "${CMAKE_SOURCE_DIR}/std/c/index.zig" DESTINATION "${ZIG_STD_DEST}/c")
install(FILES "${CMAKE_SOURCE_DIR}/std/c/linux.zig" DESTINATION "${ZIG_STD_DEST}/c")
Expand Down Expand Up @@ -234,6 +235,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}")
install(FILES "${CMAKE_SOURCE_DIR}/std/rand_test.zig" DESTINATION "${ZIG_STD_DEST}")
install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")
install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special")
install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")
install(FILES "${CMAKE_SOURCE_DIR}/std/special/builtin.zig" DESTINATION "${ZIG_STD_DEST}/special")
install(FILES "${CMAKE_SOURCE_DIR}/std/special/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}/special")
install(FILES "${CMAKE_SOURCE_DIR}/std/special/test_runner.zig" DESTINATION "${ZIG_STD_DEST}/special")
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,12 @@ the Zig compiler itself:
* gcc >= 5.0.0 or clang >= 3.6.0
* cmake >= 2.8.5

#### Runtime Dependencies
#### Library Dependencies

These libraries must be installed on your system, with the development files
available. The Zig compiler dynamically links against them.

* LLVM == 4.x
* libclang == 4.x
* LLVM, Clang, and LLD libraries == 4.x

### Debug / Development Build

Expand Down
7 changes: 7 additions & 0 deletions doc/langref.md
Original file line number Diff line number Diff line change
Expand Up @@ -633,3 +633,10 @@ Invokes the panic handler function. By default the panic handler function
calls the public `panic` function exposed in the root source file, or
if there is not one specified, invokes the one provided in
`std/special/panic.zig`.

### @bitcast(comptime DestType: type, value: var) -> DestType

Transmutes memory from one type to another without changing any bits.
The source and destination types must have the same size. This function
can be used to, for example, reinterpret a pointer, or convert a `f32` to a
`u32`.
8 changes: 5 additions & 3 deletions src/all_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1196,6 +1196,7 @@ enum BuiltinFnId {
BuiltinFnIdSetGlobalSection,
BuiltinFnIdSetGlobalLinkage,
BuiltinFnIdPanic,
BuiltinFnIdBitCast,
};

struct BuiltinFnEntry {
Expand Down Expand Up @@ -1719,7 +1720,7 @@ enum IrInstructionId {
IrInstructionIdFnProto,
IrInstructionIdTestComptime,
IrInstructionIdInitEnum,
IrInstructionIdPointerReinterpret,
IrInstructionIdBitCast,
IrInstructionIdWidenOrShorten,
IrInstructionIdIntToPtr,
IrInstructionIdPtrToInt,
Expand Down Expand Up @@ -2369,10 +2370,11 @@ struct IrInstructionInitEnum {
LLVMValueRef tmp_ptr;
};

struct IrInstructionPointerReinterpret {
struct IrInstructionBitCast {
IrInstruction base;

IrInstruction *ptr;
IrInstruction *dest_type;
IrInstruction *target;
};

struct IrInstructionWidenOrShorten {
Expand Down
2 changes: 1 addition & 1 deletion src/analyze.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3355,7 +3355,6 @@ bool type_has_bits(TypeTableEntry *type_entry) {
bool type_requires_comptime(TypeTableEntry *type_entry) {
switch (get_underlying_type(type_entry)->id) {
case TypeTableEntryIdInvalid:
case TypeTableEntryIdUnreachable:
case TypeTableEntryIdVar:
case TypeTableEntryIdTypeDecl:
zig_unreachable();
Expand Down Expand Up @@ -3383,6 +3382,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
case TypeTableEntryIdPointer:
case TypeTableEntryIdEnumTag:
case TypeTableEntryIdVoid:
case TypeTableEntryIdUnreachable:
return false;
}
zig_unreachable();
Expand Down
23 changes: 15 additions & 8 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static void init_darwin_native(CodeGen *g) {
}
}

static PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path) {
PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path) {
PackageTableEntry *entry = allocate<PackageTableEntry>(1);
entry->package_table.init(4);
buf_init_from_str(&entry->root_src_dir, root_src_dir);
Expand Down Expand Up @@ -1345,12 +1345,12 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
zig_unreachable();
}

static LLVMValueRef ir_render_pointer_reinterpret(CodeGen *g, IrExecutable *executable,
IrInstructionPointerReinterpret *instruction)
static LLVMValueRef ir_render_bitcast(CodeGen *g, IrExecutable *executable,
IrInstructionBitCast *instruction)
{
TypeTableEntry *wanted_type = instruction->base.value.type;
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
return LLVMBuildBitCast(g->builder, ptr, wanted_type->type_ref, "");
LLVMValueRef target = ir_llvm_value(g, instruction->target);
return LLVMBuildBitCast(g->builder, target, wanted_type->type_ref, "");
}

static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable,
Expand Down Expand Up @@ -2776,8 +2776,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_init_enum(g, executable, (IrInstructionInitEnum *)instruction);
case IrInstructionIdStructInit:
return ir_render_struct_init(g, executable, (IrInstructionStructInit *)instruction);
case IrInstructionIdPointerReinterpret:
return ir_render_pointer_reinterpret(g, executable, (IrInstructionPointerReinterpret *)instruction);
case IrInstructionIdBitCast:
return ir_render_bitcast(g, executable, (IrInstructionBitCast *)instruction);
case IrInstructionIdWidenOrShorten:
return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction);
case IrInstructionIdPtrToInt:
Expand Down Expand Up @@ -3638,8 +3638,14 @@ static void do_code_gen(CodeGen *g) {
} else {
assert(var->gen_arg_index != SIZE_MAX);
TypeTableEntry *gen_type;
FnGenParamInfo *gen_info = &fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index];

if (handle_is_ptr(var->value->type)) {
gen_type = fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index].type;
if (gen_info->is_byval) {
gen_type = var->value->type;
} else {
gen_type = gen_info->type;
}
var->value_ref = LLVMGetParam(fn, var->gen_arg_index);
} else {
gen_type = var->value->type;
Expand Down Expand Up @@ -4254,6 +4260,7 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdSetGlobalSection, "setGlobalSection", 2);
create_builtin_fn(g, BuiltinFnIdSetGlobalLinkage, "setGlobalLinkage", 2);
create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
create_builtin_fn(g, BuiltinFnIdBitCast, "bitcast", 2);
}

static void add_compile_var(CodeGen *g, const char *name, ConstExprValue *value) {
Expand Down
1 change: 1 addition & 0 deletions src/codegen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min);
void codegen_set_linker_script(CodeGen *g, const char *linker_script);
void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt);

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

void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code);
Expand Down
135 changes: 76 additions & 59 deletions src/ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,8 +480,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionInitEnum *) {
return IrInstructionIdInitEnum;
}

static constexpr IrInstructionId ir_instruction_id(IrInstructionPointerReinterpret *) {
return IrInstructionIdPointerReinterpret;
static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) {
return IrInstructionIdBitCast;
}

static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) {
Expand Down Expand Up @@ -1940,14 +1940,16 @@ static IrInstruction *ir_build_init_enum_from(IrBuilder *irb, IrInstruction *old
return new_instruction;
}

static IrInstruction *ir_build_pointer_reinterpret(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *ptr)
static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *dest_type, IrInstruction *target)
{
IrInstructionPointerReinterpret *instruction = ir_build_instruction<IrInstructionPointerReinterpret>(
IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>(
irb, scope, source_node);
instruction->ptr = ptr;
instruction->dest_type = dest_type;
instruction->target = target;

ir_ref_instruction(ptr, irb->current_basic_block);
if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block);
ir_ref_instruction(target, irb->current_basic_block);

return &instruction->base;
}
Expand Down Expand Up @@ -2664,11 +2666,12 @@ static IrInstruction *ir_instruction_initenum_get_dep(IrInstructionInitEnum *ins
}
}

static IrInstruction *ir_instruction_pointerreinterpret_get_dep(IrInstructionPointerReinterpret *instruction,
static IrInstruction *ir_instruction_bitcast_get_dep(IrInstructionBitCast *instruction,
size_t index)
{
switch (index) {
case 0: return instruction->ptr;
case 0: return instruction->dest_type;
case 1: return instruction->target;
default: return nullptr;
}
}
Expand Down Expand Up @@ -2925,8 +2928,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index);
case IrInstructionIdInitEnum:
return ir_instruction_initenum_get_dep((IrInstructionInitEnum *) instruction, index);
case IrInstructionIdPointerReinterpret:
return ir_instruction_pointerreinterpret_get_dep((IrInstructionPointerReinterpret *) instruction, index);
case IrInstructionIdBitCast:
return ir_instruction_bitcast_get_dep((IrInstructionBitCast *) instruction, index);
case IrInstructionIdWidenOrShorten:
return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index);
case IrInstructionIdIntToPtr:
Expand Down Expand Up @@ -4197,6 +4200,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo

return ir_build_panic(irb, scope, node, arg0_value);
}
case BuiltinFnIdBitCast:
{
AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
if (arg0_value == irb->codegen->invalid_instruction)
return arg0_value;

AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
if (arg1_value == irb->codegen->invalid_instruction)
return arg1_value;

return ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value);
}
}
zig_unreachable();
}
Expand Down Expand Up @@ -6364,34 +6381,6 @@ static IrInstruction *ir_analyze_maybe_wrap(IrAnalyze *ira, IrInstruction *sourc
return result;
}

static IrInstruction *ir_analyze_pointer_reinterpret(IrAnalyze *ira, IrInstruction *source_instr,
IrInstruction *ptr, TypeTableEntry *wanted_type)
{
if (ptr->value.type->id != TypeTableEntryIdPointer &&
ptr->value.type->id != TypeTableEntryIdMaybe)
{
ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&ptr->value.type->name)));
return ira->codegen->invalid_instruction;
}

if (instr_is_comptime(ptr)) {
ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk);
if (!val)
return ira->codegen->invalid_instruction;

IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
source_instr->scope, source_instr->source_node);
const_instruction->base.value = *val;
const_instruction->base.value.type = wanted_type;
return &const_instruction->base;
}

IrInstruction *result = ir_build_pointer_reinterpret(&ira->new_irb, source_instr->scope,
source_instr->source_node, ptr);
result->value.type = wanted_type;
return result;
}

static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr,
IrInstruction *value, TypeTableEntry *wanted_type)
{
Expand Down Expand Up @@ -6829,24 +6818,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
}
}

// explicit cast from pointer to another pointer
if ((actual_type->id == TypeTableEntryIdPointer || actual_type->id == TypeTableEntryIdFn) &&
(wanted_type->id == TypeTableEntryIdPointer || wanted_type->id == TypeTableEntryIdFn))
{
return ir_analyze_pointer_reinterpret(ira, source_instr, value, wanted_type);
}

// explicit cast from maybe pointer to another maybe pointer
if (actual_type->id == TypeTableEntryIdMaybe &&
(actual_type->data.maybe.child_type->id == TypeTableEntryIdPointer ||
actual_type->data.maybe.child_type->id == TypeTableEntryIdFn) &&
wanted_type->id == TypeTableEntryIdMaybe &&
(wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer ||
wanted_type->data.maybe.child_type->id == TypeTableEntryIdFn))
{
return ir_analyze_pointer_reinterpret(ira, source_instr, value, wanted_type);
}

// explicit cast from child type of maybe type to maybe type
if (wanted_type->id == TypeTableEntryIdMaybe) {
if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) {
Expand Down Expand Up @@ -8986,6 +8957,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc

ConstExprValue *array_ptr_val;
if (array_ptr->value.special != ConstValSpecialRuntime &&
array_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar &&
(array_ptr_val = const_ptr_pointee(&array_ptr->value)) &&
array_ptr_val->special != ConstValSpecialRuntime &&
(array_type->id != TypeTableEntryIdPointer ||
Expand Down Expand Up @@ -12210,6 +12182,50 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio
return ir_finish_anal(ira, ira->codegen->builtin_types.entry_unreachable);
}

static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) {
IrInstruction *dest_type_value = instruction->dest_type->other;
TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value);
if (type_is_invalid(dest_type))
return ira->codegen->builtin_types.entry_invalid;

IrInstruction *target = instruction->target->other;
TypeTableEntry *src_type = target->value.type;
if (type_is_invalid(src_type))
return ira->codegen->builtin_types.entry_invalid;

ensure_complete_type(ira->codegen, dest_type);
ensure_complete_type(ira->codegen, src_type);

uint64_t dest_size_bytes = type_size(ira->codegen, dest_type);
uint64_t src_size_bytes = type_size(ira->codegen, src_type);
if (dest_size_bytes != src_size_bytes) {
ir_add_error(ira, &instruction->base,
buf_sprintf("destination type '%s' has size %" PRIu64 " but source type '%s' has size %" PRIu64,
buf_ptr(&dest_type->name), dest_size_bytes,
buf_ptr(&src_type->name), src_size_bytes));
return ira->codegen->builtin_types.entry_invalid;
}

if (instr_is_comptime(target) && src_type->id == dest_type->id &&
(src_type->id == TypeTableEntryIdPointer || src_type->id == TypeTableEntryIdMaybe))
{
ConstExprValue *val = ir_resolve_const(ira, target, UndefOk);
if (!val)
return ira->codegen->builtin_types.entry_invalid;

ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
*out_val = *val;
out_val->type = dest_type;
return dest_type;
}

IrInstruction *result = ir_build_bit_cast(&ira->new_irb, instruction->base.scope,
instruction->base.source_node, nullptr, target);
ir_link_new_instruction(result, &instruction->base);
result->value.type = dest_type;
return dest_type;
}

static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
IrInstructionDeclRef *instruction)
{
Expand Down Expand Up @@ -12283,7 +12299,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
switch (instruction->id) {
case IrInstructionIdInvalid:
case IrInstructionIdPointerReinterpret:
case IrInstructionIdWidenOrShorten:
case IrInstructionIdIntToPtr:
case IrInstructionIdPtrToInt:
Expand Down Expand Up @@ -12449,6 +12464,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction);
case IrInstructionIdPanic:
return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction);
case IrInstructionIdBitCast:
return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction);
case IrInstructionIdMaybeWrap:
case IrInstructionIdErrWrapCode:
case IrInstructionIdErrWrapPayload:
Expand Down Expand Up @@ -12620,7 +12637,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdFnProto:
case IrInstructionIdTestComptime:
case IrInstructionIdInitEnum:
case IrInstructionIdPointerReinterpret:
case IrInstructionIdBitCast:
case IrInstructionIdWidenOrShorten:
case IrInstructionIdPtrToInt:
case IrInstructionIdIntToPtr:
Expand Down
Loading

0 comments on commit 3ca027c

Please sign in to comment.