aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-11-05 10:56:42 -0500
committerAndrew Kelley <superjoe30@gmail.com>2018-11-05 10:56:42 -0500
commitf8d6f5daff5ac9b9f69319b9bd827ccc34ea9d72 (patch)
treefc0da10e6a69eb167e7d994f348148917c8ef98b /src/codegen.cpp
parentce912e29640e0a3b39a5c304c86bdbb5fff67169 (diff)
parent973e0abe79abf33cb5e9f4550fe323cb93eb6ee1 (diff)
downloadzig-f8d6f5daff5ac9b9f69319b9bd827ccc34ea9d72.tar.gz
zig-f8d6f5daff5ac9b9f69319b9bd827ccc34ea9d72.zip
Merge remote-tracking branch 'origin/master' into llvm8
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp237
1 files changed, 135 insertions, 102 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 91e7c8dde9..71de547353 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -118,7 +118,6 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
g->string_literals_table.init(16);
g->type_info_cache.init(32);
g->is_test_build = false;
- g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib);
buf_resize(&g->global_asm, 0);
for (size_t i = 0; i < array_length(symbols_that_llvm_depends_on); i += 1) {
@@ -446,6 +445,21 @@ static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) {
return first_arg_ret ? 1 : 0;
}
+static void maybe_export_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) {
+ if (linkage != GlobalLinkageIdInternal && g->zig_target.os == OsWindows) {
+ LLVMSetDLLStorageClass(global_value, LLVMDLLExportStorageClass);
+ }
+}
+
+static void maybe_import_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) {
+ if (linkage != GlobalLinkageIdInternal && g->zig_target.os == OsWindows) {
+ // TODO come up with a good explanation/understanding for why we never do
+ // DLLImportStorageClass. Empirically it only causes problems. But let's have
+ // this documented and then clean up the code accordingly.
+ //LLVMSetDLLStorageClass(global_value, LLVMDLLImportStorageClass);
+ }
+}
+
static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
if (fn_table_entry->llvm_value)
return fn_table_entry->llvm_value;
@@ -539,6 +553,8 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
}
if (fn_table_entry->body_node != nullptr) {
+ maybe_export_dll(g, fn_table_entry->llvm_value, linkage);
+
bool want_fn_safety = g->build_mode != BuildModeFastRelease &&
g->build_mode != BuildModeSmallRelease &&
!fn_table_entry->def_scope->safety_off;
@@ -548,6 +564,8 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
addLLVMFnAttrStr(fn_table_entry->llvm_value, "stack-protector-buffer-size", "4");
}
}
+ } else {
+ maybe_import_dll(g, fn_table_entry->llvm_value, linkage);
}
if (fn_table_entry->alignstack_value != 0) {
@@ -1795,8 +1813,8 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty
return nullptr;
}
- uint32_t unaligned_bit_count = ptr_type->data.pointer.unaligned_bit_count;
- if (unaligned_bit_count == 0) {
+ uint32_t host_int_bytes = ptr_type->data.pointer.host_int_bytes;
+ if (host_int_bytes == 0) {
gen_store(g, value, ptr, ptr_type);
return nullptr;
}
@@ -1804,10 +1822,12 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_ty
bool big_endian = g->is_big_endian;
LLVMValueRef containing_int = gen_load(g, ptr, ptr_type, "");
-
- uint32_t bit_offset = ptr_type->data.pointer.bit_offset;
uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int));
- uint32_t shift_amt = big_endian ? host_bit_count - bit_offset - unaligned_bit_count : bit_offset;
+ assert(host_bit_count == host_int_bytes * 8);
+ uint32_t size_in_bits = type_size_bits(g, child_type);
+
+ uint32_t bit_offset = ptr_type->data.pointer.bit_offset_in_host;
+ uint32_t shift_amt = big_endian ? host_bit_count - bit_offset - size_in_bits : bit_offset;
LLVMValueRef shift_amt_val = LLVMConstInt(LLVMTypeOf(containing_int), shift_amt, false);
LLVMValueRef mask_val = LLVMConstAllOnes(child_type->type_ref);
@@ -3209,18 +3229,20 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI
ZigType *ptr_type = instruction->ptr->value.type;
assert(ptr_type->id == ZigTypeIdPointer);
- uint32_t unaligned_bit_count = ptr_type->data.pointer.unaligned_bit_count;
- if (unaligned_bit_count == 0)
+ uint32_t host_int_bytes = ptr_type->data.pointer.host_int_bytes;
+ if (host_int_bytes == 0)
return get_handle_value(g, ptr, child_type, ptr_type);
bool big_endian = g->is_big_endian;
assert(!handle_is_ptr(child_type));
LLVMValueRef containing_int = gen_load(g, ptr, ptr_type, "");
-
- uint32_t bit_offset = ptr_type->data.pointer.bit_offset;
uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int));
- uint32_t shift_amt = big_endian ? host_bit_count - bit_offset - unaligned_bit_count : bit_offset;
+ assert(host_bit_count == host_int_bytes * 8);
+ uint32_t size_in_bits = type_size_bits(g, child_type);
+
+ uint32_t bit_offset = ptr_type->data.pointer.bit_offset_in_host;
+ uint32_t shift_amt = big_endian ? host_bit_count - bit_offset - size_in_bits : bit_offset;
LLVMValueRef shift_amt_val = LLVMConstInt(LLVMTypeOf(containing_int), shift_amt, false);
LLVMValueRef shifted_value = LLVMBuildLShr(g->builder, containing_int, shift_amt_val, "");
@@ -3276,20 +3298,22 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
array_type->data.array.len, false);
add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, end);
}
- if (array_ptr_type->data.pointer.unaligned_bit_count != 0) {
+ if (array_ptr_type->data.pointer.host_int_bytes != 0) {
return array_ptr_ptr;
}
ZigType *child_type = array_type->data.array.child_type;
if (child_type->id == ZigTypeIdStruct &&
child_type->data.structure.layout == ContainerLayoutPacked)
{
- size_t unaligned_bit_count = instruction->base.value.type->data.pointer.unaligned_bit_count;
- if (unaligned_bit_count != 0) {
+ ZigType *ptr_type = instruction->base.value.type;
+ size_t host_int_bytes = ptr_type->data.pointer.host_int_bytes;
+ if (host_int_bytes != 0) {
+ uint32_t size_in_bits = type_size_bits(g, ptr_type->data.pointer.child_type);
LLVMTypeRef ptr_u8_type_ref = LLVMPointerType(LLVMInt8Type(), 0);
LLVMValueRef u8_array_ptr = LLVMBuildBitCast(g->builder, array_ptr, ptr_u8_type_ref, "");
- assert(unaligned_bit_count % 8 == 0);
+ assert(size_in_bits % 8 == 0);
LLVMValueRef elem_size_bytes = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
- unaligned_bit_count / 8, false);
+ size_in_bits / 8, false);
LLVMValueRef byte_offset = LLVMBuildNUWMul(g->builder, subscript_value, elem_size_bytes, "");
LLVMValueRef indices[] = {
byte_offset
@@ -3505,7 +3529,7 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
return nullptr;
if (struct_ptr_type->id == ZigTypeIdPointer &&
- struct_ptr_type->data.pointer.unaligned_bit_count != 0)
+ struct_ptr_type->data.pointer.host_int_bytes != 0)
{
return struct_ptr;
}
@@ -4671,10 +4695,11 @@ static LLVMValueRef ir_render_struct_init(CodeGen *g, IrExecutable *executable,
LLVMValueRef value = ir_llvm_value(g, field->value);
uint32_t field_align_bytes = get_abi_alignment(g, type_struct_field->type_entry);
+ uint32_t host_int_bytes = get_host_int_bytes(g, instruction->struct_type, type_struct_field);
ZigType *ptr_type = get_pointer_to_type_extra(g, type_struct_field->type_entry,
false, false, PtrLenSingle, field_align_bytes,
- (uint32_t)type_struct_field->packed_bits_offset, (uint32_t)type_struct_field->unaligned_bit_count);
+ (uint32_t)type_struct_field->bit_offset_in_host, host_int_bytes);
gen_assign_raw(g, field_ptr, ptr_type, value);
}
@@ -5075,8 +5100,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdSizeOf:
case IrInstructionIdSwitchTarget:
case IrInstructionIdContainerInitFields:
- case IrInstructionIdMinValue:
- case IrInstructionIdMaxValue:
case IrInstructionIdCompileErr:
case IrInstructionIdCompileLog:
case IrInstructionIdArrayLen:
@@ -5098,7 +5121,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdTypeName:
case IrInstructionIdDeclRef:
case IrInstructionIdSwitchVar:
- case IrInstructionIdOffsetOf:
+ case IrInstructionIdByteOffsetOf:
+ case IrInstructionIdBitOffsetOf:
case IrInstructionIdTypeInfo:
case IrInstructionIdTypeId:
case IrInstructionIdSetEvalBranchQuota:
@@ -5336,7 +5360,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent
static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) {
expand_undef_array(g, array_const_val);
- ConstParent *parent = &array_const_val->data.x_array.s_none.parent;
+ ConstParent *parent = &array_const_val->data.x_array.data.s_none.parent;
LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent);
LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr)));
@@ -5458,15 +5482,16 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
continue;
}
LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, &const_val->data.x_struct.fields[i]);
+ uint32_t packed_bits_size = type_size_bits(g, field->type_entry);
if (is_big_endian) {
- LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, field->packed_bits_size, false);
+ LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, packed_bits_size, false);
val = LLVMConstShl(val, shift_amt);
val = LLVMConstOr(val, child_val);
} else {
LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, used_bits, false);
LLVMValueRef child_val_shifted = LLVMConstShl(child_val, shift_amt);
val = LLVMConstOr(val, child_val_shifted);
- used_bits += field->packed_bits_size;
+ used_bits += packed_bits_size;
}
}
return val;
@@ -5676,16 +5701,17 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
}
LLVMValueRef child_val = pack_const_int(g, big_int_type_ref,
&const_val->data.x_struct.fields[i]);
+ uint32_t packed_bits_size = type_size_bits(g, it_field->type_entry);
if (is_big_endian) {
LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref,
- it_field->packed_bits_size, false);
+ packed_bits_size, false);
val = LLVMConstShl(val, shift_amt);
val = LLVMConstOr(val, child_val);
} else {
LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, used_bits, false);
LLVMValueRef child_val_shifted = LLVMConstShl(child_val, shift_amt);
val = LLVMConstOr(val, child_val_shifted);
- used_bits += it_field->packed_bits_size;
+ used_bits += packed_bits_size;
}
}
fields[type_struct_field->gen_index] = val;
@@ -5716,23 +5742,29 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
case ZigTypeIdArray:
{
uint64_t len = type_entry->data.array.len;
- if (const_val->data.x_array.special == ConstArraySpecialUndef) {
- return LLVMGetUndef(type_entry->type_ref);
- }
-
- LLVMValueRef *values = allocate<LLVMValueRef>(len);
- LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref;
- bool make_unnamed_struct = false;
- for (uint64_t i = 0; i < len; i += 1) {
- ConstExprValue *elem_value = &const_val->data.x_array.s_none.elements[i];
- LLVMValueRef val = gen_const_val(g, elem_value, "");
- values[i] = val;
- make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val);
- }
- if (make_unnamed_struct) {
- return LLVMConstStruct(values, len, true);
- } else {
- return LLVMConstArray(element_type_ref, values, (unsigned)len);
+ switch (const_val->data.x_array.special) {
+ case ConstArraySpecialUndef:
+ return LLVMGetUndef(type_entry->type_ref);
+ case ConstArraySpecialNone: {
+ LLVMValueRef *values = allocate<LLVMValueRef>(len);
+ LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref;
+ bool make_unnamed_struct = false;
+ for (uint64_t i = 0; i < len; i += 1) {
+ ConstExprValue *elem_value = &const_val->data.x_array.data.s_none.elements[i];
+ LLVMValueRef val = gen_const_val(g, elem_value, "");
+ values[i] = val;
+ make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val);
+ }
+ if (make_unnamed_struct) {
+ return LLVMConstStruct(values, len, true);
+ } else {
+ return LLVMConstArray(element_type_ref, values, (unsigned)len);
+ }
+ }
+ case ConstArraySpecialBuf: {
+ Buf *buf = const_val->data.x_array.data.s_buf;
+ return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), true);
+ }
}
}
case ZigTypeIdUnion:
@@ -6091,6 +6123,7 @@ static void do_code_gen(CodeGen *g) {
// TODO debug info for the extern variable
LLVMSetLinkage(global_value, LLVMExternalLinkage);
+ maybe_import_dll(g, global_value, GlobalLinkageIdStrong);
LLVMSetAlignment(global_value, var->align_bytes);
LLVMSetGlobalConstant(global_value, var->gen_is_const);
}
@@ -6103,6 +6136,7 @@ static void do_code_gen(CodeGen *g) {
if (exported) {
LLVMSetLinkage(global_value, LLVMExternalLinkage);
+ maybe_export_dll(g, global_value, GlobalLinkageIdStrong);
}
if (tld_var->section_name) {
LLVMSetSection(global_value, buf_ptr(tld_var->section_name));
@@ -6615,8 +6649,6 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3);
create_builtin_fn(g, BuiltinFnIdSizeof, "sizeOf", 1);
create_builtin_fn(g, BuiltinFnIdAlignOf, "alignOf", 1);
- create_builtin_fn(g, BuiltinFnIdMaxValue, "maxValue", 1);
- create_builtin_fn(g, BuiltinFnIdMinValue, "minValue", 1);
create_builtin_fn(g, BuiltinFnIdMemberCount, "memberCount", 1);
create_builtin_fn(g, BuiltinFnIdMemberType, "memberType", 2);
create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2);
@@ -6665,7 +6697,8 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdTagName, "tagName", 1);
create_builtin_fn(g, BuiltinFnIdTagType, "TagType", 1);
create_builtin_fn(g, BuiltinFnIdFieldParentPtr, "fieldParentPtr", 3);
- create_builtin_fn(g, BuiltinFnIdOffsetOf, "offsetOf", 2);
+ create_builtin_fn(g, BuiltinFnIdByteOffsetOf, "byteOffsetOf", 2);
+ create_builtin_fn(g, BuiltinFnIdBitOffsetOf, "bitOffsetOf", 2);
create_builtin_fn(g, BuiltinFnIdDivExact, "divExact", 2);
create_builtin_fn(g, BuiltinFnIdDivTrunc, "divTrunc", 2);
create_builtin_fn(g, BuiltinFnIdDivFloor, "divFloor", 2);
@@ -6713,14 +6746,14 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
// Modifications to this struct must be coordinated with code that does anything with
// g->stack_trace_type. There are hard-coded references to the field indexes.
buf_append_str(contents,
- "pub const StackTrace = struct {\n"
+ "pub const StackTrace = struct.{\n"
" index: usize,\n"
" instruction_addresses: []usize,\n"
"};\n\n");
const char *cur_os = nullptr;
{
- buf_appendf(contents, "pub const Os = enum {\n");
+ buf_appendf(contents, "pub const Os = enum.{\n");
uint32_t field_count = (uint32_t)target_os_count();
for (uint32_t i = 0; i < field_count; i += 1) {
Os os_type = get_target_os(i);
@@ -6738,7 +6771,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
const char *cur_arch = nullptr;
{
- buf_appendf(contents, "pub const Arch = enum {\n");
+ buf_appendf(contents, "pub const Arch = enum.{\n");
uint32_t field_count = (uint32_t)target_arch_count();
for (uint32_t i = 0; i < field_count; i += 1) {
const ArchType *arch_type = get_target_arch(i);
@@ -6762,7 +6795,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
const char *cur_environ = nullptr;
{
- buf_appendf(contents, "pub const Environ = enum {\n");
+ buf_appendf(contents, "pub const Environ = enum.{\n");
uint32_t field_count = (uint32_t)target_environ_count();
for (uint32_t i = 0; i < field_count; i += 1) {
ZigLLVM_EnvironmentType environ_type = get_target_environ(i);
@@ -6780,7 +6813,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
const char *cur_obj_fmt = nullptr;
{
- buf_appendf(contents, "pub const ObjectFormat = enum {\n");
+ buf_appendf(contents, "pub const ObjectFormat = enum.{\n");
uint32_t field_count = (uint32_t)target_oformat_count();
for (uint32_t i = 0; i < field_count; i += 1) {
ZigLLVM_ObjectFormatType oformat = get_target_oformat(i);
@@ -6798,7 +6831,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
assert(cur_obj_fmt != nullptr);
{
- buf_appendf(contents, "pub const GlobalLinkage = enum {\n");
+ buf_appendf(contents, "pub const GlobalLinkage = enum.{\n");
uint32_t field_count = array_length(global_linkage_values);
for (uint32_t i = 0; i < field_count; i += 1) {
const GlobalLinkageValue *value = &global_linkage_values[i];
@@ -6808,7 +6841,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
}
{
buf_appendf(contents,
- "pub const AtomicOrder = enum {\n"
+ "pub const AtomicOrder = enum.{\n"
" Unordered,\n"
" Monotonic,\n"
" Acquire,\n"
@@ -6819,7 +6852,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
}
{
buf_appendf(contents,
- "pub const AtomicRmwOp = enum {\n"
+ "pub const AtomicRmwOp = enum.{\n"
" Xchg,\n"
" Add,\n"
" Sub,\n"
@@ -6833,7 +6866,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
}
{
buf_appendf(contents,
- "pub const Mode = enum {\n"
+ "pub const Mode = enum.{\n"
" Debug,\n"
" ReleaseSafe,\n"
" ReleaseFast,\n"
@@ -6841,7 +6874,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
"};\n\n");
}
{
- buf_appendf(contents, "pub const TypeId = enum {\n");
+ buf_appendf(contents, "pub const TypeId = enum.{\n");
size_t field_count = type_id_len();
for (size_t i = 0; i < field_count; i += 1) {
const ZigTypeId id = type_id_at_index(i);
@@ -6851,7 +6884,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
}
{
buf_appendf(contents,
- "pub const TypeInfo = union(TypeId) {\n"
+ "pub const TypeInfo = union(TypeId).{\n"
" Type: void,\n"
" Void: void,\n"
" Bool: void,\n"
@@ -6877,96 +6910,96 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
" Opaque: void,\n"
" Promise: Promise,\n"
"\n\n"
- " pub const Int = struct {\n"
+ " pub const Int = struct.{\n"
" is_signed: bool,\n"
" bits: u8,\n"
" };\n"
"\n"
- " pub const Float = struct {\n"
+ " pub const Float = struct.{\n"
" bits: u8,\n"
" };\n"
"\n"
- " pub const Pointer = struct {\n"
+ " pub const Pointer = struct.{\n"
" size: Size,\n"
" is_const: bool,\n"
" is_volatile: bool,\n"
" alignment: u32,\n"
" child: type,\n"
"\n"
- " pub const Size = enum {\n"
+ " pub const Size = enum.{\n"
" One,\n"
" Many,\n"
" Slice,\n"
" };\n"
" };\n"
"\n"
- " pub const Array = struct {\n"
+ " pub const Array = struct.{\n"
" len: usize,\n"
" child: type,\n"
" };\n"
"\n"
- " pub const ContainerLayout = enum {\n"
+ " pub const ContainerLayout = enum.{\n"
" Auto,\n"
" Extern,\n"
" Packed,\n"
" };\n"
"\n"
- " pub const StructField = struct {\n"
+ " pub const StructField = struct.{\n"
" name: []const u8,\n"
" offset: ?usize,\n"
" field_type: type,\n"
" };\n"
"\n"
- " pub const Struct = struct {\n"
+ " pub const Struct = struct.{\n"
" layout: ContainerLayout,\n"
" fields: []StructField,\n"
" defs: []Definition,\n"
" };\n"
"\n"
- " pub const Optional = struct {\n"
+ " pub const Optional = struct.{\n"
" child: type,\n"
" };\n"
"\n"
- " pub const ErrorUnion = struct {\n"
+ " pub const ErrorUnion = struct.{\n"
" error_set: type,\n"
" payload: type,\n"
" };\n"
"\n"
- " pub const Error = struct {\n"
+ " pub const Error = struct.{\n"
" name: []const u8,\n"
" value: usize,\n"
" };\n"
"\n"
- " pub const ErrorSet = struct {\n"
+ " pub const ErrorSet = struct.{\n"
" errors: []Error,\n"
" };\n"
"\n"
- " pub const EnumField = struct {\n"
+ " pub const EnumField = struct.{\n"
" name: []const u8,\n"
" value: usize,\n"
" };\n"
"\n"
- " pub const Enum = struct {\n"
+ " pub const Enum = struct.{\n"
" layout: ContainerLayout,\n"
" tag_type: type,\n"
" fields: []EnumField,\n"
" defs: []Definition,\n"
" };\n"
"\n"
- " pub const UnionField = struct {\n"
+ " pub const UnionField = struct.{\n"
" name: []const u8,\n"
" enum_field: ?EnumField,\n"
" field_type: type,\n"
" };\n"
"\n"
- " pub const Union = struct {\n"
+ " pub const Union = struct.{\n"
" layout: ContainerLayout,\n"
" tag_type: ?type,\n"
" fields: []UnionField,\n"
" defs: []Definition,\n"
" };\n"
"\n"
- " pub const CallingConvention = enum {\n"
+ " pub const CallingConvention = enum.{\n"
" Unspecified,\n"
" C,\n"
" Cold,\n"
@@ -6975,13 +7008,13 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
" Async,\n"
" };\n"
"\n"
- " pub const FnArg = struct {\n"
+ " pub const FnArg = struct.{\n"
" is_generic: bool,\n"
" is_noalias: bool,\n"
" arg_type: ?type,\n"
" };\n"
"\n"
- " pub const Fn = struct {\n"
+ " pub const Fn = struct.{\n"
" calling_convention: CallingConvention,\n"
" is_generic: bool,\n"
" is_var_args: bool,\n"
@@ -6990,21 +7023,21 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
" args: []FnArg,\n"
" };\n"
"\n"
- " pub const Promise = struct {\n"
+ " pub const Promise = struct.{\n"
" child: ?type,\n"
" };\n"
"\n"
- " pub const Definition = struct {\n"
+ " pub const Definition = struct.{\n"
" name: []const u8,\n"
" is_pub: bool,\n"
" data: Data,\n"
"\n"
- " pub const Data = union(enum) {\n"
+ " pub const Data = union(enum).{\n"
" Type: type,\n"
" Var: type,\n"
" Fn: FnDef,\n"
"\n"
- " pub const FnDef = struct {\n"
+ " pub const FnDef = struct.{\n"
" fn_type: type,\n"
" inline_type: Inline,\n"
" calling_convention: CallingConvention,\n"
@@ -7015,7 +7048,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
" return_type: type,\n"
" arg_names: [][] const u8,\n"
"\n"
- " pub const Inline = enum {\n"
+ " pub const Inline = enum.{\n"
" Auto,\n"
" Always,\n"
" Never,\n"
@@ -7041,7 +7074,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
}
{
buf_appendf(contents,
- "pub const FloatMode = enum {\n"
+ "pub const FloatMode = enum.{\n"
" Strict,\n"
" Optimized,\n"
"};\n\n");
@@ -7050,7 +7083,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
}
{
buf_appendf(contents,
- "pub const Endian = enum {\n"
+ "pub const Endian = enum.{\n"
" Big,\n"
" Little,\n"
"};\n\n");
@@ -7191,7 +7224,10 @@ static void init(CodeGen *g) {
bool is_optimized = g->build_mode != BuildModeDebug;
LLVMCodeGenOptLevel opt_level = is_optimized ? LLVMCodeGenLevelAggressive : LLVMCodeGenLevelNone;
- LLVMRelocMode reloc_mode = g->is_static ? LLVMRelocStatic : LLVMRelocPIC;
+ if (g->out_type == OutTypeExe && g->is_static) {
+ g->disable_pic = true;
+ }
+ LLVMRelocMode reloc_mode = g->disable_pic ? LLVMRelocStatic : LLVMRelocPIC;
const char *target_specific_cpu_args;
const char *target_specific_features;
@@ -7242,10 +7278,15 @@ static void init(CodeGen *g) {
define_builtin_types(g);
- g->invalid_instruction = allocate<IrInstruction>(1);
+ IrInstruction *sentinel_instructions = allocate<IrInstruction>(2);
+ g->invalid_instruction = &sentinel_instructions[0];
g->invalid_instruction->value.type = g->builtin_types.entry_invalid;
g->invalid_instruction->value.global_refs = allocate<ConstGlobalRefs>(1);
+ g->unreach_instruction = &sentinel_instructions[1];
+ g->unreach_instruction->value.type = g->builtin_types.entry_unreachable;
+ g->unreach_instruction->value.global_refs = allocate<ConstGlobalRefs>(1);
+
g->const_void_val.special = ConstValSpecialStatic;
g->const_void_val.type = g->builtin_types.entry_void;
g->const_void_val.global_refs = allocate<ConstGlobalRefs>(1);
@@ -7278,7 +7319,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) {
import->source_code = nullptr;
import->path = full_path;
g->root_import = import;
- import->decls_scope = create_decls_scope(nullptr, nullptr, nullptr, import);
+ import->decls_scope = create_decls_scope(g, nullptr, nullptr, nullptr, import);
init(g);
@@ -7352,12 +7393,12 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
ConstExprValue *test_fn_array = create_const_vals(1);
test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length);
test_fn_array->special = ConstValSpecialStatic;
- test_fn_array->data.x_array.s_none.elements = create_const_vals(g->test_fns.length);
+ test_fn_array->data.x_array.data.s_none.elements = create_const_vals(g->test_fns.length);
for (size_t i = 0; i < g->test_fns.length; i += 1) {
ZigFn *test_fn_entry = g->test_fns.at(i);
- ConstExprValue *this_val = &test_fn_array->data.x_array.s_none.elements[i];
+ ConstExprValue *this_val = &test_fn_array->data.x_array.data.s_none.elements[i];
this_val->special = ConstValSpecialStatic;
this_val->type = struct_type;
this_val->data.x_struct.parent.id = ConstParentIdArray;
@@ -7445,7 +7486,9 @@ static void gen_root_source(CodeGen *g) {
{
g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap.zig");
}
- if (g->zig_target.os == OsWindows && !g->have_dllmain_crt_startup && g->out_type == OutTypeLib) {
+ if (g->zig_target.os == OsWindows && !g->have_dllmain_crt_startup &&
+ g->out_type == OutTypeLib && !g->is_static)
+ {
g->bootstrap_import = add_special_code(g, create_bootstrap_pkg(g, g->root_package), "bootstrap_lib.zig");
}
@@ -8003,6 +8046,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
cache_bool(ch, g->linker_rdynamic);
cache_bool(ch, g->no_rosegment_workaround);
cache_bool(ch, g->each_lib_rpath);
+ cache_bool(ch, g->disable_pic);
cache_buf_opt(ch, g->mmacosx_version_min);
cache_buf_opt(ch, g->mios_version_min);
cache_usize(ch, g->version_major);
@@ -8089,17 +8133,6 @@ static void resolve_out_paths(CodeGen *g) {
} else {
zig_unreachable();
}
-
- if (g->want_h_file && !g->out_h_path) {
- assert(g->root_out_name);
- Buf *h_basename = buf_sprintf("%s.h", buf_ptr(g->root_out_name));
- if (g->enable_cache) {
- g->out_h_path = buf_alloc();
- os_path_join(&g->artifact_dir, h_basename, g->out_h_path);
- } else {
- g->out_h_path = h_basename;
- }
- }
}
@@ -8155,11 +8188,11 @@ void codegen_build_and_link(CodeGen *g) {
codegen_add_time_event(g, "LLVM Emit Output");
zig_llvm_emit_output(g);
- if (g->want_h_file) {
+ if (g->out_h_path != nullptr) {
codegen_add_time_event(g, "Generate .h");
gen_h_file(g);
}
- if (g->out_type != OutTypeObj) {
+ if (g->out_type != OutTypeObj && g->emit_file_type == EmitFileTypeBinary) {
codegen_link(g);
}
}