diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2018-12-23 17:04:26 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2018-12-23 17:04:26 -0500 |
| commit | c00216701c64269a2395e84f3ccff99d6fb89ffc (patch) | |
| tree | 9fa071b9e96f9eadc5069b71634b11fc13b00839 /src/analyze.cpp | |
| parent | c21884e1d64e4193e03be4f3064917a26b34b142 (diff) | |
| parent | 45081c1e9cc28757cb563c77553631f7a92b29d8 (diff) | |
| download | zig-c00216701c64269a2395e84f3ccff99d6fb89ffc.tar.gz zig-c00216701c64269a2395e84f3ccff99d6fb89ffc.zip | |
Merge remote-tracking branch 'origin/master' into llvm8
Diffstat (limited to 'src/analyze.cpp')
| -rw-r--r-- | src/analyze.cpp | 158 |
1 files changed, 97 insertions, 61 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index bc9789fca8..9c24f3cc8d 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -401,7 +401,8 @@ ZigType *get_promise_type(CodeGen *g, ZigType *result_type) { } ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const, - bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, uint32_t bit_offset_in_host, uint32_t host_int_bytes) + bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, + uint32_t bit_offset_in_host, uint32_t host_int_bytes) { assert(!type_is_invalid(child_type)); assert(ptr_len == PtrLenSingle || child_type->id != ZigTypeIdOpaque); @@ -1059,7 +1060,7 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) { } zig_panic("TODO implement C ABI for x86_64 return types. type '%s'\nSee https://github.com/ziglang/zig/issues/1481", buf_ptr(&fn_type_id->return_type->name)); - } else if (g->zig_target.arch.arch == ZigLLVM_arm || g->zig_target.arch.arch == ZigLLVM_armeb) { + } else if (target_is_arm(&g->zig_target)) { return type_size(g, fn_type_id->return_type) > 16; } zig_panic("TODO implement C ABI for this architecture. See https://github.com/ziglang/zig/issues/1481"); @@ -1619,13 +1620,16 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc case ZigTypeIdUnion: case ZigTypeIdFn: case ZigTypeIdPromise: - if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown))) - return g->builtin_types.entry_invalid; - if (type_requires_comptime(type_entry)) { - add_node_error(g, param_node->data.param_decl.type, - buf_sprintf("parameter of type '%s' must be declared comptime", - buf_ptr(&type_entry->name))); - return g->builtin_types.entry_invalid; + switch (type_requires_comptime(g, type_entry)) { + case ReqCompTimeNo: + break; + case ReqCompTimeYes: + add_node_error(g, param_node->data.param_decl.type, + buf_sprintf("parameter of type '%s' must be declared comptime", + buf_ptr(&type_entry->name))); + return g->builtin_types.entry_invalid; + case ReqCompTimeInvalid: + return g->builtin_types.entry_invalid; } break; } @@ -1711,10 +1715,13 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc case ZigTypeIdUnion: case ZigTypeIdFn: case ZigTypeIdPromise: - if ((err = type_resolve(g, fn_type_id.return_type, ResolveStatusZeroBitsKnown))) - return g->builtin_types.entry_invalid; - if (type_requires_comptime(fn_type_id.return_type)) { - return get_generic_fn_type(g, &fn_type_id); + switch (type_requires_comptime(g, fn_type_id.return_type)) { + case ReqCompTimeInvalid: + return g->builtin_types.entry_invalid; + case ReqCompTimeYes: + return get_generic_fn_type(g, &fn_type_id); + case ReqCompTimeNo: + break; } break; } @@ -2560,8 +2567,6 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) { static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { assert(struct_type->id == ZigTypeIdStruct); - Error err; - if (struct_type->data.structure.resolve_status == ResolveStatusInvalid) return ErrorSemanticAnalyzeFail; if (struct_type->data.structure.resolve_status >= ResolveStatusZeroBitsKnown) @@ -2619,13 +2624,15 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { buf_sprintf("enums, not structs, support field assignment")); } - if ((err = type_resolve(g, field_type, ResolveStatusZeroBitsKnown))) { - struct_type->data.structure.resolve_status = ResolveStatusInvalid; - continue; - } - - if (type_requires_comptime(field_type)) { - struct_type->data.structure.requires_comptime = true; + switch (type_requires_comptime(g, field_type)) { + case ReqCompTimeYes: + struct_type->data.structure.requires_comptime = true; + break; + case ReqCompTimeInvalid: + struct_type->data.structure.resolve_status = ResolveStatusInvalid; + continue; + case ReqCompTimeNo: + break; } if (!type_has_bits(field_type)) @@ -2674,39 +2681,50 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { assert(decl_node->type == NodeTypeContainerDecl); assert(struct_type->di_type); + size_t field_count = struct_type->data.structure.src_field_count; if (struct_type->data.structure.layout == ContainerLayoutPacked) { struct_type->data.structure.abi_alignment = 1; - } - - size_t field_count = struct_type->data.structure.src_field_count; - for (size_t i = 0; i < field_count; i += 1) { - TypeStructField *field = &struct_type->data.structure.fields[i]; - - // If this assertion trips, look up the call stack. Probably something is - // calling type_resolve with ResolveStatusAlignmentKnown when it should only - // be resolving ResolveStatusZeroBitsKnown - assert(field->type_entry != nullptr); - - if (type_is_invalid(field->type_entry)) { - struct_type->data.structure.resolve_status = ResolveStatusInvalid; - break; + for (size_t i = 0; i < field_count; i += 1) { + TypeStructField *field = &struct_type->data.structure.fields[i]; + if (field->type_entry != nullptr && type_is_invalid(field->type_entry)) { + struct_type->data.structure.resolve_status = ResolveStatusInvalid; + break; + } } + } else for (size_t i = 0; i < field_count; i += 1) { + TypeStructField *field = &struct_type->data.structure.fields[i]; + uint32_t this_field_align; + + // TODO If we have no type_entry for the field, we've already failed to + // compile the program correctly. This stage1 compiler needs a deeper + // reworking to make this correct, or we can ignore the problem + // and make sure it is fixed in stage2. This workaround is for when + // there is a false positive of a dependency loop, of alignment depending + // on itself. When this false positive happens we assume a pointer-aligned + // field, which is usually fine but could be incorrectly over-aligned or + // even under-aligned. See https://github.com/ziglang/zig/issues/1512 + if (field->type_entry == nullptr) { + this_field_align = LLVMABIAlignmentOfType(g->target_data_ref, LLVMPointerType(LLVMInt8Type(), 0)); + } else { + if (type_is_invalid(field->type_entry)) { + struct_type->data.structure.resolve_status = ResolveStatusInvalid; + break; + } - if (!type_has_bits(field->type_entry)) - continue; + if (!type_has_bits(field->type_entry)) + continue; - // alignment of structs is the alignment of the most-aligned field - if (struct_type->data.structure.layout != ContainerLayoutPacked) { if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) { struct_type->data.structure.resolve_status = ResolveStatusInvalid; break; } - uint32_t this_field_align = get_abi_alignment(g, field->type_entry); + this_field_align = get_abi_alignment(g, field->type_entry); assert(this_field_align != 0); - if (this_field_align > struct_type->data.structure.abi_alignment) { - struct_type->data.structure.abi_alignment = this_field_align; - } + } + // alignment of structs is the alignment of the most-aligned field + if (this_field_align > struct_type->data.structure.abi_alignment) { + struct_type->data.structure.abi_alignment = this_field_align; } } @@ -2890,11 +2908,17 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { } union_field->type_entry = field_type; - if (type_requires_comptime(field_type)) { - union_type->data.unionation.requires_comptime = true; + switch (type_requires_comptime(g, field_type)) { + case ReqCompTimeInvalid: + union_type->data.unionation.is_invalid = true; + continue; + case ReqCompTimeYes: + union_type->data.unionation.requires_comptime = true; + break; + case ReqCompTimeNo: + break; } - if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) { ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value, buf_sprintf("non-enum union field assignment")); @@ -4579,7 +4603,10 @@ void find_libc_include_path(CodeGen *g) { fprintf(stderr, "Unable to determine libc include path. --libc-include-dir"); exit(1); } - } else if (g->zig_target.os == OsLinux || g->zig_target.os == OsMacOSX) { + } else if (g->zig_target.os == OsLinux || + g->zig_target.os == OsMacOSX || + g->zig_target.os == OsFreeBSD) + { g->libc_include_dir = get_posix_libc_include_path(); } else { fprintf(stderr, "Unable to determine libc include path.\n" @@ -4627,6 +4654,8 @@ void find_libc_lib_path(CodeGen *g) { } else if (g->zig_target.os == OsLinux) { g->libc_lib_dir = get_linux_libc_lib_path("crt1.o"); + } else if (g->zig_target.os == OsFreeBSD) { + g->libc_lib_dir = buf_create_from_str("/usr/lib"); } else { zig_panic("Unable to determine libc lib path."); } @@ -4639,6 +4668,8 @@ void find_libc_lib_path(CodeGen *g) { return; } else if (g->zig_target.os == OsLinux) { g->libc_static_lib_dir = get_linux_libc_lib_path("crtbegin.o"); + } else if (g->zig_target.os == OsFreeBSD) { + g->libc_static_lib_dir = buf_create_from_str("/usr/lib"); } else { zig_panic("Unable to determine libc static lib path."); } @@ -5089,7 +5120,10 @@ bool type_has_bits(ZigType *type_entry) { return !type_entry->zero_bits; } -bool type_requires_comptime(ZigType *type_entry) { +ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) { + Error err; + if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown))) + return ReqCompTimeInvalid; switch (type_entry->id) { case ZigTypeIdInvalid: case ZigTypeIdOpaque: @@ -5102,27 +5136,25 @@ bool type_requires_comptime(ZigType *type_entry) { case ZigTypeIdNamespace: case ZigTypeIdBoundFn: case ZigTypeIdArgTuple: - return true; + return ReqCompTimeYes; case ZigTypeIdArray: - return type_requires_comptime(type_entry->data.array.child_type); + return type_requires_comptime(g, type_entry->data.array.child_type); case ZigTypeIdStruct: - assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown)); - return type_entry->data.structure.requires_comptime; + return type_entry->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo; case ZigTypeIdUnion: - assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown)); - return type_entry->data.unionation.requires_comptime; + return type_entry->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo; case ZigTypeIdOptional: - return type_requires_comptime(type_entry->data.maybe.child_type); + return type_requires_comptime(g, type_entry->data.maybe.child_type); case ZigTypeIdErrorUnion: - return type_requires_comptime(type_entry->data.error_union.payload_type); + return type_requires_comptime(g, type_entry->data.error_union.payload_type); case ZigTypeIdPointer: if (type_entry->data.pointer.child_type->id == ZigTypeIdOpaque) { - return false; + return ReqCompTimeNo; } else { - return type_requires_comptime(type_entry->data.pointer.child_type); + return type_requires_comptime(g, type_entry->data.pointer.child_type); } case ZigTypeIdFn: - return type_entry->data.fn.is_generic; + return type_entry->data.fn.is_generic ? ReqCompTimeYes : ReqCompTimeNo; case ZigTypeIdEnum: case ZigTypeIdErrorSet: case ZigTypeIdBool: @@ -5131,7 +5163,7 @@ bool type_requires_comptime(ZigType *type_entry) { case ZigTypeIdVoid: case ZigTypeIdUnreachable: case ZigTypeIdPromise: - return false; + return ReqCompTimeNo; } zig_unreachable(); } @@ -6090,6 +6122,8 @@ uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) { return (uint32_t)(x.data.floating.bit_count) * (uint32_t)1953839089; case ZigLLVMFnIdSqrt: return (uint32_t)(x.data.floating.bit_count) * (uint32_t)2225366385; + case ZigLLVMFnIdBswap: + return (uint32_t)(x.data.bswap.bit_count) * (uint32_t)3661994335; case ZigLLVMFnIdOverflowArithmetic: return ((uint32_t)(x.data.overflow_arithmetic.bit_count) * 87135777) + ((uint32_t)(x.data.overflow_arithmetic.add_sub_mul) * 31640542) + @@ -6108,6 +6142,8 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) { return a.data.clz.bit_count == b.data.clz.bit_count; case ZigLLVMFnIdPopCount: return a.data.pop_count.bit_count == b.data.pop_count.bit_count; + case ZigLLVMFnIdBswap: + return a.data.bswap.bit_count == b.data.bswap.bit_count; case ZigLLVMFnIdFloor: case ZigLLVMFnIdCeil: case ZigLLVMFnIdSqrt: |
