diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2018-01-25 11:51:41 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2018-01-25 11:51:41 -0500 |
| commit | 47be64af5add5c146541c16dbb043ddf97f97d34 (patch) | |
| tree | 3fabcb50c94b254a71cdbf009f29ad1ece6b1f67 /src/analyze.cpp | |
| parent | 4556f448060b19492d7b104ff01585241ba9c256 (diff) | |
| parent | f7670882aff5fb3a943057edd9da34d053b5fe59 (diff) | |
| download | zig-47be64af5add5c146541c16dbb043ddf97f97d34.tar.gz zig-47be64af5add5c146541c16dbb043ddf97f97d34.zip | |
Merge remote-tracking branch 'origin/master' into llvm6
Diffstat (limited to 'src/analyze.cpp')
| -rw-r--r-- | src/analyze.cpp | 176 |
1 files changed, 126 insertions, 50 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index 9da8485014..49f8e093a0 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -609,7 +609,10 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t buf_resize(&entry->name, 0); buf_appendf(&entry->name, "[%" ZIG_PRI_u64 "]%s", array_size, buf_ptr(&child_type->name)); - if (!entry->zero_bits) { + if (entry->zero_bits) { + entry->di_type = ZigLLVMCreateDebugArrayType(g->dbuilder, 0, + 0, child_type->di_type, 0); + } else { entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref, (unsigned int)array_size) : nullptr; @@ -915,9 +918,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { if (fn_type_id->alignment != 0) { buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment); } - if (fn_type_id->return_type->id != TypeTableEntryIdVoid) { - buf_appendf(&fn_type->name, " -> %s", buf_ptr(&fn_type_id->return_type->name)); - } + buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name)); skip_debug_info = skip_debug_info || !fn_type_id->return_type->di_type; // next, loop over the parameters again and compute debug information @@ -1079,7 +1080,7 @@ TypeTableEntry *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) { const char *comma_str = (i == 0) ? "" : ","; buf_appendf(&fn_type->name, "%svar", comma_str); } - buf_appendf(&fn_type->name, ")->var"); + buf_appendf(&fn_type->name, ")var"); fn_type->data.fn.fn_type_id = *fn_type_id; fn_type->data.fn.is_generic = true; @@ -1155,6 +1156,104 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf ** return true; } +static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) { + switch (type_entry->id) { + case TypeTableEntryIdInvalid: + case TypeTableEntryIdVar: + zig_unreachable(); + case TypeTableEntryIdMetaType: + case TypeTableEntryIdUnreachable: + case TypeTableEntryIdNumLitFloat: + case TypeTableEntryIdNumLitInt: + case TypeTableEntryIdUndefLit: + case TypeTableEntryIdNullLit: + case TypeTableEntryIdErrorUnion: + case TypeTableEntryIdPureError: + case TypeTableEntryIdNamespace: + case TypeTableEntryIdBlock: + case TypeTableEntryIdBoundFn: + case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: + return false; + case TypeTableEntryIdVoid: + case TypeTableEntryIdBool: + case TypeTableEntryIdInt: + case TypeTableEntryIdFloat: + case TypeTableEntryIdPointer: + case TypeTableEntryIdArray: + case TypeTableEntryIdFn: + return true; + case TypeTableEntryIdStruct: + return type_entry->data.structure.layout == ContainerLayoutPacked; + case TypeTableEntryIdUnion: + return type_entry->data.unionation.layout == ContainerLayoutPacked; + case TypeTableEntryIdMaybe: + { + TypeTableEntry *child_type = type_entry->data.maybe.child_type; + return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn; + } + case TypeTableEntryIdEnum: + return type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr; + } + zig_unreachable(); +} + +static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) { + switch (type_entry->id) { + case TypeTableEntryIdInvalid: + case TypeTableEntryIdVar: + zig_unreachable(); + case TypeTableEntryIdMetaType: + case TypeTableEntryIdNumLitFloat: + case TypeTableEntryIdNumLitInt: + case TypeTableEntryIdUndefLit: + case TypeTableEntryIdNullLit: + case TypeTableEntryIdErrorUnion: + case TypeTableEntryIdPureError: + case TypeTableEntryIdNamespace: + case TypeTableEntryIdBlock: + case TypeTableEntryIdBoundFn: + case TypeTableEntryIdArgTuple: + return false; + case TypeTableEntryIdOpaque: + case TypeTableEntryIdUnreachable: + case TypeTableEntryIdVoid: + case TypeTableEntryIdBool: + return true; + case TypeTableEntryIdInt: + switch (type_entry->data.integral.bit_count) { + case 8: + case 16: + case 32: + case 64: + case 128: + return true; + default: + return false; + } + case TypeTableEntryIdFloat: + return true; + case TypeTableEntryIdArray: + return type_allowed_in_extern(g, type_entry->data.array.child_type); + case TypeTableEntryIdFn: + return type_entry->data.fn.fn_type_id.cc == CallingConventionC; + case TypeTableEntryIdPointer: + return type_allowed_in_extern(g, type_entry->data.pointer.child_type); + case TypeTableEntryIdStruct: + return type_entry->data.structure.layout == ContainerLayoutExtern; + case TypeTableEntryIdMaybe: + { + TypeTableEntry *child_type = type_entry->data.maybe.child_type; + return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn; + } + case TypeTableEntryIdEnum: + return type_entry->data.enumeration.layout == ContainerLayoutExtern; + case TypeTableEntryIdUnion: + return type_entry->data.unionation.layout == ContainerLayoutExtern; + } + zig_unreachable(); +} + static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) { assert(proto_node->type == NodeTypeFnProto); AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; @@ -1205,6 +1304,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c } } + if (fn_type_id.cc != CallingConventionUnspecified && !type_allowed_in_extern(g, type_entry)) { + add_node_error(g, param_node->data.param_decl.type, + buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", + buf_ptr(&type_entry->name), + calling_convention_name(fn_type_id.cc))); + return g->builtin_types.entry_invalid; + } + switch (type_entry->id) { case TypeTableEntryIdInvalid: return g->builtin_types.entry_invalid; @@ -1269,6 +1376,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c fn_type_id.return_type = (fn_proto->return_type == nullptr) ? g->builtin_types.entry_void : analyze_type_expr(g, child_scope, fn_proto->return_type); + if (fn_type_id.cc != CallingConventionUnspecified && !type_allowed_in_extern(g, fn_type_id.return_type)) { + add_node_error(g, fn_proto->return_type, + buf_sprintf("return type '%s' not allowed in function with calling convention '%s'", + buf_ptr(&fn_type_id.return_type->name), + calling_convention_name(fn_type_id.cc))); + return g->builtin_types.entry_invalid; + } + switch (fn_type_id.return_type->id) { case TypeTableEntryIdInvalid: return g->builtin_types.entry_invalid; @@ -1421,46 +1536,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { enum_type->di_type = tag_di_type; } -static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) { - switch (type_entry->id) { - case TypeTableEntryIdInvalid: - case TypeTableEntryIdVar: - zig_unreachable(); - case TypeTableEntryIdMetaType: - case TypeTableEntryIdUnreachable: - case TypeTableEntryIdNumLitFloat: - case TypeTableEntryIdNumLitInt: - case TypeTableEntryIdUndefLit: - case TypeTableEntryIdNullLit: - case TypeTableEntryIdErrorUnion: - case TypeTableEntryIdPureError: - case TypeTableEntryIdNamespace: - case TypeTableEntryIdBlock: - case TypeTableEntryIdBoundFn: - case TypeTableEntryIdArgTuple: - case TypeTableEntryIdOpaque: - return false; - case TypeTableEntryIdVoid: - case TypeTableEntryIdBool: - case TypeTableEntryIdInt: - case TypeTableEntryIdFloat: - case TypeTableEntryIdPointer: - case TypeTableEntryIdArray: - case TypeTableEntryIdUnion: - case TypeTableEntryIdFn: - return true; - case TypeTableEntryIdStruct: - return type_entry->data.structure.layout == ContainerLayoutPacked; - case TypeTableEntryIdMaybe: - { - TypeTableEntry *child_type = type_entry->data.maybe.child_type; - return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn; - } - case TypeTableEntryIdEnum: - return type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr; - } - zig_unreachable(); -} TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[], TypeTableEntry *field_types[], size_t field_count) @@ -1864,7 +1939,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) { uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits; TypeTableEntry *tag_type = union_type->data.unionation.tag_type; - if (tag_type == nullptr) { + if (tag_type == nullptr || tag_type->zero_bits) { assert(most_aligned_union_member != nullptr); if (padding_in_bits > 0) { @@ -2506,8 +2581,10 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) { if (create_enum_type) { ImportTableEntry *import = get_scope_import(scope); - uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref); - uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref); + uint64_t tag_debug_size_in_bits = tag_type->zero_bits ? 0 : + 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref); + uint64_t tag_debug_align_in_bits = tag_type->zero_bits ? 0 : + 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref); // TODO get a more accurate debug scope ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, ZigLLVMFileToScope(import->di_file), buf_ptr(&tag_type->name), @@ -2586,7 +2663,7 @@ static bool scope_is_root_decls(Scope *scope) { static void wrong_panic_prototype(CodeGen *g, AstNode *proto_node, TypeTableEntry *fn_type) { add_node_error(g, proto_node, - buf_sprintf("expected 'fn([]const u8, ?&builtin.StackTrace) -> unreachable', found '%s'", + buf_sprintf("expected 'fn([]const u8, ?&builtin.StackTrace) unreachable', found '%s'", buf_ptr(&fn_type->name))); } @@ -3448,7 +3525,6 @@ TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name) { TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag) { assert(type_entry->id == TypeTableEntryIdUnion); assert(type_entry->data.unionation.zero_bits_known); - assert(type_entry->data.unionation.gen_tag_index != SIZE_MAX); for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) { TypeUnionField *field = &type_entry->data.unionation.fields[i]; if (bigint_cmp(&field->enum_field->value, tag) == CmpEQ) { |
