diff --git a/doc/langref.md b/doc/langref.md index f579f8d50c..122c62a23d 100644 --- a/doc/langref.md +++ b/doc/langref.md @@ -9,9 +9,7 @@ TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestD TestDecl = "test" String Block -TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl) - -TypeDecl = "type" Symbol "=" TypeExpr ";" +TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | UseDecl) ErrorValueDecl = "error" Symbol ";" @@ -155,7 +153,7 @@ GotoExpression = "goto" Symbol GroupedExpression = "(" Expression ")" -KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this" | "unreachable" +KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "this" | "unreachable" ContainerDecl = option("extern" | "packed") ("struct" | "enum" | "union") "{" many(ContainerMember) "}" ``` diff --git a/src/all_types.hpp b/src/all_types.hpp index 839f1bc354..a186c65a1f 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -254,7 +254,6 @@ enum TldId { TldIdVar, TldIdFn, TldIdContainer, - TldIdTypeDef, TldIdCompTime, }; @@ -303,12 +302,6 @@ struct TldContainer { TypeTableEntry *type_entry; }; -struct TldTypeDef { - Tld base; - - TypeTableEntry *type_entry; -}; - struct TldCompTime { Tld base; }; @@ -330,7 +323,6 @@ enum NodeType { NodeTypeReturnExpr, NodeTypeDefer, NodeTypeVariableDeclaration, - NodeTypeTypeDecl, NodeTypeErrorValueDecl, NodeTypeTestDecl, NodeTypeBinOpExpr, @@ -369,7 +361,6 @@ enum NodeType { NodeTypeStructValueField, NodeTypeArrayType, NodeTypeErrorType, - NodeTypeTypeLiteral, NodeTypeVarLiteral, NodeTypeTryExpr, NodeTypeInlineExpr, @@ -448,12 +439,6 @@ struct AstNodeVariableDeclaration { AstNode *expr; }; -struct AstNodeTypeDecl { - VisibMod visib_mod; - Buf *symbol; - AstNode *child_type; -}; - struct AstNodeErrorValueDecl { Buf *name; @@ -790,9 +775,6 @@ struct AstNodeArrayType { struct AstNodeErrorType { }; -struct AstNodeTypeLiteral { -}; - struct AstNodeVarLiteral { }; @@ -816,7 +798,6 @@ struct AstNode { AstNodeReturnExpr return_expr; AstNodeDefer defer; AstNodeVariableDeclaration variable_declaration; - AstNodeTypeDecl type_decl; AstNodeErrorValueDecl error_value_decl; AstNodeTestDecl test_decl; AstNodeBinOpExpr bin_op_expr; @@ -856,7 +837,6 @@ struct AstNode { AstNodeUnreachableExpr unreachable_expr; AstNodeArrayType array_type; AstNodeErrorType error_type; - AstNodeTypeLiteral type_literal; AstNodeVarLiteral var_literal; AstNodeInlineExpr inline_expr; } data; @@ -1026,11 +1006,6 @@ struct TypeTableEntryBoundFn { TypeTableEntry *fn_type; }; -struct TypeTableEntryTypeDecl { - TypeTableEntry *child_type; - TypeTableEntry *canonical_type; -}; - enum TypeTableEntryId { TypeTableEntryIdInvalid, TypeTableEntryIdVar, @@ -1054,11 +1029,11 @@ enum TypeTableEntryId { TypeTableEntryIdEnumTag, TypeTableEntryIdUnion, TypeTableEntryIdFn, - TypeTableEntryIdTypeDecl, TypeTableEntryIdNamespace, TypeTableEntryIdBlock, TypeTableEntryIdBoundFn, TypeTableEntryIdArgTuple, + TypeTableEntryIdOpaque, }; struct TypeTableEntry { @@ -1083,7 +1058,6 @@ struct TypeTableEntry { TypeTableEntryEnumTag enum_tag; TypeTableEntryUnion unionation; TypeTableEntryFn fn; - TypeTableEntryTypeDecl type_decl; TypeTableEntryBoundFn bound_fn; } data; diff --git a/src/analyze.cpp b/src/analyze.cpp index 1f2d014393..fd84014acb 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -186,6 +186,8 @@ bool type_is_complete(TypeTableEntry *type_entry) { return type_entry->data.enumeration.complete; case TypeTableEntryIdUnion: return type_entry->data.unionation.complete; + case TypeTableEntryIdOpaque: + return false; case TypeTableEntryIdMetaType: case TypeTableEntryIdVoid: case TypeTableEntryIdBool: @@ -202,7 +204,6 @@ bool type_is_complete(TypeTableEntry *type_entry) { case TypeTableEntryIdErrorUnion: case TypeTableEntryIdPureError: case TypeTableEntryIdFn: - case TypeTableEntryIdTypeDecl: case TypeTableEntryIdNamespace: case TypeTableEntryIdBlock: case TypeTableEntryIdBoundFn: @@ -240,12 +241,12 @@ bool type_has_zero_bits_known(TypeTableEntry *type_entry) { case TypeTableEntryIdErrorUnion: case TypeTableEntryIdPureError: case TypeTableEntryIdFn: - case TypeTableEntryIdTypeDecl: case TypeTableEntryIdNamespace: case TypeTableEntryIdBlock: case TypeTableEntryIdBoundFn: case TypeTableEntryIdEnumTag: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: return true; } zig_unreachable(); @@ -254,18 +255,17 @@ bool type_has_zero_bits_known(TypeTableEntry *type_entry) { uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry) { assert(type_is_complete(type_entry)); - TypeTableEntry *canon_type = get_underlying_type(type_entry); if (!type_has_bits(type_entry)) return 0; - if (canon_type->id == TypeTableEntryIdStruct && canon_type->data.structure.layout == ContainerLayoutPacked) { + if (type_entry->id == TypeTableEntryIdStruct && type_entry->data.structure.layout == ContainerLayoutPacked) { uint64_t size_in_bits = type_size_bits(g, type_entry); return (size_in_bits + 7) / 8; - } else if (canon_type->id == TypeTableEntryIdArray) { - TypeTableEntry *canon_child_type = get_underlying_type(canon_type->data.array.child_type); - if (canon_child_type->id == TypeTableEntryIdStruct && - canon_child_type->data.structure.layout == ContainerLayoutPacked) + } else if (type_entry->id == TypeTableEntryIdArray) { + TypeTableEntry *child_type = type_entry->data.array.child_type; + if (child_type->id == TypeTableEntryIdStruct && + child_type->data.structure.layout == ContainerLayoutPacked) { uint64_t size_in_bits = type_size_bits(g, type_entry); return (size_in_bits + 7) / 8; @@ -277,27 +277,26 @@ uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry) { uint64_t type_size_bits(CodeGen *g, TypeTableEntry *type_entry) { assert(type_is_complete(type_entry)); - TypeTableEntry *canon_type = get_underlying_type(type_entry); if (!type_has_bits(type_entry)) return 0; - if (canon_type->id == TypeTableEntryIdStruct && canon_type->data.structure.layout == ContainerLayoutPacked) { + if (type_entry->id == TypeTableEntryIdStruct && type_entry->data.structure.layout == ContainerLayoutPacked) { uint64_t result = 0; - for (size_t i = 0; i < canon_type->data.structure.src_field_count; i += 1) { - result += type_size_bits(g, canon_type->data.structure.fields[i].type_entry); + for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { + result += type_size_bits(g, type_entry->data.structure.fields[i].type_entry); } return result; - } else if (canon_type->id == TypeTableEntryIdArray) { - TypeTableEntry *canon_child_type = get_underlying_type(canon_type->data.array.child_type); - if (canon_child_type->id == TypeTableEntryIdStruct && - canon_child_type->data.structure.layout == ContainerLayoutPacked) + } else if (type_entry->id == TypeTableEntryIdArray) { + TypeTableEntry *child_type = type_entry->data.array.child_type; + if (child_type->id == TypeTableEntryIdStruct && + child_type->data.structure.layout == ContainerLayoutPacked) { - return canon_type->data.array.len * type_size_bits(g, canon_child_type); + return type_entry->data.array.len * type_size_bits(g, child_type); } } - return LLVMSizeOfTypeInBits(g->target_data_ref, canon_type->type_ref); + return LLVMSizeOfTypeInBits(g->target_data_ref, type_entry->type_ref); } static bool type_is_copyable(CodeGen *g, TypeTableEntry *type_entry) { @@ -360,10 +359,9 @@ TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type bit_offset + unaligned_bit_count, const_str, volatile_str, buf_ptr(&child_type->name)); } - TypeTableEntry *canon_child_type = get_underlying_type(child_type); - assert(canon_child_type->id != TypeTableEntryIdInvalid); + assert(child_type->id != TypeTableEntryIdInvalid); - entry->zero_bits = !type_has_bits(canon_child_type); + entry->zero_bits = !type_has_bits(child_type); if (!entry->zero_bits) { entry->type_ref = LLVMPointerType(child_type->type_ref, 0); @@ -766,17 +764,22 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c } } -TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *child_type) { - TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdTypeDecl); +TypeTableEntry *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *name) { + TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdOpaque); buf_init_from_str(&entry->name, name); - entry->is_copyable = type_is_copyable(g, child_type); - entry->type_ref = child_type->type_ref; - entry->di_type = child_type->di_type; - entry->zero_bits = child_type->zero_bits; - entry->data.type_decl.child_type = child_type; - entry->data.type_decl.canonical_type = get_underlying_type(child_type); + ImportTableEntry *import = scope ? get_scope_import(scope) : nullptr; + unsigned line = source_node ? (unsigned)(source_node->line + 1) : 0; + + entry->is_copyable = false; + entry->type_ref = LLVMInt8Type(); + entry->di_type = ZigLLVMCreateDebugForwardDeclType(g->dbuilder, + ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name), + import ? ZigLLVMFileToScope(import->di_file) : nullptr, + import ? import->di_file : nullptr, + line); + entry->zero_bits = false; return entry; } @@ -968,14 +971,6 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKi return entry; } -TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry) { - if (type_entry->id == TypeTableEntryIdTypeDecl) { - return type_entry->data.type_decl.canonical_type; - } else { - return type_entry; - } -} - static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, TypeTableEntry *type_entry, Buf *type_name) { size_t backward_branch_count = 0; return ir_eval_const_value(g, scope, node, type_entry, @@ -1066,6 +1061,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c case TypeTableEntryIdUndefLit: case TypeTableEntryIdNullLit: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: add_node_error(g, param_node->data.param_decl.type, buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name))); return g->builtin_types.entry_invalid; @@ -1099,7 +1095,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c case TypeTableEntryIdEnum: case TypeTableEntryIdUnion: case TypeTableEntryIdFn: - case TypeTableEntryIdTypeDecl: case TypeTableEntryIdEnumTag: ensure_complete_type(g, type_entry); if (!fn_type_id.is_extern && !type_is_copyable(g, type_entry)) { @@ -1123,6 +1118,7 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c case TypeTableEntryIdUndefLit: case TypeTableEntryIdNullLit: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: add_node_error(g, fn_proto->return_type, buf_sprintf("return type '%s' not allowed", buf_ptr(&fn_type_id.return_type->name))); return g->builtin_types.entry_invalid; @@ -1155,7 +1151,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c case TypeTableEntryIdEnum: case TypeTableEntryIdUnion: case TypeTableEntryIdFn: - case TypeTableEntryIdTypeDecl: case TypeTableEntryIdEnumTag: break; } @@ -1173,8 +1168,6 @@ bool type_is_invalid(TypeTableEntry *type_entry) { return type_entry->data.enumeration.is_invalid; case TypeTableEntryIdUnion: return type_entry->data.unionation.is_invalid; - case TypeTableEntryIdTypeDecl: - return type_is_invalid(type_entry->data.type_decl.canonical_type); default: return false; } @@ -1380,8 +1373,7 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { } static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) { - TypeTableEntry *canon_type = get_underlying_type(type_entry); - switch (canon_type->id) { + switch (type_entry->id) { case TypeTableEntryIdInvalid: case TypeTableEntryIdVar: zig_unreachable(); @@ -1395,11 +1387,11 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) { case TypeTableEntryIdPureError: case TypeTableEntryIdEnum: case TypeTableEntryIdEnumTag: - case TypeTableEntryIdTypeDecl: case TypeTableEntryIdNamespace: case TypeTableEntryIdBlock: case TypeTableEntryIdBoundFn: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: return false; case TypeTableEntryIdVoid: case TypeTableEntryIdBool: @@ -1411,11 +1403,11 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) { case TypeTableEntryIdFn: return true; case TypeTableEntryIdStruct: - return canon_type->data.structure.layout == ContainerLayoutPacked; + return type_entry->data.structure.layout == ContainerLayoutPacked; case TypeTableEntryIdMaybe: { - TypeTableEntry *canon_child_type = get_underlying_type(canon_type->data.maybe.child_type); - return canon_child_type->id == TypeTableEntryIdPointer || canon_child_type->id == TypeTableEntryIdFn; + TypeTableEntry *child_type = type_entry->data.maybe.child_type; + return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn; } } zig_unreachable(); @@ -2037,15 +2029,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { add_top_level_decl(g, decls_scope, &tld_var->base); break; } - case NodeTypeTypeDecl: - { - Buf *name = node->data.type_decl.symbol; - VisibMod visib_mod = node->data.type_decl.visib_mod; - TldTypeDef *tld_typedef = allocate(1); - init_tld(&tld_typedef->base, TldIdTypeDef, name, visib_mod, node, &decls_scope->base); - add_top_level_decl(g, decls_scope, &tld_typedef->base); - break; - } case NodeTypeFnProto: { // if the name is missing, we immediately announce an error @@ -2126,7 +2109,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { case NodeTypeStructValueField: case NodeTypeArrayType: case NodeTypeErrorType: - case NodeTypeTypeLiteral: case NodeTypeVarLiteral: case NodeTypeTryExpr: case NodeTypeInlineExpr: @@ -2154,10 +2136,7 @@ static void resolve_decl_container(CodeGen *g, TldContainer *tld_container) { } TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry) { - TypeTableEntry *underlying_type = get_underlying_type(type_entry); - switch (underlying_type->id) { - case TypeTableEntryIdTypeDecl: - zig_unreachable(); + switch (type_entry->id) { case TypeTableEntryIdInvalid: return g->builtin_types.entry_invalid; case TypeTableEntryIdUnreachable: @@ -2168,8 +2147,9 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt case TypeTableEntryIdNullLit: case TypeTableEntryIdBlock: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: add_node_error(g, source_node, buf_sprintf("variable of type '%s' not allowed", - buf_ptr(&underlying_type->name))); + buf_ptr(&type_entry->name))); return g->builtin_types.entry_invalid; case TypeTableEntryIdNamespace: case TypeTableEntryIdMetaType: @@ -2328,17 +2308,6 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { g->global_vars.append(tld_var); } -static void resolve_decl_typedef(CodeGen *g, TldTypeDef *tld_typedef) { - AstNode *typedef_node = tld_typedef->base.source_node; - assert(typedef_node->type == NodeTypeTypeDecl); - AstNode *type_node = typedef_node->data.type_decl.child_type; - Buf *decl_name = typedef_node->data.type_decl.symbol; - - TypeTableEntry *child_type = analyze_type_expr(g, tld_typedef->base.parent_scope, type_node); - tld_typedef->type_entry = (child_type->id == TypeTableEntryIdInvalid) ? - child_type : get_typedecl_type(g, buf_ptr(decl_name), child_type); -} - void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only) { if (tld->resolution != TldResolutionUnresolved) return; @@ -2370,12 +2339,6 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only) { resolve_decl_container(g, tld_container); break; } - case TldIdTypeDef: - { - TldTypeDef *tld_typedef = (TldTypeDef *)tld; - resolve_decl_typedef(g, tld_typedef); - break; - } case TldIdCompTime: { TldCompTime *tld_comptime = (TldCompTime *)tld; @@ -2589,6 +2552,7 @@ static bool is_container(TypeTableEntry *type_entry) { switch (type_entry->id) { case TypeTableEntryIdInvalid: case TypeTableEntryIdVar: + case TypeTableEntryIdOpaque: zig_unreachable(); case TypeTableEntryIdStruct: case TypeTableEntryIdEnum: @@ -2610,7 +2574,6 @@ static bool is_container(TypeTableEntry *type_entry) { case TypeTableEntryIdErrorUnion: case TypeTableEntryIdPureError: case TypeTableEntryIdFn: - case TypeTableEntryIdTypeDecl: case TypeTableEntryIdNamespace: case TypeTableEntryIdBlock: case TypeTableEntryIdBoundFn: @@ -2659,7 +2622,6 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) { case TypeTableEntryIdErrorUnion: case TypeTableEntryIdPureError: case TypeTableEntryIdFn: - case TypeTableEntryIdTypeDecl: case TypeTableEntryIdNamespace: case TypeTableEntryIdBlock: case TypeTableEntryIdBoundFn: @@ -2667,6 +2629,7 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) { case TypeTableEntryIdVar: case TypeTableEntryIdEnumTag: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: zig_unreachable(); } } @@ -3062,6 +3025,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) { case TypeTableEntryIdBoundFn: case TypeTableEntryIdVar: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: zig_unreachable(); case TypeTableEntryIdUnreachable: case TypeTableEntryIdVoid: @@ -3086,8 +3050,6 @@ bool handle_is_ptr(TypeTableEntry *type_entry) { return type_has_bits(type_entry->data.maybe.child_type) && type_entry->data.maybe.child_type->id != TypeTableEntryIdPointer && type_entry->data.maybe.child_type->id != TypeTableEntryIdFn; - case TypeTableEntryIdTypeDecl: - return handle_is_ptr(type_entry->data.type_decl.canonical_type); } zig_unreachable(); } @@ -3165,6 +3127,8 @@ bool fn_type_id_eql(FnTypeId *a, FnTypeId *b) { static uint32_t hash_const_val(ConstExprValue *const_val) { assert(const_val->special == ConstValSpecialStatic); switch (const_val->type->id) { + case TypeTableEntryIdOpaque: + zig_unreachable(); case TypeTableEntryIdBool: return const_val->data.x_bool ? (uint32_t)127863866 : (uint32_t)215080464; case TypeTableEntryIdMetaType: @@ -3254,8 +3218,6 @@ static uint32_t hash_const_val(ConstExprValue *const_val) { case TypeTableEntryIdFn: return hash_ptr(const_val->data.x_fn.fn_entry) + (const_val->data.x_fn.is_inline ? 4133894920 : 3983484790); - case TypeTableEntryIdTypeDecl: - return hash_ptr(const_val->data.x_type); case TypeTableEntryIdNamespace: return hash_ptr(const_val->data.x_import); case TypeTableEntryIdBlock: @@ -3359,10 +3321,10 @@ bool type_has_bits(TypeTableEntry *type_entry) { } bool type_requires_comptime(TypeTableEntry *type_entry) { - switch (get_underlying_type(type_entry)->id) { + switch (type_entry->id) { case TypeTableEntryIdInvalid: case TypeTableEntryIdVar: - case TypeTableEntryIdTypeDecl: + case TypeTableEntryIdOpaque: zig_unreachable(); case TypeTableEntryIdNumLitFloat: case TypeTableEntryIdNumLitInt: @@ -3603,14 +3565,14 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { - TypeTableEntry *canon_wanted_type = get_underlying_type(const_val->type); - if (canon_wanted_type->id == TypeTableEntryIdArray) { + TypeTableEntry *wanted_type = const_val->type; + if (wanted_type->id == TypeTableEntryIdArray) { const_val->special = ConstValSpecialStatic; - size_t elem_count = canon_wanted_type->data.array.len; + size_t elem_count = wanted_type->data.array.len; const_val->data.x_array.elements = allocate(elem_count); for (size_t i = 0; i < elem_count; i += 1) { ConstExprValue *element_val = &const_val->data.x_array.elements[i]; - element_val->type = canon_wanted_type->data.array.child_type; + element_val->type = wanted_type->data.array.child_type; init_const_undefined(g, element_val); ConstParent *parent = get_const_val_parent(element_val); if (parent != nullptr) { @@ -3619,15 +3581,15 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { parent->data.p_array.elem_index = i; } } - } else if (canon_wanted_type->id == TypeTableEntryIdStruct) { - ensure_complete_type(g, canon_wanted_type); + } else if (wanted_type->id == TypeTableEntryIdStruct) { + ensure_complete_type(g, wanted_type); const_val->special = ConstValSpecialStatic; - size_t field_count = canon_wanted_type->data.structure.src_field_count; + size_t field_count = wanted_type->data.structure.src_field_count; const_val->data.x_struct.fields = allocate(field_count); for (size_t i = 0; i < field_count; i += 1) { ConstExprValue *field_val = &const_val->data.x_struct.fields[i]; - field_val->type = canon_wanted_type->data.structure.fields[i].type_entry; + field_val->type = wanted_type->data.structure.fields[i].type_entry; assert(field_val->type); init_const_undefined(g, field_val); ConstParent *parent = get_const_val_parent(field_val); @@ -3678,6 +3640,8 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { assert(a->special == ConstValSpecialStatic); assert(b->special == ConstValSpecialStatic); switch (a->type->id) { + case TypeTableEntryIdOpaque: + zig_unreachable(); case TypeTableEntryIdEnum: { ConstEnumValue *enum1 = &a->data.x_enum; @@ -3767,8 +3731,6 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { } case TypeTableEntryIdErrorUnion: zig_panic("TODO"); - case TypeTableEntryIdTypeDecl: - zig_panic("TODO"); case TypeTableEntryIdNamespace: return a->data.x_import == b->data.x_import; case TypeTableEntryIdBlock: @@ -3857,9 +3819,9 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) { } assert(const_val->type); - TypeTableEntry *canon_type = get_underlying_type(const_val->type); - switch (canon_type->id) { - case TypeTableEntryIdTypeDecl: + TypeTableEntry *type_entry = const_val->type; + switch (type_entry->id) { + case TypeTableEntryIdOpaque: zig_unreachable(); case TypeTableEntryIdInvalid: buf_appendf(buf, "(invalid)"); @@ -3926,7 +3888,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) { return; } case ConstPtrSpecialHardCodedAddr: - buf_appendf(buf, "(&%s)(%" PRIx64 ")", buf_ptr(&canon_type->data.pointer.child_type->name), + buf_appendf(buf, "(&%s)(%" PRIx64 ")", buf_ptr(&type_entry->data.pointer.child_type->name), const_val->data.x_ptr.data.hard_coded_addr.addr); return; case ConstPtrSpecialDiscard: @@ -3949,8 +3911,8 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) { } case TypeTableEntryIdArray: { - TypeTableEntry *child_type = canon_type->data.array.child_type; - uint64_t len = canon_type->data.array.len; + TypeTableEntry *child_type = type_entry->data.array.child_type; + uint64_t len = type_entry->data.array.len; // if it's []u8, assume UTF-8 and output a string if (child_type->id == TypeTableEntryIdInt && @@ -3973,7 +3935,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) { return; } - buf_appendf(buf, "%s{", buf_ptr(&canon_type->name)); + buf_appendf(buf, "%s{", buf_ptr(&type_entry->name)); for (uint64_t i = 0; i < len; i += 1) { if (i != 0) buf_appendf(buf, ","); @@ -4021,22 +3983,22 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) { } case TypeTableEntryIdStruct: { - buf_appendf(buf, "(struct %s constant)", buf_ptr(&canon_type->name)); + buf_appendf(buf, "(struct %s constant)", buf_ptr(&type_entry->name)); return; } case TypeTableEntryIdEnum: { - buf_appendf(buf, "(enum %s constant)", buf_ptr(&canon_type->name)); + buf_appendf(buf, "(enum %s constant)", buf_ptr(&type_entry->name)); return; } case TypeTableEntryIdErrorUnion: { - buf_appendf(buf, "(error union %s constant)", buf_ptr(&canon_type->name)); + buf_appendf(buf, "(error union %s constant)", buf_ptr(&type_entry->name)); return; } case TypeTableEntryIdUnion: { - buf_appendf(buf, "(union %s constant)", buf_ptr(&canon_type->name)); + buf_appendf(buf, "(union %s constant)", buf_ptr(&type_entry->name)); return; } case TypeTableEntryIdPureError: @@ -4046,7 +4008,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) { } case TypeTableEntryIdEnumTag: { - TypeTableEntry *enum_type = canon_type->data.enum_tag.enum_type; + TypeTableEntry *enum_type = type_entry->data.enum_tag.enum_type; TypeEnumField *field = &enum_type->data.enumeration.fields[const_val->data.x_bignum.data.x_uint]; buf_appendf(buf, "%s.%s", buf_ptr(&enum_type->name), buf_ptr(field->name)); return; @@ -4095,6 +4057,7 @@ uint32_t type_id_hash(TypeId x) { switch (x.id) { case TypeTableEntryIdInvalid: case TypeTableEntryIdVar: + case TypeTableEntryIdOpaque: case TypeTableEntryIdMetaType: case TypeTableEntryIdVoid: case TypeTableEntryIdBool: @@ -4112,7 +4075,6 @@ uint32_t type_id_hash(TypeId x) { case TypeTableEntryIdEnumTag: case TypeTableEntryIdUnion: case TypeTableEntryIdFn: - case TypeTableEntryIdTypeDecl: case TypeTableEntryIdNamespace: case TypeTableEntryIdBlock: case TypeTableEntryIdBoundFn: @@ -4157,11 +4119,11 @@ bool type_id_eql(TypeId a, TypeId b) { case TypeTableEntryIdEnumTag: case TypeTableEntryIdUnion: case TypeTableEntryIdFn: - case TypeTableEntryIdTypeDecl: case TypeTableEntryIdNamespace: case TypeTableEntryIdBlock: case TypeTableEntryIdBoundFn: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: zig_unreachable(); case TypeTableEntryIdPointer: return a.data.pointer.child_type == b.data.pointer.child_type && @@ -4211,10 +4173,10 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) { ConstParent *get_const_val_parent(ConstExprValue *value) { assert(value->type); - TypeTableEntry *canon_type = get_underlying_type(value->type); - if (canon_type->id == TypeTableEntryIdArray) { + TypeTableEntry *type_entry = value->type; + if (type_entry->id == TypeTableEntryIdArray) { return &value->data.x_array.parent; - } else if (canon_type->id == TypeTableEntryIdStruct) { + } else if (type_entry->id == TypeTableEntryIdStruct) { return &value->data.x_struct.parent; } return nullptr; diff --git a/src/analyze.hpp b/src/analyze.hpp index e16ad0527c..de0d0bc933 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -24,7 +24,6 @@ TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint32_t size_in_b TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits); TypeTableEntry **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type); TypeTableEntry *get_c_int_type(CodeGen *g, CIntType c_int_type); -TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *child_type); TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id); TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type); TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size); @@ -34,11 +33,11 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKi TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x); TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type); TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry); +TypeTableEntry *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *name); bool handle_is_ptr(TypeTableEntry *type_entry); void find_libc_include_path(CodeGen *g); void find_libc_lib_path(CodeGen *g); -TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry); bool type_has_bits(TypeTableEntry *type_entry); diff --git a/src/ast_render.cpp b/src/ast_render.cpp index faebd8f7a3..3f47c1379c 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -166,8 +166,6 @@ static const char *node_type_str(NodeType node_type) { return "Defer"; case NodeTypeVariableDeclaration: return "VariableDeclaration"; - case NodeTypeTypeDecl: - return "TypeDecl"; case NodeTypeErrorValueDecl: return "ErrorValueDecl"; case NodeTypeTestDecl: @@ -234,8 +232,6 @@ static const char *node_type_str(NodeType node_type) { return "ArrayType"; case NodeTypeErrorType: return "ErrorType"; - case NodeTypeTypeLiteral: - return "TypeLiteral"; case NodeTypeVarLiteral: return "VarLiteral"; case NodeTypeTryExpr: @@ -394,7 +390,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { if (child->type == NodeTypeUse || child->type == NodeTypeVariableDeclaration || - child->type == NodeTypeTypeDecl || child->type == NodeTypeErrorValueDecl || child->type == NodeTypeFnProto) { @@ -507,14 +502,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { } break; } - case NodeTypeTypeDecl: - { - const char *pub_str = visib_mod_string(node->data.type_decl.visib_mod); - const char *var_name = buf_ptr(node->data.type_decl.symbol); - fprintf(ar->f, "%stype %s = ", pub_str, var_name); - render_node_grouped(ar, node->data.type_decl.child_type); - break; - } case NodeTypeBinOpExpr: if (!grouped) fprintf(ar->f, "("); render_node_ungrouped(ar, node->data.bin_op_expr.op1); @@ -668,9 +655,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { case NodeTypeErrorType: fprintf(ar->f, "error"); break; - case NodeTypeTypeLiteral: - fprintf(ar->f, "type"); - break; case NodeTypeVarLiteral: fprintf(ar->f, "var"); break; @@ -1034,6 +1018,12 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) { fprintf(ar->f, "union {"); fprintf(ar->f, "TODO"); fprintf(ar->f, "}"); + } else if (type_entry->id == TypeTableEntryIdOpaque) { + if (buf_eql_buf(&type_entry->name, name)) { + fprintf(ar->f, "@OpaqueType()"); + } else { + fprintf(ar->f, "%s", buf_ptr(&type_entry->name)); + } } else { fprintf(ar->f, "%s", buf_ptr(&type_entry->name)); } @@ -1047,15 +1037,6 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) { fprintf(ar->f, ";\n"); } -static void ast_render_tld_typedef(AstRender *ar, Buf *name, TldTypeDef *tld_typedef) { - TypeTableEntry *type_entry = tld_typedef->type_entry; - TypeTableEntry *canon_type = get_underlying_type(type_entry); - - fprintf(ar->f, "pub type "); - print_symbol(ar, name); - fprintf(ar->f, " = %s;\n", buf_ptr(&canon_type->name)); -} - void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) { AstRender ar = {0}; ar.f = f; @@ -1087,9 +1068,6 @@ void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) { case TldIdContainer: fprintf(stdout, "container\n"); break; - case TldIdTypeDef: - ast_render_tld_typedef(&ar, entry->key, (TldTypeDef *)tld); - break; case TldIdCompTime: fprintf(stdout, "comptime\n"); break; diff --git a/src/codegen.cpp b/src/codegen.cpp index ea68e0c304..f36c45c69a 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -649,12 +649,9 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val, LLVMPositionBuilderAtEnd(g->builder, ok_block); } -static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, TypeTableEntry *actual_type_non_canon, - TypeTableEntry *wanted_type_non_canon, LLVMValueRef expr_val) +static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, TypeTableEntry *actual_type, + TypeTableEntry *wanted_type, LLVMValueRef expr_val) { - TypeTableEntry *actual_type = get_underlying_type(actual_type_non_canon); - TypeTableEntry *wanted_type = get_underlying_type(wanted_type_non_canon); - assert(actual_type->id == wanted_type->id); uint64_t actual_bits; @@ -852,7 +849,7 @@ static LLVMValueRef gen_struct_memcpy(CodeGen *g, LLVMValueRef src, LLVMValueRef static LLVMValueRef gen_assign_raw(CodeGen *g, LLVMValueRef ptr, TypeTableEntry *ptr_type, LLVMValueRef value) { - TypeTableEntry *child_type = get_underlying_type(ptr_type->data.pointer.child_type); + TypeTableEntry *child_type = ptr_type->data.pointer.child_type; if (!type_has_bits(child_type)) return nullptr; @@ -1111,7 +1108,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, IrInstruction *op2 = bin_op_instruction->op2; assert(op1->value.type == op2->value.type); - TypeTableEntry *canon_type = get_underlying_type(op1->value.type); + TypeTableEntry *type_entry = op1->value.type; bool want_debug_safety = bin_op_instruction->safety_check_on && ir_want_debug_safety(g, &bin_op_instruction->base); @@ -1133,22 +1130,22 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, case IrBinOpCmpGreaterThan: case IrBinOpCmpLessOrEq: case IrBinOpCmpGreaterOrEq: - if (canon_type->id == TypeTableEntryIdFloat) { + if (type_entry->id == TypeTableEntryIdFloat) { LLVMRealPredicate pred = cmp_op_to_real_predicate(op_id); return LLVMBuildFCmp(g->builder, pred, op1_value, op2_value, ""); - } else if (canon_type->id == TypeTableEntryIdInt) { - LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, canon_type->data.integral.is_signed); + } else if (type_entry->id == TypeTableEntryIdInt) { + LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, type_entry->data.integral.is_signed); return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, ""); - } else if (canon_type->id == TypeTableEntryIdEnum) { - if (canon_type->data.enumeration.gen_field_count == 0) { + } else if (type_entry->id == TypeTableEntryIdEnum) { + if (type_entry->data.enumeration.gen_field_count == 0) { LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false); return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, ""); } else { zig_unreachable(); } - } else if (canon_type->id == TypeTableEntryIdPureError || - canon_type->id == TypeTableEntryIdPointer || - canon_type->id == TypeTableEntryIdBool) + } else if (type_entry->id == TypeTableEntryIdPureError || + type_entry->id == TypeTableEntryIdPointer || + type_entry->id == TypeTableEntryIdBool) { LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false); return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, ""); @@ -1157,15 +1154,15 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, } case IrBinOpAdd: case IrBinOpAddWrap: - if (canon_type->id == TypeTableEntryIdFloat) { + if (type_entry->id == TypeTableEntryIdFloat) { return LLVMBuildFAdd(g->builder, op1_value, op2_value, ""); - } else if (canon_type->id == TypeTableEntryIdInt) { + } else if (type_entry->id == TypeTableEntryIdInt) { bool is_wrapping = (op_id == IrBinOpAddWrap); if (is_wrapping) { return LLVMBuildAdd(g->builder, op1_value, op2_value, ""); } else if (want_debug_safety) { - return gen_overflow_op(g, canon_type, AddSubMulAdd, op1_value, op2_value); - } else if (canon_type->data.integral.is_signed) { + return gen_overflow_op(g, type_entry, AddSubMulAdd, op1_value, op2_value); + } else if (type_entry->data.integral.is_signed) { return LLVMBuildNSWAdd(g->builder, op1_value, op2_value, ""); } else { return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, ""); @@ -1182,36 +1179,36 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, case IrBinOpBitShiftLeft: case IrBinOpBitShiftLeftWrap: { - assert(canon_type->id == TypeTableEntryIdInt); + assert(type_entry->id == TypeTableEntryIdInt); bool is_wrapping = (op_id == IrBinOpBitShiftLeftWrap); if (is_wrapping) { return LLVMBuildShl(g->builder, op1_value, op2_value, ""); } else if (want_debug_safety) { - return gen_overflow_shl_op(g, canon_type, op1_value, op2_value); - } else if (canon_type->data.integral.is_signed) { + return gen_overflow_shl_op(g, type_entry, op1_value, op2_value); + } else if (type_entry->data.integral.is_signed) { return ZigLLVMBuildNSWShl(g->builder, op1_value, op2_value, ""); } else { return ZigLLVMBuildNUWShl(g->builder, op1_value, op2_value, ""); } } case IrBinOpBitShiftRight: - assert(canon_type->id == TypeTableEntryIdInt); - if (canon_type->data.integral.is_signed) { + assert(type_entry->id == TypeTableEntryIdInt); + if (type_entry->data.integral.is_signed) { return LLVMBuildAShr(g->builder, op1_value, op2_value, ""); } else { return LLVMBuildLShr(g->builder, op1_value, op2_value, ""); } case IrBinOpSub: case IrBinOpSubWrap: - if (canon_type->id == TypeTableEntryIdFloat) { + if (type_entry->id == TypeTableEntryIdFloat) { return LLVMBuildFSub(g->builder, op1_value, op2_value, ""); - } else if (canon_type->id == TypeTableEntryIdInt) { + } else if (type_entry->id == TypeTableEntryIdInt) { bool is_wrapping = (op_id == IrBinOpSubWrap); if (is_wrapping) { return LLVMBuildSub(g->builder, op1_value, op2_value, ""); } else if (want_debug_safety) { - return gen_overflow_op(g, canon_type, AddSubMulSub, op1_value, op2_value); - } else if (canon_type->data.integral.is_signed) { + return gen_overflow_op(g, type_entry, AddSubMulSub, op1_value, op2_value); + } else if (type_entry->data.integral.is_signed) { return LLVMBuildNSWSub(g->builder, op1_value, op2_value, ""); } else { return LLVMBuildNUWSub(g->builder, op1_value, op2_value, ""); @@ -1221,15 +1218,15 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, } case IrBinOpMult: case IrBinOpMultWrap: - if (canon_type->id == TypeTableEntryIdFloat) { + if (type_entry->id == TypeTableEntryIdFloat) { return LLVMBuildFMul(g->builder, op1_value, op2_value, ""); - } else if (canon_type->id == TypeTableEntryIdInt) { + } else if (type_entry->id == TypeTableEntryIdInt) { bool is_wrapping = (op_id == IrBinOpMultWrap); if (is_wrapping) { return LLVMBuildMul(g->builder, op1_value, op2_value, ""); } else if (want_debug_safety) { - return gen_overflow_op(g, canon_type, AddSubMulMul, op1_value, op2_value); - } else if (canon_type->data.integral.is_signed) { + return gen_overflow_op(g, type_entry, AddSubMulMul, op1_value, op2_value); + } else if (type_entry->data.integral.is_signed) { return LLVMBuildNSWMul(g->builder, op1_value, op2_value, ""); } else { return LLVMBuildNUWMul(g->builder, op1_value, op2_value, ""); @@ -1238,9 +1235,9 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, zig_unreachable(); } case IrBinOpDiv: - return gen_div(g, want_debug_safety, op1_value, op2_value, canon_type, false); + return gen_div(g, want_debug_safety, op1_value, op2_value, type_entry, false); case IrBinOpRem: - return gen_rem(g, want_debug_safety, op1_value, op2_value, canon_type); + return gen_rem(g, want_debug_safety, op1_value, op2_value, type_entry); } zig_unreachable(); } @@ -1644,7 +1641,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir LLVMValueRef value = ir_llvm_value(g, instruction->value); assert(instruction->ptr->value.type->id == TypeTableEntryIdPointer); - TypeTableEntry *ptr_type = get_underlying_type(instruction->ptr->value.type); + TypeTableEntry *ptr_type = instruction->ptr->value.type; gen_assign_raw(g, ptr, ptr_type, value); @@ -1685,9 +1682,9 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI if (array_ptr_type->data.pointer.unaligned_bit_count != 0) { return array_ptr_ptr; } - TypeTableEntry *canon_child_type = get_underlying_type(array_type->data.array.child_type); - if (canon_child_type->id == TypeTableEntryIdStruct && - canon_child_type->data.structure.layout == ContainerLayoutPacked) + TypeTableEntry *child_type = array_type->data.array.child_type; + if (child_type->id == TypeTableEntryIdStruct && + 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) { @@ -1701,7 +1698,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI byte_offset }; LLVMValueRef elem_byte_ptr = LLVMBuildInBoundsGEP(g->builder, u8_array_ptr, indices, 1, ""); - return LLVMBuildBitCast(g->builder, elem_byte_ptr, LLVMPointerType(canon_child_type->type_ref, 0), ""); + return LLVMBuildBitCast(g->builder, elem_byte_ptr, LLVMPointerType(child_type->type_ref, 0), ""); } } LLVMValueRef indices[] = { @@ -2206,8 +2203,8 @@ static LLVMValueRef ir_render_div_exact(CodeGen *g, IrExecutable *executable, Ir static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutable *executable, IrInstructionTruncate *instruction) { LLVMValueRef target_val = ir_llvm_value(g, instruction->target); - TypeTableEntry *dest_type = get_underlying_type(instruction->base.value.type); - TypeTableEntry *src_type = get_underlying_type(instruction->target->value.type); + TypeTableEntry *dest_type = instruction->base.value.type; + TypeTableEntry *src_type = instruction->target->value.type; if (dest_type == src_type) { // no-op return target_val; @@ -2228,7 +2225,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, ""); - TypeTableEntry *ptr_type = get_underlying_type(instruction->dest_ptr->value.type); + TypeTableEntry *ptr_type = instruction->dest_ptr->value.type; assert(ptr_type->id == TypeTableEntryIdPointer); LLVMValueRef is_volatile = ptr_type->data.pointer.is_volatile ? @@ -2256,8 +2253,8 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrIns LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, ""); LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, ptr_u8, ""); - TypeTableEntry *dest_ptr_type = get_underlying_type(instruction->dest_ptr->value.type); - TypeTableEntry *src_ptr_type = get_underlying_type(instruction->src_ptr->value.type); + TypeTableEntry *dest_ptr_type = instruction->dest_ptr->value.type; + TypeTableEntry *src_ptr_type = instruction->src_ptr->value.type; assert(dest_ptr_type->id == TypeTableEntryIdPointer); assert(src_ptr_type->id == TypeTableEntryIdPointer); @@ -2407,7 +2404,7 @@ static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutable *executable } static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstructionOverflowOp *instruction) { - TypeTableEntry *int_type = get_underlying_type(instruction->result_ptr_type); + TypeTableEntry *int_type = instruction->result_ptr_type; assert(int_type->id == TypeTableEntryIdInt); LLVMValueRef op1 = ir_llvm_value(g, instruction->op1); @@ -2444,7 +2441,7 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable, return render_shl_with_overflow(g, instruction); } - TypeTableEntry *int_type = get_underlying_type(instruction->result_ptr_type); + TypeTableEntry *int_type = instruction->result_ptr_type; assert(int_type->id == TypeTableEntryIdInt); LLVMValueRef fn_val = get_int_overflow_fn(g, int_type, add_sub_mul); @@ -2467,8 +2464,8 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable, } static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrInstructionTestErr *instruction) { - TypeTableEntry *err_union_type = get_underlying_type(instruction->value->value.type); - TypeTableEntry *child_type = get_underlying_type(err_union_type->data.error.child_type); + TypeTableEntry *err_union_type = instruction->value->value.type; + TypeTableEntry *child_type = err_union_type->data.error.child_type; LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->value); LLVMValueRef err_val; @@ -2484,11 +2481,11 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI } static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrCode *instruction) { - TypeTableEntry *ptr_type = get_underlying_type(instruction->value->value.type); + TypeTableEntry *ptr_type = instruction->value->value.type; assert(ptr_type->id == TypeTableEntryIdPointer); bool is_volatile = ptr_type->data.pointer.is_volatile; - TypeTableEntry *err_union_type = get_underlying_type(ptr_type->data.pointer.child_type); - TypeTableEntry *child_type = get_underlying_type(err_union_type->data.error.child_type); + TypeTableEntry *err_union_type = ptr_type->data.pointer.child_type; + TypeTableEntry *child_type = err_union_type->data.error.child_type; LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value); LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, is_volatile); @@ -2501,11 +2498,11 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab } static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable, IrInstructionUnwrapErrPayload *instruction) { - TypeTableEntry *ptr_type = get_underlying_type(instruction->value->value.type); + TypeTableEntry *ptr_type = instruction->value->value.type; assert(ptr_type->id == TypeTableEntryIdPointer); bool is_volatile = ptr_type->data.pointer.is_volatile; - TypeTableEntry *err_union_type = get_underlying_type(ptr_type->data.pointer.child_type); - TypeTableEntry *child_type = get_underlying_type(err_union_type->data.error.child_type); + TypeTableEntry *err_union_type = ptr_type->data.pointer.child_type; + TypeTableEntry *child_type = err_union_type->data.error.child_type; LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value); LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, is_volatile); @@ -2941,9 +2938,9 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con break; } - TypeTableEntry *canon_type = get_underlying_type(const_val->type); - assert(!canon_type->zero_bits); - switch (canon_type->id) { + TypeTableEntry *type_entry = const_val->type; + assert(!type_entry->zero_bits); + switch (type_entry->id) { case TypeTableEntryIdInvalid: case TypeTableEntryIdVar: case TypeTableEntryIdMetaType: @@ -2956,12 +2953,12 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con case TypeTableEntryIdPureError: case TypeTableEntryIdEnum: case TypeTableEntryIdEnumTag: - case TypeTableEntryIdTypeDecl: case TypeTableEntryIdNamespace: case TypeTableEntryIdBlock: case TypeTableEntryIdBoundFn: case TypeTableEntryIdArgTuple: case TypeTableEntryIdVoid: + case TypeTableEntryIdOpaque: zig_unreachable(); case TypeTableEntryIdBool: return LLVMConstInt(big_int_type_ref, const_val->data.x_bool ? 1 : 0, false); @@ -2975,7 +2972,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con { LLVMValueRef float_val = gen_const_val(g, const_val); LLVMValueRef int_val = LLVMConstFPToUI(float_val, - LLVMIntType((unsigned)canon_type->data.floating.bit_count)); + LLVMIntType((unsigned)type_entry->data.floating.bit_count)); return LLVMConstZExt(int_val, big_int_type_ref); } case TypeTableEntryIdPointer: @@ -2992,11 +2989,11 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con zig_panic("TODO bit pack a union"); case TypeTableEntryIdStruct: { - assert(canon_type->data.structure.layout == ContainerLayoutPacked); + assert(type_entry->data.structure.layout == ContainerLayoutPacked); LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false); - for (size_t i = 0; i < canon_type->data.structure.src_field_count; i += 1) { - TypeStructField *field = &canon_type->data.structure.fields[i]; + for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { + TypeStructField *field = &type_entry->data.structure.fields[i]; if (field->gen_index == SIZE_MAX) { continue; } @@ -3012,37 +3009,35 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con } static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { - TypeTableEntry *canon_type = get_underlying_type(const_val->type); - assert(!canon_type->zero_bits); + TypeTableEntry *type_entry = const_val->type; + assert(!type_entry->zero_bits); switch (const_val->special) { case ConstValSpecialRuntime: zig_unreachable(); case ConstValSpecialUndef: - return LLVMGetUndef(canon_type->type_ref); + return LLVMGetUndef(type_entry->type_ref); case ConstValSpecialStatic: break; } - switch (canon_type->id) { - case TypeTableEntryIdTypeDecl: - zig_unreachable(); + switch (type_entry->id) { case TypeTableEntryIdInt: case TypeTableEntryIdEnumTag: - return LLVMConstInt(canon_type->type_ref, bignum_to_twos_complement(&const_val->data.x_bignum), false); + return LLVMConstInt(type_entry->type_ref, bignum_to_twos_complement(&const_val->data.x_bignum), false); case TypeTableEntryIdPureError: assert(const_val->data.x_pure_err); return LLVMConstInt(g->builtin_types.entry_pure_error->type_ref, const_val->data.x_pure_err->value, false); case TypeTableEntryIdFloat: if (const_val->data.x_bignum.kind == BigNumKindFloat) { - return LLVMConstReal(canon_type->type_ref, const_val->data.x_bignum.data.x_float); + return LLVMConstReal(type_entry->type_ref, const_val->data.x_bignum.data.x_float); } else { double x = (double)const_val->data.x_bignum.data.x_uint; if (const_val->data.x_bignum.is_negative) { x = -x; } - return LLVMConstReal(canon_type->type_ref, x); + return LLVMConstReal(type_entry->type_ref, x); } case TypeTableEntryIdBool: if (const_val->data.x_bool) { @@ -3052,7 +3047,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { } case TypeTableEntryIdMaybe: { - TypeTableEntry *child_type = canon_type->data.maybe.child_type; + TypeTableEntry *child_type = type_entry->data.maybe.child_type; if (child_type->zero_bits) { return LLVMConstInt(LLVMInt1Type(), const_val->data.x_maybe ? 1 : 0, false); } else if (child_type->id == TypeTableEntryIdPointer || @@ -3082,12 +3077,12 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { } case TypeTableEntryIdStruct: { - LLVMValueRef *fields = allocate(canon_type->data.structure.gen_field_count); - size_t src_field_count = canon_type->data.structure.src_field_count; - if (canon_type->data.structure.layout == ContainerLayoutPacked) { + LLVMValueRef *fields = allocate(type_entry->data.structure.gen_field_count); + size_t src_field_count = type_entry->data.structure.src_field_count; + if (type_entry->data.structure.layout == ContainerLayoutPacked) { size_t src_field_index = 0; while (src_field_index < src_field_count) { - TypeStructField *type_struct_field = &canon_type->data.structure.fields[src_field_index]; + TypeStructField *type_struct_field = &type_entry->data.structure.fields[src_field_index]; if (type_struct_field->gen_index == SIZE_MAX) { src_field_index += 1; continue; @@ -3095,7 +3090,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { size_t src_field_index_end = src_field_index + 1; for (; src_field_index_end < src_field_count; src_field_index_end += 1) { - TypeStructField *it_field = &canon_type->data.structure.fields[src_field_index_end]; + TypeStructField *it_field = &type_entry->data.structure.fields[src_field_index_end]; if (it_field->gen_index != type_struct_field->gen_index) break; } @@ -3104,11 +3099,11 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { fields[type_struct_field->gen_index] = gen_const_val(g, &const_val->data.x_struct.fields[src_field_index]); } else { - LLVMTypeRef big_int_type_ref = LLVMStructGetTypeAtIndex(canon_type->type_ref, + LLVMTypeRef big_int_type_ref = LLVMStructGetTypeAtIndex(type_entry->type_ref, (unsigned)type_struct_field->gen_index); LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false); for (size_t i = src_field_index; i < src_field_index_end; i += 1) { - TypeStructField *it_field = &canon_type->data.structure.fields[i]; + TypeStructField *it_field = &type_entry->data.structure.fields[i]; if (it_field->gen_index == SIZE_MAX) { continue; } @@ -3126,14 +3121,14 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { } } else { for (uint32_t i = 0; i < src_field_count; i += 1) { - TypeStructField *type_struct_field = &canon_type->data.structure.fields[i]; + TypeStructField *type_struct_field = &type_entry->data.structure.fields[i]; if (type_struct_field->gen_index == SIZE_MAX) { continue; } fields[type_struct_field->gen_index] = gen_const_val(g, &const_val->data.x_struct.fields[i]); } } - return LLVMConstNamedStruct(canon_type->type_ref, fields, canon_type->data.structure.gen_field_count); + return LLVMConstNamedStruct(type_entry->type_ref, fields, type_entry->data.structure.gen_field_count); } case TypeTableEntryIdUnion: { @@ -3141,7 +3136,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { } case TypeTableEntryIdArray: { - uint64_t len = canon_type->data.array.len; + uint64_t len = type_entry->data.array.len; LLVMValueRef *values = allocate(len); for (uint64_t i = 0; i < len; i += 1) { ConstExprValue *elem_value = &const_val->data.x_array.elements[i]; @@ -3151,13 +3146,13 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { } case TypeTableEntryIdEnum: { - LLVMTypeRef tag_type_ref = canon_type->data.enumeration.tag_type->type_ref; + LLVMTypeRef tag_type_ref = type_entry->data.enumeration.tag_type->type_ref; LLVMValueRef tag_value = LLVMConstInt(tag_type_ref, const_val->data.x_enum.tag, false); - if (canon_type->data.enumeration.gen_field_count == 0) { + if (type_entry->data.enumeration.gen_field_count == 0) { return tag_value; } else { - TypeTableEntry *union_type = canon_type->data.enumeration.union_type; - TypeEnumField *enum_field = &canon_type->data.enumeration.fields[const_val->data.x_enum.tag]; + TypeTableEntry *union_type = type_entry->data.enumeration.union_type; + TypeEnumField *enum_field = &type_entry->data.enumeration.fields[const_val->data.x_enum.tag]; assert(enum_field->value == const_val->data.x_enum.tag); LLVMValueRef union_value; if (type_has_bits(enum_field->type_entry)) { @@ -3261,7 +3256,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { } case TypeTableEntryIdErrorUnion: { - TypeTableEntry *child_type = canon_type->data.error.child_type; + TypeTableEntry *child_type = type_entry->data.error.child_type; if (!type_has_bits(child_type)) { uint64_t value = const_val->data.x_err_union.err ? const_val->data.x_err_union.err->value : 0; return LLVMConstInt(g->err_tag_type->type_ref, value, false); @@ -3296,6 +3291,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { case TypeTableEntryIdBoundFn: case TypeTableEntryIdVar: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: zig_unreachable(); } @@ -4107,7 +4103,7 @@ static void define_builtin_types(CodeGen *g) { g->builtin_types.entry_i64 = get_int_type(g, true, 64); { - g->builtin_types.entry_c_void = get_typedecl_type(g, "c_void", g->builtin_types.entry_u8); + g->builtin_types.entry_c_void = get_opaque_type(g, nullptr, nullptr, "c_void"); g->primitive_type_table.put(&g->builtin_types.entry_c_void->name, g->builtin_types.entry_c_void); } @@ -4747,6 +4743,7 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) { zig_unreachable(); } } + case TypeTableEntryIdOpaque: case TypeTableEntryIdArray: case TypeTableEntryIdStruct: case TypeTableEntryIdErrorUnion: @@ -4754,7 +4751,6 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) { case TypeTableEntryIdEnum: case TypeTableEntryIdUnion: case TypeTableEntryIdFn: - case TypeTableEntryIdTypeDecl: case TypeTableEntryIdEnumTag: zig_panic("TODO implement get_c_type for more types"); case TypeTableEntryIdInvalid: diff --git a/src/ir.cpp b/src/ir.cpp index 53f324e372..bef2571186 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -5323,11 +5323,6 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *scope, AstNode *nod return ir_build_br(irb, scope, node, dest_block, is_comptime); } -static IrInstruction *ir_gen_type_literal(IrBuilder *irb, Scope *scope, AstNode *node) { - assert(node->type == NodeTypeTypeLiteral); - return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_type); -} - static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *node) { assert(node->type == NodeTypeErrorType); return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_pure_error); @@ -5600,8 +5595,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop return ir_lval_wrap(irb, scope, ir_gen_goto(irb, scope, node), lval); case NodeTypeCompTime: return ir_gen_comptime(irb, scope, node, lval); - case NodeTypeTypeLiteral: - return ir_lval_wrap(irb, scope, ir_gen_type_literal(irb, scope, node), lval); case NodeTypeErrorType: return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval); case NodeTypeBreak: @@ -5628,8 +5621,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop zig_panic("TODO IR gen NodeTypeFnDecl"); case NodeTypeErrorValueDecl: zig_panic("TODO IR gen NodeTypeErrorValueDecl"); - case NodeTypeTypeDecl: - zig_panic("TODO IR gen NodeTypeTypeDecl"); case NodeTypeTestDecl: zig_panic("TODO IR gen NodeTypeTestDecl"); } @@ -5753,13 +5744,6 @@ static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction, return ir_add_error_node(ira, source_instruction->source_node, msg); } -static void ir_add_typedef_err_note(IrAnalyze *ira, ErrorMsg *msg, TypeTableEntry *type_entry) { - if (type_entry->id == TypeTableEntryIdTypeDecl) { - // requires tracking source_node in the typedecl type - zig_panic("TODO add error note about typedecls"); - } -} - static IrInstruction *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec) { IrBasicBlock *bb = exec->basic_block_list.at(0); for (size_t i = 0; i < bb->instruction_list.length; i += 1) { @@ -5791,27 +5775,25 @@ static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *so } static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type) { - TypeTableEntry *other_type_underlying = get_underlying_type(other_type); - - if (type_is_invalid(other_type_underlying)) { + if (type_is_invalid(other_type)) { return false; } ConstExprValue *const_val = &instruction->value; assert(const_val->special != ConstValSpecialRuntime); - if (other_type_underlying->id == TypeTableEntryIdFloat) { + if (other_type->id == TypeTableEntryIdFloat) { return true; - } else if (other_type_underlying->id == TypeTableEntryIdInt && + } else if (other_type->id == TypeTableEntryIdInt && const_val->data.x_bignum.kind == BigNumKindInt) { - if (bignum_fits_in_bits(&const_val->data.x_bignum, other_type_underlying->data.integral.bit_count, - other_type_underlying->data.integral.is_signed)) + if (bignum_fits_in_bits(&const_val->data.x_bignum, other_type->data.integral.bit_count, + other_type->data.integral.is_signed)) { return true; } - } else if ((other_type_underlying->id == TypeTableEntryIdNumLitFloat && + } else if ((other_type->id == TypeTableEntryIdNumLitFloat && const_val->data.x_bignum.kind == BigNumKindFloat) || - (other_type_underlying->id == TypeTableEntryIdNumLitInt && + (other_type->id == TypeTableEntryIdNumLitInt && const_val->data.x_bignum.kind == BigNumKindInt)) { return true; @@ -6890,12 +6872,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst TypeTableEntry *wanted_type, IrInstruction *value) { TypeTableEntry *actual_type = value->value.type; - TypeTableEntry *wanted_type_canon = get_underlying_type(wanted_type); - TypeTableEntry *actual_type_canon = get_underlying_type(actual_type); - TypeTableEntry *usize_type = ira->codegen->builtin_types.entry_usize; - if (type_is_invalid(wanted_type_canon) || type_is_invalid(actual_type_canon)) { + if (type_is_invalid(wanted_type) || type_is_invalid(actual_type)) { return ira->codegen->invalid_instruction; } @@ -6908,36 +6887,36 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst } // explicit cast from bool to int - if (wanted_type_canon->id == TypeTableEntryIdInt && - actual_type_canon->id == TypeTableEntryIdBool) + if (wanted_type->id == TypeTableEntryIdInt && + actual_type->id == TypeTableEntryIdBool) { return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpBoolToInt, false); } // explicit cast from pointer to usize - if (wanted_type_canon == usize_type && type_is_codegen_pointer(actual_type_canon)) { + if (wanted_type == usize_type && type_is_codegen_pointer(actual_type)) { return ir_analyze_ptr_to_int(ira, source_instr, value, wanted_type); } // explicit widening or shortening cast - if ((wanted_type_canon->id == TypeTableEntryIdInt && - actual_type_canon->id == TypeTableEntryIdInt) || - (wanted_type_canon->id == TypeTableEntryIdFloat && - actual_type_canon->id == TypeTableEntryIdFloat)) + if ((wanted_type->id == TypeTableEntryIdInt && + actual_type->id == TypeTableEntryIdInt) || + (wanted_type->id == TypeTableEntryIdFloat && + actual_type->id == TypeTableEntryIdFloat)) { return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); } // explicit cast from int to float - if (wanted_type_canon->id == TypeTableEntryIdFloat && - actual_type_canon->id == TypeTableEntryIdInt) + if (wanted_type->id == TypeTableEntryIdFloat && + actual_type->id == TypeTableEntryIdInt) { return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpIntToFloat, false); } // explicit cast from float to int - if (wanted_type_canon->id == TypeTableEntryIdInt && - actual_type_canon->id == TypeTableEntryIdFloat) + if (wanted_type->id == TypeTableEntryIdInt && + actual_type->id == TypeTableEntryIdFloat) { return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpFloatToInt, false); } @@ -7070,17 +7049,17 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ira->codegen->invalid_instruction; return cast2; - } else if (ir_num_lit_fits_in_other_type(ira, value, wanted_type_canon)) { + } else if (ir_num_lit_fits_in_other_type(ira, value, wanted_type)) { CastOp op; if ((actual_type->id == TypeTableEntryIdNumLitFloat && - wanted_type_canon->id == TypeTableEntryIdFloat) || + wanted_type->id == TypeTableEntryIdFloat) || (actual_type->id == TypeTableEntryIdNumLitInt && - wanted_type_canon->id == TypeTableEntryIdInt)) + wanted_type->id == TypeTableEntryIdInt)) { op = CastOpNoop; - } else if (wanted_type_canon->id == TypeTableEntryIdInt) { + } else if (wanted_type->id == TypeTableEntryIdInt) { op = CastOpFloatToInt; - } else if (wanted_type_canon->id == TypeTableEntryIdFloat) { + } else if (wanted_type->id == TypeTableEntryIdFloat) { op = CastOpIntToFloat; } else { zig_unreachable(); @@ -7475,7 +7454,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp case TypeTableEntryIdPointer: case TypeTableEntryIdPureError: case TypeTableEntryIdFn: - case TypeTableEntryIdTypeDecl: + case TypeTableEntryIdOpaque: case TypeTableEntryIdNamespace: case TypeTableEntryIdBlock: case TypeTableEntryIdBoundFn: @@ -7709,15 +7688,14 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, bin_op_instruction->base.source_node, instructions, 2); if (type_is_invalid(resolved_type)) return resolved_type; - TypeTableEntry *canon_resolved_type = get_underlying_type(resolved_type); IrBinOp op_id = bin_op_instruction->op_id; - if (canon_resolved_type->id == TypeTableEntryIdInt || - canon_resolved_type->id == TypeTableEntryIdNumLitInt) + if (resolved_type->id == TypeTableEntryIdInt || + resolved_type->id == TypeTableEntryIdNumLitInt) { // int - } else if ((canon_resolved_type->id == TypeTableEntryIdFloat || - canon_resolved_type->id == TypeTableEntryIdNumLitFloat) && + } else if ((resolved_type->id == TypeTableEntryIdFloat || + resolved_type->id == TypeTableEntryIdNumLitFloat) && (op_id == IrBinOpAdd || op_id == IrBinOpSub || op_id == IrBinOpMult || @@ -7751,7 +7729,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp bin_op_instruction->base.other = &bin_op_instruction->base; int err; - if ((err = ir_eval_math_op(canon_resolved_type, op1_val, op_id, op2_val, out_val))) { + if ((err = ir_eval_math_op(resolved_type, op1_val, op_id, op2_val, out_val))) { if (err == ErrorDivByZero) { ir_add_error_node(ira, bin_op_instruction->base.source_node, buf_sprintf("division by zero is undefined")); @@ -7776,13 +7754,13 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruction) { IrInstruction *op1 = instruction->op1->other; - TypeTableEntry *op1_canon_type = get_underlying_type(op1->value.type); - if (type_is_invalid(op1_canon_type)) + TypeTableEntry *op1_type = op1->value.type; + if (type_is_invalid(op1_type)) return ira->codegen->builtin_types.entry_invalid; IrInstruction *op2 = instruction->op2->other; - TypeTableEntry *op2_canon_type = get_underlying_type(op2->value.type); - if (type_is_invalid(op2_canon_type)) + TypeTableEntry *op2_type = op2->value.type; + if (type_is_invalid(op2_type)) return ira->codegen->builtin_types.entry_invalid; ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); @@ -7797,22 +7775,22 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * size_t op1_array_index; size_t op1_array_end; TypeTableEntry *child_type; - if (op1_canon_type->id == TypeTableEntryIdArray) { - child_type = op1_canon_type->data.array.child_type; + if (op1_type->id == TypeTableEntryIdArray) { + child_type = op1_type->data.array.child_type; op1_array_val = op1_val; op1_array_index = 0; - op1_array_end = op1_canon_type->data.array.len; - } else if (op1_canon_type->id == TypeTableEntryIdPointer && - op1_canon_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && + op1_array_end = op1_type->data.array.len; + } else if (op1_type->id == TypeTableEntryIdPointer && + op1_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray && op1_val->data.x_ptr.data.base_array.is_cstr) { - child_type = op1_canon_type->data.pointer.child_type; + child_type = op1_type->data.pointer.child_type; op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; op1_array_end = op1_array_val->type->data.array.len - 1; - } else if (is_slice(op1_canon_type)) { - TypeTableEntry *ptr_type = op1_canon_type->data.structure.fields[slice_ptr_index].type_entry; + } else if (is_slice(op1_type)) { + TypeTableEntry *ptr_type = op1_type->data.structure.fields[slice_ptr_index].type_entry; child_type = ptr_type->data.pointer.child_type; ConstExprValue *ptr_val = &op1_val->data.x_struct.fields[slice_ptr_index]; assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); @@ -7822,15 +7800,14 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * } else { ir_add_error(ira, op1, buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op1->value.type->name))); - // TODO if meta_type is type decl, add note pointing to type decl declaration return ira->codegen->builtin_types.entry_invalid; } ConstExprValue *op2_array_val; size_t op2_array_index; size_t op2_array_end; - if (op2_canon_type->id == TypeTableEntryIdArray) { - if (op2_canon_type->data.array.child_type != child_type) { + if (op2_type->id == TypeTableEntryIdArray) { + if (op2_type->data.array.child_type != child_type) { ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", buf_ptr(&child_type->name), buf_ptr(&op2->value.type->name))); @@ -7839,8 +7816,8 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * op2_array_val = op2_val; op2_array_index = 0; op2_array_end = op2_array_val->type->data.array.len; - } else if (op2_canon_type->id == TypeTableEntryIdPointer && - op2_canon_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && + } else if (op2_type->id == TypeTableEntryIdPointer && + op2_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray && op2_val->data.x_ptr.data.base_array.is_cstr) { @@ -7853,8 +7830,8 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; op2_array_end = op2_array_val->type->data.array.len - 1; - } else if (is_slice(op2_canon_type)) { - TypeTableEntry *ptr_type = op2_canon_type->data.structure.fields[slice_ptr_index].type_entry; + } else if (is_slice(op2_type)) { + TypeTableEntry *ptr_type = op2_type->data.structure.fields[slice_ptr_index].type_entry; if (ptr_type->data.pointer.child_type != child_type) { ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", buf_ptr(&child_type->name), @@ -7869,7 +7846,6 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * } else { ir_add_error(ira, op2, buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name))); - // TODO if meta_type is type decl, add note pointing to type decl declaration return ira->codegen->builtin_types.entry_invalid; } @@ -7878,7 +7854,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * TypeTableEntry *result_type; ConstExprValue *out_array_val; size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); - if (op1_canon_type->id == TypeTableEntryIdArray || op2_canon_type->id == TypeTableEntryIdArray) { + if (op1_type->id == TypeTableEntryIdArray || op2_type->id == TypeTableEntryIdArray) { result_type = get_array_type(ira->codegen, child_type, new_len); out_array_val = out_val; @@ -7931,14 +7907,13 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp if (!ir_resolve_usize(ira, op2, &mult_amt)) return ira->codegen->builtin_types.entry_invalid; - TypeTableEntry *array_canon_type = get_underlying_type(op1->value.type); - if (array_canon_type->id != TypeTableEntryIdArray) { + TypeTableEntry *array_type = op1->value.type; + if (array_type->id != TypeTableEntryIdArray) { ir_add_error(ira, op1, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value.type->name))); - // TODO if meta_type is type decl, add note pointing to type decl declaration return ira->codegen->builtin_types.entry_invalid; } - uint64_t old_array_len = array_canon_type->data.array.len; + uint64_t old_array_len = array_type->data.array.len; BigNum array_len; bignum_init_unsigned(&array_len, old_array_len); @@ -7961,7 +7936,7 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp } assert(i == new_array_len); - TypeTableEntry *child_type = array_canon_type->data.array.child_type; + TypeTableEntry *child_type = array_type->data.array.child_type; return get_array_type(ira->codegen, child_type, new_array_len); } @@ -8033,7 +8008,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc AstNode *source_node = decl_var_instruction->base.source_node; IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); - TypeTableEntry *result_type = get_underlying_type(casted_init_value->value.type); + TypeTableEntry *result_type = casted_init_value->value.type; if (type_is_invalid(result_type)) { result_type = ira->codegen->builtin_types.entry_invalid; } @@ -8041,8 +8016,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc bool is_comptime_var = ir_get_var_is_comptime(var); switch (result_type->id) { - case TypeTableEntryIdTypeDecl: - zig_unreachable(); case TypeTableEntryIdInvalid: break; // handled above case TypeTableEntryIdNumLitFloat: @@ -8057,6 +8030,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc case TypeTableEntryIdVar: case TypeTableEntryIdBlock: case TypeTableEntryIdNullLit: + case TypeTableEntryIdOpaque: ir_add_error_node(ira, source_node, buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name))); result_type = ira->codegen->builtin_types.entry_invalid; @@ -8670,14 +8644,11 @@ static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstruct IrInstruction *value = un_op_instruction->value->other; TypeTableEntry *meta_type = ir_resolve_type(ira, value); - TypeTableEntry *underlying_meta_type = get_underlying_type(meta_type); - - if (type_is_invalid(underlying_meta_type)) + if (type_is_invalid(meta_type)) return ira->codegen->builtin_types.entry_invalid; - switch (underlying_meta_type->id) { - case TypeTableEntryIdTypeDecl: + switch (meta_type->id) { case TypeTableEntryIdInvalid: // handled above zig_unreachable(); @@ -8712,9 +8683,9 @@ static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstruct case TypeTableEntryIdUnreachable: case TypeTableEntryIdVar: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: ir_add_error_node(ira, un_op_instruction->base.source_node, buf_sprintf("unable to wrap type '%s' in error type", buf_ptr(&meta_type->name))); - // TODO if meta_type is type decl, add note pointing to type decl declaration return ira->codegen->builtin_types.entry_invalid; } zig_unreachable(); @@ -8756,13 +8727,11 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { IrInstruction *value = un_op_instruction->value->other; TypeTableEntry *type_entry = ir_resolve_type(ira, value); - TypeTableEntry *canon_type = get_underlying_type(type_entry); - if (type_is_invalid(canon_type)) + if (type_is_invalid(type_entry)) return ira->codegen->builtin_types.entry_invalid; - switch (canon_type->id) { + switch (type_entry->id) { case TypeTableEntryIdInvalid: case TypeTableEntryIdVar: - case TypeTableEntryIdTypeDecl: zig_unreachable(); case TypeTableEntryIdMetaType: case TypeTableEntryIdVoid: @@ -8793,9 +8762,9 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op return ira->codegen->builtin_types.entry_type; } case TypeTableEntryIdUnreachable: + case TypeTableEntryIdOpaque: ir_add_error_node(ira, un_op_instruction->base.source_node, buf_sprintf("type '%s' not nullable", buf_ptr(&type_entry->name))); - // TODO if it's a type decl, put an error note here pointing to the decl return ira->codegen->builtin_types.entry_invalid; } zig_unreachable(); @@ -9406,23 +9375,6 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source return ir_analyze_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); } - case TldIdTypeDef: - { - TldTypeDef *tld_typedef = (TldTypeDef *)tld; - assert(tld_typedef->type_entry); - - // TODO instead of allocating this every time, put it in the tld value and we can reference - // the same one every time - ConstExprValue *const_val = allocate(1); - const_val->special = ConstValSpecialStatic; - const_val->type = ira->codegen->builtin_types.entry_type; - const_val->data.x_type = tld_typedef->type_entry; - - bool ptr_is_const = true; - bool ptr_is_volatile = false; - return ir_analyze_const_ptr(ira, source_instruction, const_val, ira->codegen->builtin_types.entry_type, - ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile); - } } zig_unreachable(); } @@ -9726,9 +9678,9 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi case TypeTableEntryIdEnum: case TypeTableEntryIdUnion: case TypeTableEntryIdFn: - case TypeTableEntryIdTypeDecl: case TypeTableEntryIdEnumTag: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: { ConstExprValue *out_val = ir_build_const_from(ira, &typeof_instruction->base); out_val->data.x_type = type_entry; @@ -9990,12 +9942,10 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira, bool is_const = slice_type_instruction->is_const; TypeTableEntry *resolved_child_type = ir_resolve_type(ira, child_type); - TypeTableEntry *canon_child_type = get_underlying_type(resolved_child_type); - if (type_is_invalid(canon_child_type)) + if (type_is_invalid(resolved_child_type)) return ira->codegen->builtin_types.entry_invalid; - switch (canon_child_type->id) { - case TypeTableEntryIdTypeDecl: + switch (resolved_child_type->id) { case TypeTableEntryIdInvalid: // handled above zig_unreachable(); case TypeTableEntryIdVar: @@ -10004,9 +9954,9 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira, case TypeTableEntryIdNullLit: case TypeTableEntryIdBlock: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: ir_add_error_node(ira, slice_type_instruction->base.source_node, buf_sprintf("slice of type '%s' not allowed", buf_ptr(&resolved_child_type->name))); - // TODO if this is a typedecl, add error note showing the declaration of the type decl return ira->codegen->builtin_types.entry_invalid; case TypeTableEntryIdMetaType: case TypeTableEntryIdVoid: @@ -10100,11 +10050,9 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira, IrInstruction *child_type_value = array_type_instruction->child_type->other; TypeTableEntry *child_type = ir_resolve_type(ira, child_type_value); - TypeTableEntry *canon_child_type = get_underlying_type(child_type); - if (type_is_invalid(canon_child_type)) + if (type_is_invalid(child_type)) return ira->codegen->builtin_types.entry_invalid; - switch (canon_child_type->id) { - case TypeTableEntryIdTypeDecl: + switch (child_type->id) { case TypeTableEntryIdInvalid: // handled above zig_unreachable(); case TypeTableEntryIdVar: @@ -10113,9 +10061,9 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira, case TypeTableEntryIdNullLit: case TypeTableEntryIdBlock: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: ir_add_error_node(ira, array_type_instruction->base.source_node, buf_sprintf("array of type '%s' not allowed", buf_ptr(&child_type->name))); - // TODO if this is a typedecl, add error note showing the declaration of the type decl return ira->codegen->builtin_types.entry_invalid; case TypeTableEntryIdMetaType: case TypeTableEntryIdVoid: @@ -10172,15 +10120,13 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira, { IrInstruction *type_value = size_of_instruction->type_value->other; TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); - TypeTableEntry *canon_type_entry = get_underlying_type(type_entry); ensure_complete_type(ira->codegen, type_entry); - if (type_is_invalid(canon_type_entry)) + if (type_is_invalid(type_entry)) return ira->codegen->builtin_types.entry_invalid; - switch (canon_type_entry->id) { + switch (type_entry->id) { case TypeTableEntryIdInvalid: // handled above - case TypeTableEntryIdTypeDecl: zig_unreachable(); case TypeTableEntryIdVar: case TypeTableEntryIdUnreachable: @@ -10193,9 +10139,9 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira, case TypeTableEntryIdMetaType: case TypeTableEntryIdNamespace: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: ir_add_error_node(ira, size_of_instruction->base.source_node, buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name))); - // TODO if this is a typedecl, add error note showing the declaration of the type decl return ira->codegen->builtin_types.entry_invalid; case TypeTableEntryIdVoid: case TypeTableEntryIdBool: @@ -10516,15 +10462,13 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira, if (pointee_val->special == ConstValSpecialRuntime) pointee_val = nullptr; } - TypeTableEntry *canon_target_type = get_underlying_type(target_type); ensure_complete_type(ira->codegen, target_type); - if (type_is_invalid(canon_target_type)) + if (type_is_invalid(target_type)) return ira->codegen->builtin_types.entry_invalid; - switch (canon_target_type->id) { + switch (target_type->id) { case TypeTableEntryIdInvalid: case TypeTableEntryIdVar: - case TypeTableEntryIdTypeDecl: zig_unreachable(); case TypeTableEntryIdMetaType: case TypeTableEntryIdVoid: @@ -10576,9 +10520,9 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira, case TypeTableEntryIdBlock: case TypeTableEntryIdBoundFn: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: ir_add_error(ira, &switch_target_instruction->base, buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name))); - // TODO if this is a typedecl, add error note showing the declaration of the type decl return ira->codegen->builtin_types.entry_invalid; } zig_unreachable(); @@ -10630,9 +10574,8 @@ static TypeTableEntry *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstr return get_pointer_to_type(ira->codegen, field->type_entry, target_value_ptr->value.type->data.pointer.is_const); } else { - ErrorMsg *msg = ir_add_error(ira, &instruction->base, + ir_add_error(ira, &instruction->base, buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); - ir_add_typedef_err_note(ira, msg, target_type); return ira->codegen->builtin_types.entry_invalid; } } @@ -10743,13 +10686,13 @@ static TypeTableEntry *ir_analyze_instruction_array_len(IrAnalyze *ira, IrInstructionArrayLen *array_len_instruction) { IrInstruction *array_value = array_len_instruction->array_value->other; - TypeTableEntry *canon_type = get_underlying_type(array_value->value.type); - if (type_is_invalid(canon_type)) { + TypeTableEntry *type_entry = array_value->value.type; + if (type_is_invalid(type_entry)) { return ira->codegen->builtin_types.entry_invalid; - } else if (canon_type->id == TypeTableEntryIdArray) { + } else if (type_entry->id == TypeTableEntryIdArray) { return ir_analyze_const_usize(ira, &array_len_instruction->base, - canon_type->data.array.len); - } else if (is_slice(canon_type)) { + type_entry->data.array.len); + } else if (is_slice(type_entry)) { if (array_value->value.special != ConstValSpecialRuntime) { ConstExprValue *len_val = &array_value->value.data.x_struct.fields[slice_len_index]; if (len_val->special != ConstValSpecialRuntime) { @@ -10757,7 +10700,7 @@ static TypeTableEntry *ir_analyze_instruction_array_len(IrAnalyze *ira, len_val->data.x_bignum.data.x_uint); } } - TypeStructField *field = &canon_type->data.structure.fields[slice_len_index]; + TypeStructField *field = &type_entry->data.structure.fields[slice_len_index]; IrInstruction *len_ptr = ir_build_struct_field_ptr(&ira->new_irb, array_len_instruction->base.scope, array_len_instruction->base.source_node, array_value, field); len_ptr->value.type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_usize, true); @@ -10766,7 +10709,6 @@ static TypeTableEntry *ir_analyze_instruction_array_len(IrAnalyze *ira, } else { ir_add_error_node(ira, array_len_instruction->base.source_node, buf_sprintf("type '%s' has no field 'len'", buf_ptr(&array_value->value.type->name))); - // TODO if this is a typedecl, add error note showing the declaration of the type decl return ira->codegen->builtin_types.entry_invalid; } } @@ -11049,29 +10991,28 @@ static TypeTableEntry *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_ IrInstruction *target_type_value, bool is_max) { TypeTableEntry *target_type = ir_resolve_type(ira, target_type_value); - TypeTableEntry *canon_type = get_underlying_type(target_type); - if (type_is_invalid(canon_type)) + if (type_is_invalid(target_type)) return ira->codegen->builtin_types.entry_invalid; - switch (canon_type->id) { + switch (target_type->id) { case TypeTableEntryIdInvalid: zig_unreachable(); case TypeTableEntryIdInt: { ConstExprValue *out_val = ir_build_const_from(ira, source_instruction); - eval_min_max_value(ira->codegen, canon_type, out_val, is_max); + eval_min_max_value(ira->codegen, target_type, out_val, is_max); return ira->codegen->builtin_types.entry_num_lit_int; } case TypeTableEntryIdFloat: { ConstExprValue *out_val = ir_build_const_from(ira, source_instruction); - eval_min_max_value(ira->codegen, canon_type, out_val, is_max); + eval_min_max_value(ira->codegen, target_type, out_val, is_max); return ira->codegen->builtin_types.entry_num_lit_float; } case TypeTableEntryIdBool: case TypeTableEntryIdVoid: { ConstExprValue *out_val = ir_build_const_from(ira, source_instruction); - eval_min_max_value(ira->codegen, canon_type, out_val, is_max); + eval_min_max_value(ira->codegen, target_type, out_val, is_max); return target_type; } case TypeTableEntryIdEnumTag: @@ -11092,18 +11033,17 @@ static TypeTableEntry *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_ case TypeTableEntryIdEnum: case TypeTableEntryIdUnion: case TypeTableEntryIdFn: - case TypeTableEntryIdTypeDecl: case TypeTableEntryIdNamespace: case TypeTableEntryIdBlock: case TypeTableEntryIdBoundFn: case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: { const char *err_format = is_max ? "no max value available for type '%s'" : "no min value available for type '%s'"; ir_add_error(ira, source_instruction, buf_sprintf(err_format, buf_ptr(&target_type->name))); - // TODO if this is a typedecl, add error note showing the declaration of the type decl return ira->codegen->builtin_types.entry_invalid; } } @@ -11508,14 +11448,11 @@ static TypeTableEntry *ir_analyze_instruction_div_exact(IrAnalyze *ira, IrInstru if (type_is_invalid(result_type)) return ira->codegen->builtin_types.entry_invalid; - TypeTableEntry *canon_type = get_underlying_type(result_type); - - if (canon_type->id != TypeTableEntryIdInt && - canon_type->id != TypeTableEntryIdNumLitInt) + if (result_type->id != TypeTableEntryIdInt && + result_type->id != TypeTableEntryIdNumLitInt) { ir_add_error(ira, &instruction->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&result_type->name))); - // TODO if meta_type is type decl, add note pointing to type decl declaration return ira->codegen->builtin_types.entry_invalid; } @@ -11563,49 +11500,42 @@ static TypeTableEntry *ir_analyze_instruction_div_exact(IrAnalyze *ira, IrInstru static TypeTableEntry *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstructionTruncate *instruction) { IrInstruction *dest_type_value = instruction->dest_type->other; TypeTableEntry *dest_type = ir_resolve_type(ira, dest_type_value); - TypeTableEntry *canon_dest_type = get_underlying_type(dest_type); - - if (type_is_invalid(canon_dest_type)) + if (type_is_invalid(dest_type)) return ira->codegen->builtin_types.entry_invalid; - if (canon_dest_type->id != TypeTableEntryIdInt && - canon_dest_type->id != TypeTableEntryIdNumLitInt) + if (dest_type->id != TypeTableEntryIdInt && + dest_type->id != TypeTableEntryIdNumLitInt) { ir_add_error(ira, dest_type_value, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); - // TODO if meta_type is type decl, add note pointing to type decl declaration return ira->codegen->builtin_types.entry_invalid; } IrInstruction *target = instruction->target->other; TypeTableEntry *src_type = target->value.type; - TypeTableEntry *canon_src_type = get_underlying_type(src_type); - if (type_is_invalid(canon_src_type)) + if (type_is_invalid(src_type)) return ira->codegen->builtin_types.entry_invalid; - if (canon_src_type->id != TypeTableEntryIdInt && - canon_src_type->id != TypeTableEntryIdNumLitInt) + if (src_type->id != TypeTableEntryIdInt && + src_type->id != TypeTableEntryIdNumLitInt) { ir_add_error(ira, target, buf_sprintf("expected integer type, found '%s'", buf_ptr(&src_type->name))); - // TODO if meta_type is type decl, add note pointing to type decl declaration return ira->codegen->builtin_types.entry_invalid; } - if (canon_src_type->data.integral.is_signed != canon_dest_type->data.integral.is_signed) { - const char *sign_str = canon_dest_type->data.integral.is_signed ? "signed" : "unsigned"; + if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) { + const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned"; ir_add_error(ira, target, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name))); - // TODO if meta_type is type decl, add note pointing to type decl declaration return ira->codegen->builtin_types.entry_invalid; - } else if (canon_src_type->data.integral.bit_count < canon_dest_type->data.integral.bit_count) { + } else if (src_type->data.integral.bit_count < dest_type->data.integral.bit_count) { ir_add_error(ira, target, buf_sprintf("type '%s' has fewer bits than destination type '%s'", buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); - // TODO if meta_type is type decl, add note pointing to type decl declaration return ira->codegen->builtin_types.entry_invalid; } if (target->value.special == ConstValSpecialStatic) { ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); bignum_init_bignum(&out_val->data.x_bignum, &target->value.data.x_bignum); - bignum_truncate(&out_val->data.x_bignum, canon_dest_type->data.integral.bit_count); + bignum_truncate(&out_val->data.x_bignum, dest_type->data.integral.bit_count); return dest_type; } @@ -11663,7 +11593,7 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi if (type_is_invalid(count_value->value.type)) return ira->codegen->builtin_types.entry_invalid; - TypeTableEntry *dest_uncasted_type = get_underlying_type(dest_ptr->value.type); + TypeTableEntry *dest_uncasted_type = dest_ptr->value.type; bool dest_is_volatile = (dest_uncasted_type->id == TypeTableEntryIdPointer) && dest_uncasted_type->data.pointer.is_volatile; @@ -11749,8 +11679,8 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi if (type_is_invalid(count_value->value.type)) return ira->codegen->builtin_types.entry_invalid; - TypeTableEntry *dest_uncasted_type = get_underlying_type(dest_ptr->value.type); - TypeTableEntry *src_uncasted_type = get_underlying_type(src_ptr->value.type); + TypeTableEntry *dest_uncasted_type = dest_ptr->value.type; + TypeTableEntry *src_uncasted_type = src_ptr->value.type; bool dest_is_volatile = (dest_uncasted_type->id == TypeTableEntryIdPointer) && dest_uncasted_type->data.pointer.is_volatile; bool src_is_volatile = (src_uncasted_type->id == TypeTableEntryIdPointer) && @@ -11866,8 +11796,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio TypeTableEntry *ptr_type = ptr_ptr->value.type; assert(ptr_type->id == TypeTableEntryIdPointer); - TypeTableEntry *non_canon_array_type = ptr_type->data.pointer.child_type; - TypeTableEntry *canon_array_type = get_underlying_type(non_canon_array_type); + TypeTableEntry *array_type = ptr_type->data.pointer.child_type; IrInstruction *start = instruction->start->other; if (type_is_invalid(start->value.type)) @@ -11892,22 +11821,21 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio TypeTableEntry *return_type; - if (canon_array_type->id == TypeTableEntryIdArray) { - return_type = get_slice_type(ira->codegen, canon_array_type->data.array.child_type, instruction->is_const); - } else if (canon_array_type->id == TypeTableEntryIdPointer) { - return_type = get_slice_type(ira->codegen, canon_array_type->data.pointer.child_type, instruction->is_const); + if (array_type->id == TypeTableEntryIdArray) { + return_type = get_slice_type(ira->codegen, array_type->data.array.child_type, instruction->is_const); + } else if (array_type->id == TypeTableEntryIdPointer) { + return_type = get_slice_type(ira->codegen, array_type->data.pointer.child_type, instruction->is_const); if (!end) { ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value")); return ira->codegen->builtin_types.entry_invalid; } - } else if (is_slice(canon_array_type)) { + } else if (is_slice(array_type)) { return_type = get_slice_type(ira->codegen, - canon_array_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, + array_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, instruction->is_const); } else { ir_add_error(ira, &instruction->base, - buf_sprintf("slice of non-array type '%s'", buf_ptr(&non_canon_array_type->name))); - // TODO if this is a typedecl, add error note showing the declaration of the type decl + buf_sprintf("slice of non-array type '%s'", buf_ptr(&array_type->name))); return ira->codegen->builtin_types.entry_invalid; } @@ -11919,12 +11847,12 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio ConstExprValue *parent_ptr; size_t abs_offset; size_t rel_end; - if (canon_array_type->id == TypeTableEntryIdArray) { + if (array_type->id == TypeTableEntryIdArray) { array_val = const_ptr_pointee(&ptr_ptr->value); abs_offset = 0; - rel_end = canon_array_type->data.array.len; + rel_end = array_type->data.array.len; parent_ptr = nullptr; - } else if (canon_array_type->id == TypeTableEntryIdPointer) { + } else if (array_type->id == TypeTableEntryIdPointer) { parent_ptr = const_ptr_pointee(&ptr_ptr->value); switch (parent_ptr->data.x_ptr.special) { case ConstPtrSpecialInvalid: @@ -11946,7 +11874,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio array_val = nullptr; break; } - } else if (is_slice(canon_array_type)) { + } else if (is_slice(array_type)) { ConstExprValue *slice_ptr = const_ptr_pointee(&ptr_ptr->value); parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index]; ConstExprValue *len_val = &slice_ptr->data.x_struct.fields[slice_len_index]; @@ -12005,7 +11933,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio if (array_val) { size_t index = abs_offset + start_scalar; init_const_ptr_array(ira->codegen, ptr_val, array_val, index, instruction->is_const); - if (canon_array_type->id == TypeTableEntryIdArray) { + if (array_type->id == TypeTableEntryIdArray) { ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut; } } else { @@ -12045,17 +11973,16 @@ static TypeTableEntry *ir_analyze_instruction_member_count(IrAnalyze *ira, IrIns if (type_is_invalid(container->value.type)) return ira->codegen->builtin_types.entry_invalid; TypeTableEntry *container_type = ir_resolve_type(ira, container); - TypeTableEntry *canon_type = get_underlying_type(container_type); uint64_t result; - if (type_is_invalid(canon_type)) { + if (type_is_invalid(container_type)) { return ira->codegen->builtin_types.entry_invalid; - } else if (canon_type->id == TypeTableEntryIdEnum) { - result = canon_type->data.enumeration.src_field_count; - } else if (canon_type->id == TypeTableEntryIdStruct) { - result = canon_type->data.structure.src_field_count; - } else if (canon_type->id == TypeTableEntryIdUnion) { - result = canon_type->data.unionation.src_field_count; + } else if (container_type->id == TypeTableEntryIdEnum) { + result = container_type->data.enumeration.src_field_count; + } else if (container_type->id == TypeTableEntryIdStruct) { + result = container_type->data.structure.src_field_count; + } else if (container_type->id == TypeTableEntryIdUnion) { + result = container_type->data.unionation.src_field_count; } else { ir_add_error(ira, &instruction->base, buf_sprintf("no value count available for type '%s'", buf_ptr(&container_type->name))); return ira->codegen->builtin_types.entry_invalid; @@ -12112,14 +12039,12 @@ static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInst if (type_is_invalid(type_value->value.type)) return ira->codegen->builtin_types.entry_invalid; TypeTableEntry *dest_type = ir_resolve_type(ira, type_value); - TypeTableEntry *canon_type = get_underlying_type(dest_type); - if (type_is_invalid(canon_type)) + if (type_is_invalid(dest_type)) return ira->codegen->builtin_types.entry_invalid; - if (canon_type->id != TypeTableEntryIdInt) { + if (dest_type->id != TypeTableEntryIdInt) { ir_add_error(ira, type_value, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); - // TODO if this is a typedecl, add error note showing the declaration of the type decl return ira->codegen->builtin_types.entry_invalid; } @@ -12171,11 +12096,11 @@ static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInst out_val->data.x_bool = bignum_shl(dest_bignum, op1_bignum, op2_bignum); break; } - if (!bignum_fits_in_bits(dest_bignum, canon_type->data.integral.bit_count, - canon_type->data.integral.is_signed)) + if (!bignum_fits_in_bits(dest_bignum, dest_type->data.integral.bit_count, + dest_type->data.integral.is_signed)) { out_val->data.x_bool = true; - bignum_truncate(dest_bignum, canon_type->data.integral.bit_count); + bignum_truncate(dest_bignum, dest_type->data.integral.bit_count); } pointee_val->special = ConstValSpecialStatic; return ira->codegen->builtin_types.entry_bool; @@ -12191,12 +12116,10 @@ static TypeTableEntry *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruc if (type_is_invalid(value->value.type)) return ira->codegen->builtin_types.entry_invalid; - TypeTableEntry *non_canon_type = value->value.type; - - TypeTableEntry *canon_type = get_underlying_type(non_canon_type); - if (type_is_invalid(canon_type)) { + TypeTableEntry *type_entry = value->value.type; + if (type_is_invalid(type_entry)) { return ira->codegen->builtin_types.entry_invalid; - } else if (canon_type->id == TypeTableEntryIdErrorUnion) { + } else if (type_entry->id == TypeTableEntryIdErrorUnion) { if (instr_is_comptime(value)) { ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad); if (!err_union_val) @@ -12211,7 +12134,7 @@ static TypeTableEntry *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruc ir_build_test_err_from(&ira->new_irb, &instruction->base, value); return ira->codegen->builtin_types.entry_bool; - } else if (canon_type->id == TypeTableEntryIdPureError) { + } else if (type_entry->id == TypeTableEntryIdPureError) { ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); out_val->data.x_bool = true; return ira->codegen->builtin_types.entry_bool; @@ -12233,11 +12156,10 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. assert(ptr_type->id == TypeTableEntryIdPointer); - TypeTableEntry *non_canon_type = ptr_type->data.pointer.child_type; - TypeTableEntry *canon_type = get_underlying_type(non_canon_type); - if (type_is_invalid(canon_type)) { + TypeTableEntry *type_entry = ptr_type->data.pointer.child_type; + if (type_is_invalid(type_entry)) { return ira->codegen->builtin_types.entry_invalid; - } else if (canon_type->id == TypeTableEntryIdErrorUnion) { + } else if (type_entry->id == TypeTableEntryIdErrorUnion) { if (instr_is_comptime(value)) { ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); if (!ptr_val) @@ -12257,8 +12179,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, return ira->codegen->builtin_types.entry_pure_error; } else { ir_add_error(ira, value, - buf_sprintf("expected error union type, found '%s'", buf_ptr(&non_canon_type->name))); - // TODO if this is a typedecl, add error note showing the declaration of the type decl + buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); return ira->codegen->builtin_types.entry_invalid; } } @@ -12275,12 +12196,11 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. assert(ptr_type->id == TypeTableEntryIdPointer); - TypeTableEntry *non_canon_type = ptr_type->data.pointer.child_type; - TypeTableEntry *canon_type = get_underlying_type(non_canon_type); - if (type_is_invalid(canon_type)) { + TypeTableEntry *type_entry = ptr_type->data.pointer.child_type; + if (type_is_invalid(type_entry)) { return ira->codegen->builtin_types.entry_invalid; - } else if (canon_type->id == TypeTableEntryIdErrorUnion) { - TypeTableEntry *child_type = canon_type->data.error.child_type; + } else if (type_entry->id == TypeTableEntryIdErrorUnion) { + TypeTableEntry *child_type = type_entry->data.error.child_type; TypeTableEntry *result_type = get_pointer_to_type_extra(ira->codegen, child_type, ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 0, 0); if (instr_is_comptime(value)) { @@ -12307,8 +12227,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, return result_type; } else { ir_add_error(ira, value, - buf_sprintf("expected error union type, found '%s'", buf_ptr(&non_canon_type->name))); - // TODO if this is a typedecl, add error note showing the declaration of the type decl + buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); return ira->codegen->builtin_types.entry_invalid; } @@ -12594,22 +12513,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira, return ref_instruction->value.type; } } - case TldIdTypeDef: - { - TldTypeDef *tld_typedef = (TldTypeDef *)tld; - TypeTableEntry *typedef_type = tld_typedef->type_entry; - - IrInstruction *ref_instruction = ir_create_const_type(&ira->new_irb, instruction->base.scope, - instruction->base.source_node, typedef_type); - if (lval.is_ptr) { - IrInstruction *ptr_inst = ir_get_ref(ira, &instruction->base, ref_instruction, true, false); - ir_link_new_instruction(ptr_inst, &instruction->base); - return ptr_inst->value.type; - } else { - ir_link_new_instruction(ref_instruction, &instruction->base); - return ref_instruction->value.type; - } - } } zig_unreachable(); } diff --git a/src/parseh.cpp b/src/parseh.cpp index 77cc15cc0f..8780e0424d 100644 --- a/src/parseh.cpp +++ b/src/parseh.cpp @@ -219,28 +219,8 @@ static Tld *add_container_tld(Context *c, TypeTableEntry *type_entry) { return add_const_type(c, &type_entry->name, type_entry); } -static Tld *add_typedef_tld(Context *c, TypeTableEntry *type_decl) { - assert(type_decl); - assert(type_decl->id == TypeTableEntryIdTypeDecl); - - TldTypeDef *tld_typedef = allocate(1); - parseh_init_tld(c, &tld_typedef->base, TldIdTypeDef, &type_decl->name); - tld_typedef->type_entry = type_decl; - - add_global(c, &tld_typedef->base); - c->global_type_table.put(&type_decl->name, type_decl); - - return &tld_typedef->base; -} - static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) { - while (type_entry->id == TypeTableEntryIdTypeDecl) { - if (type_entry == c->codegen->builtin_types.entry_c_void) { - return true; - } - type_entry = type_entry->data.type_decl.child_type; - } - return false; + return (type_entry == c->codegen->builtin_types.entry_c_void); } static bool qual_type_child_is_fn_proto(const QualType &qt) { @@ -369,7 +349,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const const PointerType *pointer_ty = static_cast(ty); QualType child_qt = pointer_ty->getPointeeType(); TypeTableEntry *child_type = resolve_qual_type(c, child_qt, decl); - if (get_underlying_type(child_type)->id == TypeTableEntryIdInvalid) { + if (type_is_invalid(child_type)) { emit_warning(c, decl, "pointer to unresolved type"); return c->codegen->builtin_types.entry_invalid; } @@ -410,7 +390,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const } else { auto entry = type_table->maybe_get(type_name); if (entry) { - if (get_underlying_type(entry->value)->id == TypeTableEntryIdInvalid) { + if (type_is_invalid(entry->value)) { return c->codegen->builtin_types.entry_invalid; } else { return entry->value; @@ -507,7 +487,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const fn_type_id.return_type = c->codegen->builtin_types.entry_unreachable; } else { fn_type_id.return_type = resolve_qual_type(c, fn_proto_ty->getReturnType(), decl); - if (get_underlying_type(fn_type_id.return_type)->id == TypeTableEntryIdInvalid) { + if (type_is_invalid(fn_type_id.return_type)) { emit_warning(c, decl, "unresolved function proto return type"); return c->codegen->builtin_types.entry_invalid; } @@ -522,7 +502,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const QualType qt = fn_proto_ty->getParamType(i); TypeTableEntry *param_type = resolve_qual_type(c, qt, decl); - if (get_underlying_type(param_type)->id == TypeTableEntryIdInvalid) { + if (type_is_invalid(param_type)) { emit_warning(c, decl, "unresolved function proto parameter type"); return c->codegen->builtin_types.entry_invalid; } @@ -702,6 +682,7 @@ static void replace_with_fwd_decl(Context *c, TypeTableEntry *struct_type, Buf * ZigLLVMReplaceTemporary(c->codegen->dbuilder, struct_type->di_type, replacement_di_type); struct_type->di_type = replacement_di_type; + struct_type->id = TypeTableEntryIdOpaque; } static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) { @@ -809,7 +790,9 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) return enum_type; } else { - TypeTableEntry *enum_type = get_typedecl_type(c->codegen, buf_ptr(full_type_name), tag_type_entry); + // TODO after issue #305 is solved, make this be an enum with tag_type_entry + // as the integer type and set the custom enum values + TypeTableEntry *enum_type = tag_type_entry; c->enum_type_table.put(bare_name, enum_type); c->decl_table.put(enum_decl, enum_type); @@ -847,22 +830,8 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) { Buf *bare_name = buf_create_from_str(decl_name(enum_decl)); - if (enum_type->id == TypeTableEntryIdEnum) { - if (enum_type->data.enumeration.complete) { - Tld *tld = add_container_tld(c, enum_type); - add_global_weak_alias(c, bare_name, tld); - } else { - TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(&enum_type->name), - c->codegen->builtin_types.entry_u8); - Tld *tld = add_typedef_tld(c, typedecl_type); - add_global_weak_alias(c, bare_name, tld); - } - } else if (enum_type->id == TypeTableEntryIdTypeDecl) { - Tld *tld = add_typedef_tld(c, enum_type); - add_global_weak_alias(c, bare_name, tld); - } else { - zig_unreachable(); - } + Tld *tld = add_container_tld(c, enum_type); + add_global_weak_alias(c, bare_name, tld); } static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_decl) { @@ -912,7 +881,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ const FieldDecl *field_decl = *it; if (field_decl->isBitField()) { - emit_warning(c, field_decl, "struct %s demoted to typedef - has bitfield\n", buf_ptr(bare_name)); + emit_warning(c, field_decl, "struct %s demoted to opaque type - has bitfield\n", buf_ptr(bare_name)); replace_with_fwd_decl(c, struct_type, full_type_name); return struct_type; } @@ -939,7 +908,7 @@ static TypeTableEntry *resolve_record_decl(Context *c, const RecordDecl *record_ type_struct_field->type_entry = field_type; if (type_is_invalid(field_type) || !type_is_complete(field_type)) { - emit_warning(c, field_decl, "struct %s demoted to typedef - unresolved type\n", buf_ptr(bare_name)); + emit_warning(c, field_decl, "struct %s demoted to opaque type - unresolved type\n", buf_ptr(bare_name)); replace_with_fwd_decl(c, struct_type, full_type_name); return struct_type; } @@ -1001,23 +970,14 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) { return; } - assert(struct_type->id == TypeTableEntryIdStruct); - bool is_anonymous = (record_decl->isAnonymousStructOrUnion() || decl_name(record_decl)[0] == 0); if (is_anonymous) return; Buf *bare_name = buf_create_from_str(decl_name(record_decl)); - if (struct_type->data.structure.complete) { - Tld *tld = add_container_tld(c, struct_type); - add_global_weak_alias(c, bare_name, tld); - } else { - TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(&struct_type->name), - c->codegen->builtin_types.entry_u8); - Tld *tld = add_typedef_tld(c, typedecl_type); - add_global_weak_alias(c, bare_name, tld); - } + Tld *tld = add_container_tld(c, struct_type); + add_global_weak_alias(c, bare_name, tld); } static void visit_var_decl(Context *c, const VarDecl *var_decl) { @@ -1059,8 +1019,7 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) { switch (ap_value->getKind()) { case APValue::Int: { - TypeTableEntry *canon_type = get_underlying_type(var_type); - if (canon_type->id != TypeTableEntryIdInt) { + if (var_type->id != TypeTableEntryIdInt) { emit_warning(c, var_decl, "ignoring variable '%s' - int initializer for non int type\n", buf_ptr(name)); return; diff --git a/src/parser.cpp b/src/parser.cpp index 16bc23f741..6629e7bf89 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -710,7 +710,7 @@ static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index, bool m /* PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl -KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this" | "unreachable" +KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "this" | "unreachable" */ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) { Token *token = &pc->tokens->at(*token_index); @@ -766,10 +766,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo AstNode *node = ast_create_node(pc, NodeTypeUnreachable, token); *token_index += 1; return node; - } else if (token->id == TokenIdKeywordType) { - AstNode *node = ast_create_node(pc, NodeTypeTypeLiteral, token); - *token_index += 1; - return node; } else if (token->id == TokenIdKeywordError) { AstNode *node = ast_create_node(pc, NodeTypeErrorType, token); *token_index += 1; @@ -2500,34 +2496,9 @@ static AstNode *ast_parse_test_decl_node(ParseContext *pc, size_t *token_index) return node; } -/* -TypeDecl = "type" "Symbol" "=" TypeExpr ";" -*/ -static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index, VisibMod visib_mod) { - Token *first_token = &pc->tokens->at(*token_index); - - if (first_token->id != TokenIdKeywordType) { - return nullptr; - } - *token_index += 1; - - Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol); - ast_eat_token(pc, token_index, TokenIdEq); - - AstNode *node = ast_create_node(pc, NodeTypeTypeDecl, first_token); - node->data.type_decl.symbol = token_buf(name_tok); - node->data.type_decl.child_type = ast_parse_type_expr(pc, token_index, true); - - ast_eat_token(pc, token_index, TokenIdSemicolon); - - node->data.type_decl.visib_mod = visib_mod; - - return node; -} - /* TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestDecl -TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl) +TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | UseDecl) */ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, ZigList *top_level_decls) { for (;;) { @@ -2586,12 +2557,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig continue; } - AstNode *type_decl_node = ast_parse_type_decl(pc, token_index, visib_mod); - if (type_decl_node) { - top_level_decls->append(type_decl_node); - continue; - } - return; } zig_unreachable(); @@ -2674,9 +2639,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont visit_field(&node->data.variable_declaration.type, visit, context); visit_field(&node->data.variable_declaration.expr, visit, context); break; - case NodeTypeTypeDecl: - visit_field(&node->data.type_decl.child_type, visit, context); - break; case NodeTypeErrorValueDecl: // none break; @@ -2826,9 +2788,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont case NodeTypeErrorType: // none break; - case NodeTypeTypeLiteral: - // none - break; case NodeTypeVarLiteral: // none break; diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 20c437fccd..8d536cb9a2 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -139,7 +139,6 @@ static const struct ZigKeyword zig_keywords[] = { {"this", TokenIdKeywordThis}, {"true", TokenIdKeywordTrue}, {"try", TokenIdKeywordTry}, - {"type", TokenIdKeywordType}, {"undefined", TokenIdKeywordUndefined}, {"union", TokenIdKeywordUnion}, {"unreachable", TokenIdKeywordUnreachable}, @@ -1474,7 +1473,6 @@ const char * token_name(TokenId id) { case TokenIdKeywordThis: return "this"; case TokenIdKeywordTrue: return "true"; case TokenIdKeywordTry: return "try"; - case TokenIdKeywordType: return "type"; case TokenIdKeywordUndefined: return "undefined"; case TokenIdKeywordUnion: return "union"; case TokenIdKeywordUnreachable: return "unreachable"; diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp index 0b2e2ed34e..2a647d52ee 100644 --- a/src/tokenizer.hpp +++ b/src/tokenizer.hpp @@ -76,7 +76,6 @@ enum TokenId { TokenIdKeywordThis, TokenIdKeywordTrue, TokenIdKeywordTry, - TokenIdKeywordType, TokenIdKeywordUndefined, TokenIdKeywordUnion, TokenIdKeywordUnreachable, diff --git a/test/cases/typedef.zig b/test/cases/typedef.zig deleted file mode 100644 index db6e776853..0000000000 --- a/test/cases/typedef.zig +++ /dev/null @@ -1,10 +0,0 @@ -const assert = @import("std").debug.assert; - -type int = u8; - -fn add(a: int, b: int) -> int { - a + b -} -test "typedef" { - assert(add(12, 34) == 46); -} diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 2ea6d6e9fb..358ecd0f2a 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -2191,7 +2191,7 @@ struct Foo { add_parseh_case("struct prototype used in func", AllowWarningsNo, R"SOURCE( struct Foo; struct Foo *some_func(struct Foo *foo, int x); - )SOURCE", 3, R"OUTPUT(pub type struct_Foo = u8;)OUTPUT", + )SOURCE", 3, R"OUTPUT(pub const struct_Foo = @OpaqueType();)OUTPUT", R"OUTPUT(pub extern fn some_func(foo: ?&struct_Foo, x: c_int) -> ?&struct_Foo;)OUTPUT", R"OUTPUT(pub const Foo = struct_Foo;)OUTPUT"); @@ -2277,12 +2277,12 @@ void foo(void (__cdecl *fn_ptr)(void)); )SOURCE", 1, "pub const SDL_INIT_VIDEO = 32;"); add_parseh_case("zig keywords in C code", AllowWarningsNo, R"SOURCE( -struct type { +struct comptime { int defer; }; - )SOURCE", 2, R"(pub const struct_type = extern struct { + )SOURCE", 2, R"(pub const struct_comptime = extern struct { @"defer": c_int, -};)", R"(pub const @"type" = struct_type;)"); +};)", R"(pub const @"comptime" = struct_comptime;)"); add_parseh_case("macro defines string literal with octal", AllowWarningsNo, R"SOURCE( #define FOO "aoeu\023 derp" diff --git a/test/self_hosted.zig b/test/self_hosted.zig index 432e85114d..1ffdfbc459 100644 --- a/test/self_hosted.zig +++ b/test/self_hosted.zig @@ -31,7 +31,6 @@ comptime { _ = @import("cases/switch_prong_implicit_cast.zig"); _ = @import("cases/this.zig"); _ = @import("cases/try.zig"); - _ = @import("cases/typedef.zig"); _ = @import("cases/undefined.zig"); _ = @import("cases/var_args.zig"); _ = @import("cases/void.zig");