authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-28 02:40:01-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-28 02:40:01-05:00
logeb5693d91f7ff92b88c4a0dc3e5499dd0a700b34
tree44d4d36dc5bc5ba9368119652d099aa70156efe9
parent9e7c47597985a4a35912d2b1f800d3af05597a3a

IR: function call porting progress

also implemented container init generics is still todo

8 files changed, 935 insertions(+), 1582 deletions(-)

src/all_types.hpp+62-16
...@@ -41,6 +41,7 @@ struct IrExecutable {...@@ -41,6 +41,7 @@ struct IrExecutable {
41 bool invalid;41 bool invalid;
42 ZigList<LabelTableEntry *> all_labels;42 ZigList<LabelTableEntry *> all_labels;
43 ZigList<AstNode *> goto_list;43 ZigList<AstNode *> goto_list;
44 bool is_inline;
44};45};
4546
46enum OutType {47enum OutType {
...@@ -82,6 +83,11 @@ struct ConstErrValue {...@@ -82,6 +83,11 @@ struct ConstErrValue {
82 ConstExprValue *payload;83 ConstExprValue *payload;
83};84};
8485
86struct ConstBoundFnValue {
87 FnTableEntry *fn;
88 IrInstruction *first_arg;
89};
90
85enum ConstValSpecial {91enum ConstValSpecial {
86 ConstValSpecialRuntime,92 ConstValSpecialRuntime,
87 ConstValSpecialStatic,93 ConstValSpecialStatic,
...@@ -100,6 +106,7 @@ struct ConstExprValue {...@@ -100,6 +106,7 @@ struct ConstExprValue {
100 BigNum x_bignum;106 BigNum x_bignum;
101 bool x_bool;107 bool x_bool;
102 FnTableEntry *x_fn;108 FnTableEntry *x_fn;
109 ConstBoundFnValue x_bound_fn;
103 TypeTableEntry *x_type;110 TypeTableEntry *x_type;
104 ConstExprValue *x_maybe;111 ConstExprValue *x_maybe;
105 ConstErrValue x_err;112 ConstErrValue x_err;
...@@ -494,6 +501,7 @@ struct AstNodeIfBoolExpr {...@@ -494,6 +501,7 @@ struct AstNodeIfBoolExpr {
494 AstNode *condition;501 AstNode *condition;
495 AstNode *then_block;502 AstNode *then_block;
496 AstNode *else_node; // null, block node, or other if expr node503 AstNode *else_node; // null, block node, or other if expr node
504 bool is_inline; // TODO
497505
498 // populated by semantic analyzer506 // populated by semantic analyzer
499};507};
...@@ -503,6 +511,7 @@ struct AstNodeIfVarExpr {...@@ -503,6 +511,7 @@ struct AstNodeIfVarExpr {
503 AstNode *then_block;511 AstNode *then_block;
504 AstNode *else_node; // null, block node, or other if expr node512 AstNode *else_node; // null, block node, or other if expr node
505 bool var_is_ptr;513 bool var_is_ptr;
514 bool is_inline; // TODO
506515
507 // populated by semantic analyzer516 // populated by semantic analyzer
508 TypeTableEntry *type;517 TypeTableEntry *type;
...@@ -941,12 +950,18 @@ struct TypeTableEntryFn {...@@ -941,12 +950,18 @@ struct TypeTableEntryFn {
941950
942 LLVMTypeRef raw_type_ref;951 LLVMTypeRef raw_type_ref;
943 LLVMCallConv calling_convention;952 LLVMCallConv calling_convention;
953
954 TypeTableEntry *bound_fn_parent;
944};955};
945956
946struct TypeTableEntryGenericFn {957struct TypeTableEntryGenericFn {
947 AstNode *decl_node;958 AstNode *decl_node;
948};959};
949960
961struct TypeTableEntryBoundFn {
962 TypeTableEntry *fn_type;
963};
964
950struct TypeTableEntryTypeDecl {965struct TypeTableEntryTypeDecl {
951 TypeTableEntry *child_type;966 TypeTableEntry *child_type;
952 TypeTableEntry *canonical_type;967 TypeTableEntry *canonical_type;
...@@ -978,6 +993,7 @@ enum TypeTableEntryId {...@@ -978,6 +993,7 @@ enum TypeTableEntryId {
978 TypeTableEntryIdNamespace,993 TypeTableEntryIdNamespace,
979 TypeTableEntryIdBlock,994 TypeTableEntryIdBlock,
980 TypeTableEntryIdGenericFn,995 TypeTableEntryIdGenericFn,
996 TypeTableEntryIdBoundFn,
981};997};
982998
983struct TypeTableEntry {999struct TypeTableEntry {
...@@ -988,7 +1004,6 @@ struct TypeTableEntry {...@@ -988,7 +1004,6 @@ struct TypeTableEntry {
988 ZigLLVMDIType *di_type;1004 ZigLLVMDIType *di_type;
9891005
990 bool zero_bits;1006 bool zero_bits;
991 bool deep_const;
9921007
993 union {1008 union {
994 TypeTableEntryPointer pointer;1009 TypeTableEntryPointer pointer;
...@@ -1003,6 +1018,7 @@ struct TypeTableEntry {...@@ -1003,6 +1018,7 @@ struct TypeTableEntry {
1003 TypeTableEntryFn fn;1018 TypeTableEntryFn fn;
1004 TypeTableEntryTypeDecl type_decl;1019 TypeTableEntryTypeDecl type_decl;
1005 TypeTableEntryGenericFn generic_fn;1020 TypeTableEntryGenericFn generic_fn;
1021 TypeTableEntryBoundFn bound_fn;
1006 } data;1022 } data;
10071023
1008 // use these fields to make sure we don't duplicate type table entries for the same type1024 // use these fields to make sure we don't duplicate type table entries for the same type
...@@ -1043,12 +1059,6 @@ enum FnAnalState {...@@ -1043,12 +1059,6 @@ enum FnAnalState {
1043};1059};
10441060
10451061
1046enum WantPure {
1047 WantPureAuto,
1048 WantPureFalse,
1049 WantPureTrue,
1050};
1051
1052enum FnInline {1062enum FnInline {
1053 FnInlineAuto,1063 FnInlineAuto,
1054 FnInlineAlways,1064 FnInlineAlways,
...@@ -1067,10 +1077,6 @@ struct FnTableEntry {...@@ -1067,10 +1077,6 @@ struct FnTableEntry {
1067 bool internal_linkage;1077 bool internal_linkage;
1068 bool is_extern;1078 bool is_extern;
1069 bool is_test;1079 bool is_test;
1070 bool is_pure;
1071 WantPure want_pure;
1072 AstNode *want_pure_attr_node;
1073 AstNode *want_pure_return_type;
1074 FnInline fn_inline;1080 FnInline fn_inline;
1075 FnAnalState anal_state;1081 FnAnalState anal_state;
1076 IrExecutable ir_executable;1082 IrExecutable ir_executable;
...@@ -1085,6 +1091,9 @@ struct FnTableEntry {...@@ -1085,6 +1091,9 @@ struct FnTableEntry {
1085 ZigList<VariableTableEntry *> variable_list;1091 ZigList<VariableTableEntry *> variable_list;
1086};1092};
10871093
1094uint32_t fn_table_entry_hash(FnTableEntry*);
1095bool fn_table_entry_eql(FnTableEntry *a, FnTableEntry *b);
1096
1088enum BuiltinFnId {1097enum BuiltinFnId {
1089 BuiltinFnIdInvalid,1098 BuiltinFnIdInvalid,
1090 BuiltinFnIdMemcpy,1099 BuiltinFnIdMemcpy,
...@@ -1122,7 +1131,6 @@ enum BuiltinFnId {...@@ -1122,7 +1131,6 @@ enum BuiltinFnId {
1122 BuiltinFnIdUnreachable,1131 BuiltinFnIdUnreachable,
1123 BuiltinFnIdSetFnTest,1132 BuiltinFnIdSetFnTest,
1124 BuiltinFnIdSetFnVisible,1133 BuiltinFnIdSetFnVisible,
1125 BuiltinFnIdSetFnStaticEval,
1126 BuiltinFnIdSetFnNoInline,1134 BuiltinFnIdSetFnNoInline,
1127 BuiltinFnIdSetDebugSafety,1135 BuiltinFnIdSetDebugSafety,
1128};1136};
...@@ -1385,6 +1393,7 @@ enum IrInstructionId {...@@ -1385,6 +1393,7 @@ enum IrInstructionId {
1385 IrInstructionIdStorePtr,1393 IrInstructionIdStorePtr,
1386 IrInstructionIdFieldPtr,1394 IrInstructionIdFieldPtr,
1387 IrInstructionIdStructFieldPtr,1395 IrInstructionIdStructFieldPtr,
1396 IrInstructionIdEnumFieldPtr,
1388 IrInstructionIdElemPtr,1397 IrInstructionIdElemPtr,
1389 IrInstructionIdVarPtr,1398 IrInstructionIdVarPtr,
1390 IrInstructionIdCall,1399 IrInstructionIdCall,
...@@ -1393,6 +1402,7 @@ enum IrInstructionId {...@@ -1393,6 +1402,7 @@ enum IrInstructionId {
1393 IrInstructionIdCast,1402 IrInstructionIdCast,
1394 IrInstructionIdContainerInitList,1403 IrInstructionIdContainerInitList,
1395 IrInstructionIdContainerInitFields,1404 IrInstructionIdContainerInitFields,
1405 IrInstructionIdStructInit,
1396 IrInstructionIdUnreachable,1406 IrInstructionIdUnreachable,
1397 IrInstructionIdTypeOf,1407 IrInstructionIdTypeOf,
1398 IrInstructionIdToPtrType,1408 IrInstructionIdToPtrType,
...@@ -1578,6 +1588,14 @@ struct IrInstructionStructFieldPtr {...@@ -1578,6 +1588,14 @@ struct IrInstructionStructFieldPtr {
1578 bool is_const;1588 bool is_const;
1579};1589};
15801590
1591struct IrInstructionEnumFieldPtr {
1592 IrInstruction base;
1593
1594 IrInstruction *enum_ptr;
1595 TypeEnumField *field;
1596 bool is_const;
1597};
1598
1581struct IrInstructionElemPtr {1599struct IrInstructionElemPtr {
1582 IrInstruction base;1600 IrInstruction base;
15831601
...@@ -1597,9 +1615,12 @@ struct IrInstructionVarPtr {...@@ -1597,9 +1615,12 @@ struct IrInstructionVarPtr {
1597struct IrInstructionCall {1615struct IrInstructionCall {
1598 IrInstruction base;1616 IrInstruction base;
15991617
1600 IrInstruction *fn;1618 IrInstruction *fn_ref;
1619 FnTableEntry *fn_entry;
1601 size_t arg_count;1620 size_t arg_count;
1602 IrInstruction **args;1621 IrInstruction **args;
1622 bool is_inline;
1623 LLVMValueRef tmp_ptr;
1603};1624};
16041625
1605struct IrInstructionConst {1626struct IrInstructionConst {
...@@ -1615,11 +1636,12 @@ struct IrInstructionReturn {...@@ -1615,11 +1636,12 @@ struct IrInstructionReturn {
1615 IrInstruction *value;1636 IrInstruction *value;
1616};1637};
16171638
1639// TODO get rid of this instruction, replace with instructions for each op code
1618struct IrInstructionCast {1640struct IrInstructionCast {
1619 IrInstruction base;1641 IrInstruction base;
16201642
1621 IrInstruction *value;1643 IrInstruction *value;
1622 IrInstruction *dest_type;1644 TypeTableEntry *dest_type;
1623 CastOp cast_op;1645 CastOp cast_op;
1624 LLVMValueRef tmp_ptr;1646 LLVMValueRef tmp_ptr;
1625};1647};
...@@ -1630,6 +1652,14 @@ struct IrInstructionContainerInitList {...@@ -1630,6 +1652,14 @@ struct IrInstructionContainerInitList {
1630 IrInstruction *container_type;1652 IrInstruction *container_type;
1631 size_t item_count;1653 size_t item_count;
1632 IrInstruction **items;1654 IrInstruction **items;
1655 LLVMValueRef tmp_ptr;
1656};
1657
1658struct IrInstructionContainerInitFieldsField {
1659 Buf *name;
1660 IrInstruction *value;
1661 AstNode *source_node;
1662 TypeStructField *type_struct_field;
1633};1663};
16341664
1635struct IrInstructionContainerInitFields {1665struct IrInstructionContainerInitFields {
...@@ -1637,8 +1667,21 @@ struct IrInstructionContainerInitFields {...@@ -1637,8 +1667,21 @@ struct IrInstructionContainerInitFields {
16371667
1638 IrInstruction *container_type;1668 IrInstruction *container_type;
1639 size_t field_count;1669 size_t field_count;
1640 Buf **field_names;1670 IrInstructionContainerInitFieldsField *fields;
1641 IrInstruction **field_values;1671};
1672
1673struct IrInstructionStructInitField {
1674 IrInstruction *value;
1675 TypeStructField *type_struct_field;
1676};
1677
1678struct IrInstructionStructInit {
1679 IrInstruction base;
1680
1681 TypeTableEntry *struct_type;
1682 size_t field_count;
1683 IrInstructionStructInitField *fields;
1684 LLVMValueRef tmp_ptr;
1642};1685};
16431686
1644struct IrInstructionUnreachable {1687struct IrInstructionUnreachable {
...@@ -1790,4 +1833,7 @@ static const size_t slice_len_index = 1;...@@ -1790,4 +1833,7 @@ static const size_t slice_len_index = 1;
1790static const size_t maybe_child_index = 0;1833static const size_t maybe_child_index = 0;
1791static const size_t maybe_null_index = 1;1834static const size_t maybe_null_index = 1;
17921835
1836static const size_t enum_gen_tag_index = 0;
1837static const size_t enum_gen_union_index = 1;
1838
1793#endif1839#endif
src/analyze.cpp+39-72
...@@ -84,46 +84,11 @@ AstNode *first_executing_node(AstNode *node) {...@@ -84,46 +84,11 @@ AstNode *first_executing_node(AstNode *node) {
84 zig_unreachable();84 zig_unreachable();
85}85}
8686
87void mark_impure_fn(CodeGen *g, BlockContext *context, AstNode *node) {
88 if (!context->fn_entry) return;
89 if (!context->fn_entry->is_pure) return;
90
91 context->fn_entry->is_pure = false;
92 if (context->fn_entry->want_pure == WantPureTrue) {
93 context->fn_entry->proto_node->data.fn_proto.skip = true;
94
95 ErrorMsg *msg = add_node_error(g, context->fn_entry->proto_node,
96 buf_sprintf("failed to evaluate function at compile time"));
97
98 add_error_note(g, msg, node,
99 buf_sprintf("unable to evaluate this expression at compile time"));
100
101 if (context->fn_entry->want_pure_attr_node) {
102 add_error_note(g, msg, context->fn_entry->want_pure_attr_node,
103 buf_sprintf("required to be compile-time function here"));
104 }
105
106 if (context->fn_entry->want_pure_return_type) {
107 add_error_note(g, msg, context->fn_entry->want_pure_return_type,
108 buf_sprintf("required to be compile-time function because of return type '%s'",
109 buf_ptr(&context->fn_entry->type_entry->data.fn.fn_type_id.return_type->name)));
110 }
111 }
112}
113
114ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {87ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
115 // if this assert fails, then parseh generated code that88 // if this assert fails, then parseh generated code that
116 // failed semantic analysis, which isn't supposed to happen89 // failed semantic analysis, which isn't supposed to happen
117 assert(!node->owner->c_import_node);90 assert(!node->owner->c_import_node);
11891
119 // if an error occurs in a function then it becomes impure
120 if (node->block_context) {
121 FnTableEntry *fn_entry = node->block_context->fn_entry;
122 if (fn_entry) {
123 fn_entry->is_pure = false;
124 }
125 }
126
127 ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column,92 ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column,
128 node->owner->source_code, node->owner->line_offsets, msg);93 node->owner->source_code, node->owner->line_offsets, msg);
12994
...@@ -217,6 +182,7 @@ bool type_is_complete(TypeTableEntry *type_entry) {...@@ -217,6 +182,7 @@ bool type_is_complete(TypeTableEntry *type_entry) {
217 case TypeTableEntryIdNamespace:182 case TypeTableEntryIdNamespace:
218 case TypeTableEntryIdBlock:183 case TypeTableEntryIdBlock:
219 case TypeTableEntryIdGenericFn:184 case TypeTableEntryIdGenericFn:
185 case TypeTableEntryIdBoundFn:
220 return true;186 return true;
221 }187 }
222 zig_unreachable();188 zig_unreachable();
...@@ -241,7 +207,6 @@ TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {...@@ -241,7 +207,6 @@ TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
241static TypeTableEntry *get_generic_fn_type(CodeGen *g, AstNode *decl_node) {207static TypeTableEntry *get_generic_fn_type(CodeGen *g, AstNode *decl_node) {
242 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdGenericFn);208 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdGenericFn);
243 buf_init_from_str(&entry->name, "(generic function)");209 buf_init_from_str(&entry->name, "(generic function)");
244 entry->deep_const = true;
245 entry->zero_bits = true;210 entry->zero_bits = true;
246 entry->data.generic_fn.decl_node = decl_node;211 entry->data.generic_fn.decl_node = decl_node;
247 return entry;212 return entry;
...@@ -255,8 +220,6 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool...@@ -255,8 +220,6 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
255 } else {220 } else {
256 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer);221 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer);
257222
258 entry->deep_const = is_const && child_type->deep_const;
259
260 const char *const_str = is_const ? "const " : "";223 const char *const_str = is_const ? "const " : "";
261 buf_resize(&entry->name, 0);224 buf_resize(&entry->name, 0);
262 buf_appendf(&entry->name, "&%s%s", const_str, buf_ptr(&child_type->name));225 buf_appendf(&entry->name, "&%s%s", const_str, buf_ptr(&child_type->name));
...@@ -298,8 +261,6 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -298,8 +261,6 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
298 assert(child_type->type_ref);261 assert(child_type->type_ref);
299 assert(child_type->di_type);262 assert(child_type->di_type);
300263
301 entry->deep_const = child_type->deep_const;
302
303 buf_resize(&entry->name, 0);264 buf_resize(&entry->name, 0);
304 buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name));265 buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name));
305266
...@@ -383,8 +344,6 @@ TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -383,8 +344,6 @@ TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
383344
384 entry->data.error.child_type = child_type;345 entry->data.error.child_type = child_type;
385346
386 entry->deep_const = child_type->deep_const;
387
388 if (!type_has_bits(child_type)) {347 if (!type_has_bits(child_type)) {
389 entry->type_ref = g->err_tag_type->type_ref;348 entry->type_ref = g->err_tag_type->type_ref;
390 entry->di_type = g->err_tag_type->di_type;349 entry->di_type = g->err_tag_type->di_type;
...@@ -456,7 +415,6 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t...@@ -456,7 +415,6 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
456 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);415 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);
457 entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref, array_size) : nullptr;416 entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref, array_size) : nullptr;
458 entry->zero_bits = (array_size == 0) || child_type->zero_bits;417 entry->zero_bits = (array_size == 0) || child_type->zero_bits;
459 entry->deep_const = child_type->deep_const;
460418
461 buf_resize(&entry->name, 0);419 buf_resize(&entry->name, 0);
462 buf_appendf(&entry->name, "[%" PRIu64 "]%s", array_size, buf_ptr(&child_type->name));420 buf_appendf(&entry->name, "[%" PRIu64 "]%s", array_size, buf_ptr(&child_type->name));
...@@ -507,8 +465,6 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c...@@ -507,8 +465,6 @@ TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_c
507 TypeTableEntry *var_peer = get_slice_type(g, child_type, false);465 TypeTableEntry *var_peer = get_slice_type(g, child_type, false);
508 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);466 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);
509467
510 entry->deep_const = child_type->deep_const;
511
512 buf_resize(&entry->name, 0);468 buf_resize(&entry->name, 0);
513 buf_appendf(&entry->name, "[]const %s", buf_ptr(&child_type->name));469 buf_appendf(&entry->name, "[]const %s", buf_ptr(&child_type->name));
514470
...@@ -657,7 +613,6 @@ TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *...@@ -657,7 +613,6 @@ TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *
657613
658 buf_init_from_str(&entry->name, name);614 buf_init_from_str(&entry->name, name);
659615
660 entry->deep_const = child_type->deep_const;
661 entry->type_ref = child_type->type_ref;616 entry->type_ref = child_type->type_ref;
662 entry->di_type = child_type->di_type;617 entry->di_type = child_type->di_type;
663 entry->zero_bits = child_type->zero_bits;618 entry->zero_bits = child_type->zero_bits;
...@@ -673,6 +628,23 @@ TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *...@@ -673,6 +628,23 @@ TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *
673 return entry;628 return entry;
674}629}
675630
631TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry) {
632 TypeTableEntry *fn_type = fn_entry->type_entry;
633 assert(fn_type->id == TypeTableEntryIdFn);
634 if (fn_type->data.fn.bound_fn_parent)
635 return fn_type->data.fn.bound_fn_parent;
636
637 TypeTableEntry *bound_fn_type = new_type_table_entry(TypeTableEntryIdBoundFn);
638 bound_fn_type->data.bound_fn.fn_type = fn_type;
639 bound_fn_type->zero_bits = true;
640
641 buf_resize(&bound_fn_type->name, 0);
642 buf_appendf(&bound_fn_type->name, "(bound %s)", buf_ptr(&fn_type->name));
643
644 fn_type->data.fn.bound_fn_parent = bound_fn_type;
645 return bound_fn_type;
646}
647
676// accepts ownership of fn_type_id memory648// accepts ownership of fn_type_id memory
677TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id, bool gen_debug_info) {649TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id, bool gen_debug_info) {
678 auto table_entry = g->fn_type_table.maybe_get(fn_type_id);650 auto table_entry = g->fn_type_table.maybe_get(fn_type_id);
...@@ -681,7 +653,6 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id, bool gen_debug_inf...@@ -681,7 +653,6 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id, bool gen_debug_inf
681 }653 }
682654
683 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn);655 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn);
684 fn_type->deep_const = true;
685 fn_type->data.fn.fn_type_id = *fn_type_id;656 fn_type->data.fn.fn_type_id = *fn_type_id;
686657
687 if (fn_type_id->is_cold) {658 if (fn_type_id->is_cold) {
...@@ -838,6 +809,7 @@ static IrInstruction *analyze_const_value(CodeGen *g, BlockContext *scope, AstNo...@@ -838,6 +809,7 @@ static IrInstruction *analyze_const_value(CodeGen *g, BlockContext *scope, AstNo
838 TypeTableEntry *expected_type)809 TypeTableEntry *expected_type)
839{810{
840 IrExecutable ir_executable = {0};811 IrExecutable ir_executable = {0};
812 ir_executable.is_inline = true;
841 ir_gen(g, node, scope, &ir_executable);813 ir_gen(g, node, scope, &ir_executable);
842814
843 if (ir_executable.invalid)815 if (ir_executable.invalid)
...@@ -851,6 +823,7 @@ static IrInstruction *analyze_const_value(CodeGen *g, BlockContext *scope, AstNo...@@ -851,6 +823,7 @@ static IrInstruction *analyze_const_value(CodeGen *g, BlockContext *scope, AstNo
851 fprintf(stderr, "}\n");823 fprintf(stderr, "}\n");
852 }824 }
853 IrExecutable analyzed_executable = {0};825 IrExecutable analyzed_executable = {0};
826 analyzed_executable.is_inline = true;
854 analyzed_executable.backward_branch_quota = default_backward_branch_quota;827 analyzed_executable.backward_branch_quota = default_backward_branch_quota;
855 TypeTableEntry *result_type = ir_analyze(g, &ir_executable, &analyzed_executable, expected_type, node);828 TypeTableEntry *result_type = ir_analyze(g, &ir_executable, &analyzed_executable, expected_type, node);
856 if (result_type->id == TypeTableEntryIdInvalid)829 if (result_type->id == TypeTableEntryIdInvalid)
...@@ -884,8 +857,7 @@ static TypeTableEntry *analyze_type_expr(CodeGen *g, ImportTableEntry *import, B...@@ -884,8 +857,7 @@ static TypeTableEntry *analyze_type_expr(CodeGen *g, ImportTableEntry *import, B
884857
885static bool fn_wants_full_static_eval(FnTableEntry *fn_table_entry) {858static bool fn_wants_full_static_eval(FnTableEntry *fn_table_entry) {
886 assert(fn_table_entry);859 assert(fn_table_entry);
887 AstNodeFnProto *fn_proto = &fn_table_entry->proto_node->data.fn_proto;860 return false;
888 return fn_proto->inline_arg_count == fn_proto->params.length && fn_table_entry->want_pure == WantPureTrue;
889}861}
890862
891// fn_table_entry is populated if and only if there is a function definition for this prototype863// fn_table_entry is populated if and only if there is a function definition for this prototype
...@@ -931,6 +903,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -931,6 +903,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
931 case TypeTableEntryIdNamespace:903 case TypeTableEntryIdNamespace:
932 case TypeTableEntryIdBlock:904 case TypeTableEntryIdBlock:
933 case TypeTableEntryIdGenericFn:905 case TypeTableEntryIdGenericFn:
906 case TypeTableEntryIdBoundFn:
934 if (!fn_proto->skip) {907 if (!fn_proto->skip) {
935 fn_proto->skip = true;908 fn_proto->skip = true;
936 add_node_error(g, child->data.param_decl.type,909 add_node_error(g, child->data.param_decl.type,
...@@ -991,6 +964,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -991,6 +964,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
991 case TypeTableEntryIdNamespace:964 case TypeTableEntryIdNamespace:
992 case TypeTableEntryIdBlock:965 case TypeTableEntryIdBlock:
993 case TypeTableEntryIdGenericFn:966 case TypeTableEntryIdGenericFn:
967 case TypeTableEntryIdBoundFn:
994 case TypeTableEntryIdVar:968 case TypeTableEntryIdVar:
995 if (!fn_proto->skip) {969 if (!fn_proto->skip) {
996 fn_proto->skip = true;970 fn_proto->skip = true;
...@@ -1023,9 +997,6 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -1023,9 +997,6 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
1023 }997 }
1024998
1025 if (fn_table_entry && fn_type_id.return_type->id == TypeTableEntryIdMetaType) {999 if (fn_table_entry && fn_type_id.return_type->id == TypeTableEntryIdMetaType) {
1026 fn_table_entry->want_pure = WantPureTrue;
1027 fn_table_entry->want_pure_return_type = fn_proto->return_type;
1028
1029 ErrorMsg *err_msg = nullptr;1000 ErrorMsg *err_msg = nullptr;
1030 for (size_t i = 0; i < fn_proto->params.length; i += 1) {1001 for (size_t i = 0; i < fn_proto->params.length; i += 1) {
1031 AstNode *param_decl_node = fn_proto->params.at(i);1002 AstNode *param_decl_node = fn_proto->params.at(i);
...@@ -1046,8 +1017,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -1046,8 +1017,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
1046 }1017 }
1047 }1018 }
10481019
10491020 bool gen_debug_info = fn_table_entry && !fn_wants_full_static_eval(fn_table_entry);
1050 bool gen_debug_info = !(fn_table_entry && fn_wants_full_static_eval(fn_table_entry));
1051 return get_fn_type(g, &fn_type_id, gen_debug_info);1021 return get_fn_type(g, &fn_type_id, gen_debug_info);
1052}1022}
10531023
...@@ -1167,8 +1137,6 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -1167,8 +1137,6 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
1167 assert(decl_node->type == NodeTypeContainerDecl);1137 assert(decl_node->type == NodeTypeContainerDecl);
1168 assert(enum_type->di_type);1138 assert(enum_type->di_type);
11691139
1170 enum_type->deep_const = true;
1171
1172 uint32_t field_count = decl_node->data.struct_decl.fields.length;1140 uint32_t field_count = decl_node->data.struct_decl.fields.length;
11731141
1174 enum_type->data.enumeration.src_field_count = field_count;1142 enum_type->data.enumeration.src_field_count = field_count;
...@@ -1198,11 +1166,6 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -1198,11 +1166,6 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
1198 type_enum_field->type_entry = field_type;1166 type_enum_field->type_entry = field_type;
1199 type_enum_field->value = i;1167 type_enum_field->value = i;
12001168
1201 if (!field_type->deep_const) {
1202 enum_type->deep_const = false;
1203 }
1204
1205
1206 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);1169 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);
12071170
1208 if (field_type->id == TypeTableEntryIdStruct) {1171 if (field_type->id == TypeTableEntryIdStruct) {
...@@ -1362,8 +1325,6 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -1362,8 +1325,6 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
1362 assert(decl_node->type == NodeTypeContainerDecl);1325 assert(decl_node->type == NodeTypeContainerDecl);
1363 assert(struct_type->di_type);1326 assert(struct_type->di_type);
13641327
1365 struct_type->deep_const = true;
1366
1367 size_t field_count = decl_node->data.struct_decl.fields.length;1328 size_t field_count = decl_node->data.struct_decl.fields.length;
13681329
1369 struct_type->data.structure.src_field_count = field_count;1330 struct_type->data.structure.src_field_count = field_count;
...@@ -1389,10 +1350,6 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -1389,10 +1350,6 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
1389 type_struct_field->src_index = i;1350 type_struct_field->src_index = i;
1390 type_struct_field->gen_index = SIZE_MAX;1351 type_struct_field->gen_index = SIZE_MAX;
13911352
1392 if (!field_type->deep_const) {
1393 struct_type->deep_const = false;
1394 }
1395
1396 if (field_type->id == TypeTableEntryIdStruct) {1353 if (field_type->id == TypeTableEntryIdStruct) {
1397 resolve_struct_type(g, import, field_type);1354 resolve_struct_type(g, import, field_type);
1398 } else if (field_type->id == TypeTableEntryIdEnum) {1355 } else if (field_type->id == TypeTableEntryIdEnum) {
...@@ -1537,7 +1494,6 @@ static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstN...@@ -1537,7 +1494,6 @@ static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstN
1537 fn_table_entry->proto_node = proto_node;1494 fn_table_entry->proto_node = proto_node;
1538 fn_table_entry->fn_def_node = fn_def_node;1495 fn_table_entry->fn_def_node = fn_def_node;
1539 fn_table_entry->is_extern = is_extern;1496 fn_table_entry->is_extern = is_extern;
1540 fn_table_entry->is_pure = fn_def_node != nullptr;
15411497
1542 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, proto_node, '_');1498 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, proto_node, '_');
15431499
...@@ -1852,6 +1808,7 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt...@@ -1852,6 +1808,7 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt
1852 case TypeTableEntryIdUnion:1808 case TypeTableEntryIdUnion:
1853 case TypeTableEntryIdFn:1809 case TypeTableEntryIdFn:
1854 case TypeTableEntryIdGenericFn:1810 case TypeTableEntryIdGenericFn:
1811 case TypeTableEntryIdBoundFn:
1855 return type_entry;1812 return type_entry;
1856 }1813 }
1857 zig_unreachable();1814 zig_unreachable();
...@@ -2100,6 +2057,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {...@@ -2100,6 +2057,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {
2100 case TypeTableEntryIdNamespace:2057 case TypeTableEntryIdNamespace:
2101 case TypeTableEntryIdBlock:2058 case TypeTableEntryIdBlock:
2102 case TypeTableEntryIdGenericFn:2059 case TypeTableEntryIdGenericFn:
2060 case TypeTableEntryIdBoundFn:
2103 return false;2061 return false;
21042062
2105 case TypeTableEntryIdBool:2063 case TypeTableEntryIdBool:
...@@ -2314,6 +2272,7 @@ static bool is_container(TypeTableEntry *type_entry) {...@@ -2314,6 +2272,7 @@ static bool is_container(TypeTableEntry *type_entry) {
2314 case TypeTableEntryIdNamespace:2272 case TypeTableEntryIdNamespace:
2315 case TypeTableEntryIdBlock:2273 case TypeTableEntryIdBlock:
2316 case TypeTableEntryIdGenericFn:2274 case TypeTableEntryIdGenericFn:
2275 case TypeTableEntryIdBoundFn:
2317 return false;2276 return false;
2318 }2277 }
2319 zig_unreachable();2278 zig_unreachable();
...@@ -2361,6 +2320,7 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {...@@ -2361,6 +2320,7 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
2361 case TypeTableEntryIdNamespace:2320 case TypeTableEntryIdNamespace:
2362 case TypeTableEntryIdBlock:2321 case TypeTableEntryIdBlock:
2363 case TypeTableEntryIdGenericFn:2322 case TypeTableEntryIdGenericFn:
2323 case TypeTableEntryIdBoundFn:
2364 case TypeTableEntryIdInvalid:2324 case TypeTableEntryIdInvalid:
2365 case TypeTableEntryIdVar:2325 case TypeTableEntryIdVar:
2366 zig_unreachable();2326 zig_unreachable();
...@@ -2429,10 +2389,6 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -2429,10 +2389,6 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
2429 if (fn_type->data.fn.gen_param_info) {2389 if (fn_type->data.fn.gen_param_info) {
2430 var->gen_arg_index = fn_type->data.fn.gen_param_info[i].gen_index;2390 var->gen_arg_index = fn_type->data.fn.gen_param_info[i].gen_index;
2431 }2391 }
2432
2433 if (!type->deep_const) {
2434 fn_table_entry->is_pure = false;
2435 }
2436 }2392 }
24372393
2438 TypeTableEntry *expected_type = fn_type->data.fn.fn_type_id.return_type;2394 TypeTableEntry *expected_type = fn_type->data.fn.fn_type_id.return_type;
...@@ -2768,6 +2724,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {...@@ -2768,6 +2724,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
2768 case TypeTableEntryIdNamespace:2724 case TypeTableEntryIdNamespace:
2769 case TypeTableEntryIdBlock:2725 case TypeTableEntryIdBlock:
2770 case TypeTableEntryIdGenericFn:2726 case TypeTableEntryIdGenericFn:
2727 case TypeTableEntryIdBoundFn:
2771 case TypeTableEntryIdVar:2728 case TypeTableEntryIdVar:
2772 zig_unreachable();2729 zig_unreachable();
2773 case TypeTableEntryIdUnreachable:2730 case TypeTableEntryIdUnreachable:
...@@ -2820,6 +2777,14 @@ static uint32_t hash_size(size_t x) {...@@ -2820,6 +2777,14 @@ static uint32_t hash_size(size_t x) {
2820 return x % UINT32_MAX;2777 return x % UINT32_MAX;
2821}2778}
28222779
2780uint32_t fn_table_entry_hash(FnTableEntry* value) {
2781 return ptr_hash(value);
2782}
2783
2784bool fn_table_entry_eql(FnTableEntry *a, FnTableEntry *b) {
2785 return ptr_eq(a, b);
2786}
2787
2823uint32_t fn_type_id_hash(FnTypeId *id) {2788uint32_t fn_type_id_hash(FnTypeId *id) {
2824 uint32_t result = 0;2789 uint32_t result = 0;
2825 result += id->is_extern ? 3349388391 : 0;2790 result += id->is_extern ? 3349388391 : 0;
...@@ -2912,6 +2877,7 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)...@@ -2912,6 +2877,7 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)
2912 case TypeTableEntryIdBlock:2877 case TypeTableEntryIdBlock:
2913 return hash_ptr(const_val->data.x_block);2878 return hash_ptr(const_val->data.x_block);
2914 case TypeTableEntryIdGenericFn:2879 case TypeTableEntryIdGenericFn:
2880 case TypeTableEntryIdBoundFn:
2915 case TypeTableEntryIdInvalid:2881 case TypeTableEntryIdInvalid:
2916 case TypeTableEntryIdUnreachable:2882 case TypeTableEntryIdUnreachable:
2917 case TypeTableEntryIdVar:2883 case TypeTableEntryIdVar:
...@@ -2990,6 +2956,7 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)...@@ -2990,6 +2956,7 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)
2990 case TypeTableEntryIdNamespace:2956 case TypeTableEntryIdNamespace:
2991 case TypeTableEntryIdBlock:2957 case TypeTableEntryIdBlock:
2992 case TypeTableEntryIdGenericFn:2958 case TypeTableEntryIdGenericFn:
2959 case TypeTableEntryIdBoundFn:
2993 case TypeTableEntryIdVar:2960 case TypeTableEntryIdVar:
2994 zig_unreachable();2961 zig_unreachable();
2995 case TypeTableEntryIdArray:2962 case TypeTableEntryIdArray:
src/analyze.hpp+1-1
...@@ -31,6 +31,7 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import,...@@ -31,6 +31,7 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import,
31 ContainerKind kind, AstNode *decl_node, const char *name);31 ContainerKind kind, AstNode *decl_node, const char *name);
32TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);32TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);
33TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type);33TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type);
34TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry);
34bool handle_is_ptr(TypeTableEntry *type_entry);35bool handle_is_ptr(TypeTableEntry *type_entry);
35void find_libc_include_path(CodeGen *g);36void find_libc_include_path(CodeGen *g);
36void find_libc_lib_path(CodeGen *g);37void find_libc_lib_path(CodeGen *g);
...@@ -52,7 +53,6 @@ VariableTableEntry *find_variable(CodeGen *g, BlockContext *orig_context, Buf *n...@@ -52,7 +53,6 @@ VariableTableEntry *find_variable(CodeGen *g, BlockContext *orig_context, Buf *n
52AstNode *find_decl(BlockContext *context, Buf *name);53AstNode *find_decl(BlockContext *context, Buf *name);
53void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only);54void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only);
54TopLevelDecl *get_as_top_level_decl(AstNode *node);55TopLevelDecl *get_as_top_level_decl(AstNode *node);
55void mark_impure_fn(CodeGen *g, BlockContext *context, AstNode *node);
56bool type_is_codegen_pointer(TypeTableEntry *type);56bool type_is_codegen_pointer(TypeTableEntry *type);
57TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);57TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);
58TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);58TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);
src/codegen.cpp+50-45
...@@ -1368,27 +1368,34 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI...@@ -1368,27 +1368,34 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
1368}1368}
13691369
1370static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {1370static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {
1371 LLVMValueRef fn_val = ir_llvm_value(g, instruction->fn);1371 LLVMValueRef fn_val;
1372 TypeTableEntry *fn_type = instruction->fn->type_entry;1372 TypeTableEntry *fn_type;
1373 if (instruction->fn_entry) {
1374 fn_val = instruction->fn_entry->fn_value;
1375 fn_type = instruction->fn_entry->type_entry;
1376 } else {
1377 assert(instruction->fn_ref);
1378 fn_val = ir_llvm_value(g, instruction->fn_ref);
1379 fn_type = instruction->fn_ref->type_entry;
1380 }
1381
1373 TypeTableEntry *src_return_type = fn_type->data.fn.fn_type_id.return_type;1382 TypeTableEntry *src_return_type = fn_type->data.fn.fn_type_id.return_type;
1374 bool ret_has_bits = type_has_bits(src_return_type);1383 bool ret_has_bits = type_has_bits(src_return_type);
1375 size_t fn_call_param_count = instruction->arg_count;
1376 bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type);1384 bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type);
1377 size_t actual_param_count = fn_call_param_count + (first_arg_ret ? 1 : 0);1385 size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0);
1378 bool is_var_args = fn_type->data.fn.fn_type_id.is_var_args;1386 bool is_var_args = fn_type->data.fn.fn_type_id.is_var_args;
1379 LLVMValueRef *gen_param_values = allocate<LLVMValueRef>(actual_param_count);1387 LLVMValueRef *gen_param_values = allocate<LLVMValueRef>(actual_param_count);
1380 size_t gen_param_index = 0;1388 size_t gen_param_index = 0;
1381 if (first_arg_ret) {1389 if (first_arg_ret) {
1382 zig_panic("TODO");1390 gen_param_values[gen_param_index] = instruction->tmp_ptr;
1383 //gen_param_values[gen_param_index] = node->data.fn_call_expr.tmp_ptr;1391 gen_param_index += 1;
1384 //gen_param_index += 1;
1385 }1392 }
1386 for (size_t call_i = 0; call_i < fn_call_param_count; call_i += 1) {1393 for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) {
1387 IrInstruction *param_instruction = instruction->args[call_i];1394 IrInstruction *param_instruction = instruction->args[call_i];
1388 LLVMValueRef param_value = ir_llvm_value(g, param_instruction);
1389 assert(param_value);
1390 TypeTableEntry *param_type = param_instruction->type_entry;1395 TypeTableEntry *param_type = param_instruction->type_entry;
1391 if (is_var_args || type_has_bits(param_type)) {1396 if (is_var_args || type_has_bits(param_type)) {
1397 LLVMValueRef param_value = ir_llvm_value(g, param_instruction);
1398 assert(param_value);
1392 gen_param_values[gen_param_index] = param_value;1399 gen_param_values[gen_param_index] = param_value;
1393 gen_param_index += 1;1400 gen_param_index += 1;
1394 }1401 }
...@@ -1402,8 +1409,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -1402,8 +1409,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
1402 } else if (!ret_has_bits) {1409 } else if (!ret_has_bits) {
1403 return nullptr;1410 return nullptr;
1404 } else if (first_arg_ret) {1411 } else if (first_arg_ret) {
1405 zig_panic("TODO");1412 return instruction->tmp_ptr;
1406 //return node->data.fn_call_expr.tmp_ptr;
1407 } else {1413 } else {
1408 return result;1414 return result;
1409 }1415 }
...@@ -1422,6 +1428,22 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa...@@ -1422,6 +1428,22 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
1422 return LLVMBuildStructGEP(g->builder, struct_ptr, field->gen_index, "");1428 return LLVMBuildStructGEP(g->builder, struct_ptr, field->gen_index, "");
1423}1429}
14241430
1431static LLVMValueRef ir_render_enum_field_ptr(CodeGen *g, IrExecutable *executable,
1432 IrInstructionEnumFieldPtr *instruction)
1433{
1434 LLVMValueRef enum_ptr = ir_llvm_value(g, instruction->enum_ptr);
1435 TypeEnumField *field = instruction->field;
1436
1437 if (!type_has_bits(field->type_entry))
1438 return nullptr;
1439
1440 LLVMTypeRef field_type_ref = LLVMPointerType(field->type_entry->type_ref, 0);
1441 LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, enum_ptr, enum_gen_union_index, "");
1442 LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, "");
1443
1444 return bitcasted_union_field_ptr;
1445}
1446
1425static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok) {1447static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok) {
1426 const char *ptr = buf_ptr(node->data.asm_expr.asm_template) + tok->start + 2;1448 const char *ptr = buf_ptr(node->data.asm_expr.asm_template) + tok->start + 2;
1427 size_t len = tok->end - tok->start - 2;1449 size_t len = tok->end - tok->start - 2;
...@@ -1691,6 +1713,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -1691,6 +1713,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
1691 case IrInstructionIdSwitchTarget:1713 case IrInstructionIdSwitchTarget:
1692 case IrInstructionIdStaticEval:1714 case IrInstructionIdStaticEval:
1693 case IrInstructionIdImport:1715 case IrInstructionIdImport:
1716 case IrInstructionIdContainerInitFields:
1694 zig_unreachable();1717 zig_unreachable();
1695 case IrInstructionIdReturn:1718 case IrInstructionIdReturn:
1696 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);1719 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
...@@ -1720,6 +1743,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -1720,6 +1743,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
1720 return ir_render_call(g, executable, (IrInstructionCall *)instruction);1743 return ir_render_call(g, executable, (IrInstructionCall *)instruction);
1721 case IrInstructionIdStructFieldPtr:1744 case IrInstructionIdStructFieldPtr:
1722 return ir_render_struct_field_ptr(g, executable, (IrInstructionStructFieldPtr *)instruction);1745 return ir_render_struct_field_ptr(g, executable, (IrInstructionStructFieldPtr *)instruction);
1746 case IrInstructionIdEnumFieldPtr:
1747 return ir_render_enum_field_ptr(g, executable, (IrInstructionEnumFieldPtr *)instruction);
1723 case IrInstructionIdAsm:1748 case IrInstructionIdAsm:
1724 return ir_render_asm(g, executable, (IrInstructionAsm *)instruction);1749 return ir_render_asm(g, executable, (IrInstructionAsm *)instruction);
1725 case IrInstructionIdTestNull:1750 case IrInstructionIdTestNull:
...@@ -1738,7 +1763,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -1738,7 +1763,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
1738 return ir_render_ref(g, executable, (IrInstructionRef *)instruction);1763 return ir_render_ref(g, executable, (IrInstructionRef *)instruction);
1739 case IrInstructionIdSwitchVar:1764 case IrInstructionIdSwitchVar:
1740 case IrInstructionIdContainerInitList:1765 case IrInstructionIdContainerInitList:
1741 case IrInstructionIdContainerInitFields:1766 case IrInstructionIdStructInit:
1742 case IrInstructionIdEnumTag:1767 case IrInstructionIdEnumTag:
1743 case IrInstructionIdArrayLen:1768 case IrInstructionIdArrayLen:
1744 zig_panic("TODO render more IR instructions to LLVM");1769 zig_panic("TODO render more IR instructions to LLVM");
...@@ -1960,6 +1985,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE...@@ -1960,6 +1985,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
1960 case TypeTableEntryIdNamespace:1985 case TypeTableEntryIdNamespace:
1961 case TypeTableEntryIdBlock:1986 case TypeTableEntryIdBlock:
1962 case TypeTableEntryIdGenericFn:1987 case TypeTableEntryIdGenericFn:
1988 case TypeTableEntryIdBoundFn:
1963 case TypeTableEntryIdVar:1989 case TypeTableEntryIdVar:
1964 zig_unreachable();1990 zig_unreachable();
19651991
...@@ -2197,7 +2223,6 @@ static void do_code_gen(CodeGen *g) {...@@ -2197,7 +2223,6 @@ static void do_code_gen(CodeGen *g) {
21972223
2198 TypeTableEntry *fn_type = fn_table_entry->type_entry;2224 TypeTableEntry *fn_type = fn_table_entry->type_entry;
21992225
2200 bool is_sret = false;
2201 if (!type_has_bits(fn_type->data.fn.fn_type_id.return_type)) {2226 if (!type_has_bits(fn_type->data.fn.fn_type_id.return_type)) {
2202 // nothing to do2227 // nothing to do
2203 } else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer) {2228 } else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer) {
...@@ -2208,10 +2233,6 @@ static void do_code_gen(CodeGen *g) {...@@ -2208,10 +2233,6 @@ static void do_code_gen(CodeGen *g) {
2208 LLVMValueRef first_arg = LLVMGetParam(fn_table_entry->fn_value, 0);2233 LLVMValueRef first_arg = LLVMGetParam(fn_table_entry->fn_value, 0);
2209 LLVMAddAttribute(first_arg, LLVMStructRetAttribute);2234 LLVMAddAttribute(first_arg, LLVMStructRetAttribute);
2210 ZigLLVMAddNonNullAttr(fn_table_entry->fn_value, 1);2235 ZigLLVMAddNonNullAttr(fn_table_entry->fn_value, 1);
2211 is_sret = true;
2212 }
2213 if (fn_table_entry->is_pure && !is_sret && g->is_release_build) {
2214 LLVMAddFunctionAttr(fn_table_entry->fn_value, LLVMReadOnlyAttribute);
2215 }2236 }
22162237
22172238
...@@ -2234,9 +2255,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2234,9 +2255,7 @@ static void do_code_gen(CodeGen *g) {
2234 if (param_is_noalias) {2255 if (param_is_noalias) {
2235 LLVMAddAttribute(argument_val, LLVMNoAliasAttribute);2256 LLVMAddAttribute(argument_val, LLVMNoAliasAttribute);
2236 }2257 }
2237 if ((param_type->id == TypeTableEntryIdPointer && (param_type->data.pointer.is_const || fn_table_entry->is_pure)) ||2258 if ((param_type->id == TypeTableEntryIdPointer && param_type->data.pointer.is_const) || is_byval) {
2238 is_byval)
2239 {
2240 LLVMAddAttribute(argument_val, LLVMReadOnlyAttribute);2259 LLVMAddAttribute(argument_val, LLVMReadOnlyAttribute);
2241 }2260 }
2242 if (param_type->id == TypeTableEntryIdPointer) {2261 if (param_type->id == TypeTableEntryIdPointer) {
...@@ -2339,6 +2358,15 @@ static void do_code_gen(CodeGen *g) {...@@ -2339,6 +2358,15 @@ static void do_code_gen(CodeGen *g) {
2339 } else if (instruction->id == IrInstructionIdRef) {2358 } else if (instruction->id == IrInstructionIdRef) {
2340 IrInstructionRef *ref_instruction = (IrInstructionRef *)instruction;2359 IrInstructionRef *ref_instruction = (IrInstructionRef *)instruction;
2341 slot = &ref_instruction->tmp_ptr;2360 slot = &ref_instruction->tmp_ptr;
2361 } else if (instruction->id == IrInstructionIdContainerInitList) {
2362 IrInstructionContainerInitList *container_init_list_instruction = (IrInstructionContainerInitList *)instruction;
2363 slot = &container_init_list_instruction->tmp_ptr;
2364 } else if (instruction->id == IrInstructionIdStructInit) {
2365 IrInstructionStructInit *struct_init_instruction = (IrInstructionStructInit *)instruction;
2366 slot = &struct_init_instruction->tmp_ptr;
2367 } else if (instruction->id == IrInstructionIdCall) {
2368 IrInstructionCall *call_instruction = (IrInstructionCall *)instruction;
2369 slot = &call_instruction->tmp_ptr;
2342 } else {2370 } else {
2343 zig_unreachable();2371 zig_unreachable();
2344 }2372 }
...@@ -2464,46 +2492,39 @@ static void define_builtin_types(CodeGen *g) {...@@ -2464,46 +2492,39 @@ static void define_builtin_types(CodeGen *g) {
2464 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNamespace);2492 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNamespace);
2465 buf_init_from_str(&entry->name, "(namespace)");2493 buf_init_from_str(&entry->name, "(namespace)");
2466 entry->zero_bits = true;2494 entry->zero_bits = true;
2467 entry->deep_const = true;
2468 g->builtin_types.entry_namespace = entry;2495 g->builtin_types.entry_namespace = entry;
2469 }2496 }
2470 {2497 {
2471 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBlock);2498 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBlock);
2472 buf_init_from_str(&entry->name, "(block)");2499 buf_init_from_str(&entry->name, "(block)");
2473 entry->zero_bits = true;2500 entry->zero_bits = true;
2474 entry->deep_const = true;
2475 g->builtin_types.entry_block = entry;2501 g->builtin_types.entry_block = entry;
2476 }2502 }
2477 {2503 {
2478 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);2504 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);
2479 buf_init_from_str(&entry->name, "(float literal)");2505 buf_init_from_str(&entry->name, "(float literal)");
2480 entry->zero_bits = true;2506 entry->zero_bits = true;
2481 entry->deep_const = true;
2482 g->builtin_types.entry_num_lit_float = entry;2507 g->builtin_types.entry_num_lit_float = entry;
2483 }2508 }
2484 {2509 {
2485 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitInt);2510 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitInt);
2486 buf_init_from_str(&entry->name, "(integer literal)");2511 buf_init_from_str(&entry->name, "(integer literal)");
2487 entry->zero_bits = true;2512 entry->zero_bits = true;
2488 entry->deep_const = true;
2489 g->builtin_types.entry_num_lit_int = entry;2513 g->builtin_types.entry_num_lit_int = entry;
2490 }2514 }
2491 {2515 {
2492 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUndefLit);2516 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUndefLit);
2493 buf_init_from_str(&entry->name, "(undefined)");2517 buf_init_from_str(&entry->name, "(undefined)");
2494 entry->deep_const = true;
2495 g->builtin_types.entry_undef = entry;2518 g->builtin_types.entry_undef = entry;
2496 }2519 }
2497 {2520 {
2498 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNullLit);2521 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNullLit);
2499 buf_init_from_str(&entry->name, "(null)");2522 buf_init_from_str(&entry->name, "(null)");
2500 entry->deep_const = true;
2501 g->builtin_types.entry_null = entry;2523 g->builtin_types.entry_null = entry;
2502 }2524 }
2503 {2525 {
2504 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVar);2526 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVar);
2505 buf_init_from_str(&entry->name, "(var)");2527 buf_init_from_str(&entry->name, "(var)");
2506 entry->deep_const = true;
2507 g->builtin_types.entry_var = entry;2528 g->builtin_types.entry_var = entry;
2508 }2529 }
25092530
...@@ -2514,7 +2535,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2514,7 +2535,6 @@ static void define_builtin_types(CodeGen *g) {
25142535
2515 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);2536 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
2516 entry->type_ref = LLVMIntType(size_in_bits);2537 entry->type_ref = LLVMIntType(size_in_bits);
2517 entry->deep_const = true;
25182538
2519 const char u_or_i = is_signed ? 'i' : 'u';2539 const char u_or_i = is_signed ? 'i' : 'u';
2520 buf_resize(&entry->name, 0);2540 buf_resize(&entry->name, 0);
...@@ -2554,7 +2574,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2554,7 +2574,6 @@ static void define_builtin_types(CodeGen *g) {
25542574
2555 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);2575 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
2556 entry->type_ref = LLVMIntType(size_in_bits);2576 entry->type_ref = LLVMIntType(size_in_bits);
2557 entry->deep_const = true;
25582577
2559 buf_init_from_str(&entry->name, info->name);2578 buf_init_from_str(&entry->name, info->name);
25602579
...@@ -2574,7 +2593,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2574,7 +2593,6 @@ static void define_builtin_types(CodeGen *g) {
2574 {2593 {
2575 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBool);2594 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBool);
2576 entry->type_ref = LLVMInt1Type();2595 entry->type_ref = LLVMInt1Type();
2577 entry->deep_const = true;
2578 buf_init_from_str(&entry->name, "bool");2596 buf_init_from_str(&entry->name, "bool");
2579 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);2597 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
2580 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);2598 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref);
...@@ -2590,7 +2608,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2590,7 +2608,6 @@ static void define_builtin_types(CodeGen *g) {
2590 bool is_signed = is_signed_list[sign_i];2608 bool is_signed = is_signed_list[sign_i];
25912609
2592 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);2610 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
2593 entry->deep_const = true;
2594 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);2611 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
25952612
2596 const char u_or_i = is_signed ? 'i' : 'u';2613 const char u_or_i = is_signed ? 'i' : 'u';
...@@ -2616,7 +2633,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2616,7 +2633,6 @@ static void define_builtin_types(CodeGen *g) {
2616 }2633 }
2617 {2634 {
2618 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);2635 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
2619 entry->deep_const = true;
2620 entry->type_ref = LLVMFloatType();2636 entry->type_ref = LLVMFloatType();
2621 buf_init_from_str(&entry->name, "f32");2637 buf_init_from_str(&entry->name, "f32");
2622 entry->data.floating.bit_count = 32;2638 entry->data.floating.bit_count = 32;
...@@ -2632,7 +2648,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2632,7 +2648,6 @@ static void define_builtin_types(CodeGen *g) {
2632 }2648 }
2633 {2649 {
2634 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);2650 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
2635 entry->deep_const = true;
2636 entry->type_ref = LLVMDoubleType();2651 entry->type_ref = LLVMDoubleType();
2637 buf_init_from_str(&entry->name, "f64");2652 buf_init_from_str(&entry->name, "f64");
2638 entry->data.floating.bit_count = 64;2653 entry->data.floating.bit_count = 64;
...@@ -2648,7 +2663,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2648,7 +2663,6 @@ static void define_builtin_types(CodeGen *g) {
2648 }2663 }
2649 {2664 {
2650 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);2665 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
2651 entry->deep_const = true;
2652 entry->type_ref = LLVMX86FP80Type();2666 entry->type_ref = LLVMX86FP80Type();
2653 buf_init_from_str(&entry->name, "c_long_double");2667 buf_init_from_str(&entry->name, "c_long_double");
2654 entry->data.floating.bit_count = 80;2668 entry->data.floating.bit_count = 80;
...@@ -2664,7 +2678,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2664,7 +2678,6 @@ static void define_builtin_types(CodeGen *g) {
2664 }2678 }
2665 {2679 {
2666 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);2680 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
2667 entry->deep_const = true;
2668 entry->type_ref = LLVMVoidType();2681 entry->type_ref = LLVMVoidType();
2669 entry->zero_bits = true;2682 entry->zero_bits = true;
2670 buf_init_from_str(&entry->name, "void");2683 buf_init_from_str(&entry->name, "void");
...@@ -2677,7 +2690,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2677,7 +2690,6 @@ static void define_builtin_types(CodeGen *g) {
2677 }2690 }
2678 {2691 {
2679 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable);2692 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable);
2680 entry->deep_const = true;
2681 entry->type_ref = LLVMVoidType();2693 entry->type_ref = LLVMVoidType();
2682 entry->zero_bits = true;2694 entry->zero_bits = true;
2683 buf_init_from_str(&entry->name, "unreachable");2695 buf_init_from_str(&entry->name, "unreachable");
...@@ -2687,7 +2699,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2687,7 +2699,6 @@ static void define_builtin_types(CodeGen *g) {
2687 }2699 }
2688 {2700 {
2689 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType);2701 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType);
2690 entry->deep_const = true;
2691 buf_init_from_str(&entry->name, "type");2702 buf_init_from_str(&entry->name, "type");
2692 entry->zero_bits = true;2703 entry->zero_bits = true;
2693 g->builtin_types.entry_type = entry;2704 g->builtin_types.entry_type = entry;
...@@ -2710,7 +2721,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2710,7 +2721,6 @@ static void define_builtin_types(CodeGen *g) {
27102721
2711 {2722 {
2712 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPureError);2723 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPureError);
2713 entry->deep_const = true;
2714 buf_init_from_str(&entry->name, "error");2724 buf_init_from_str(&entry->name, "error");
27152725
2716 // TODO allow overriding this type and keep track of max value and emit an2726 // TODO allow overriding this type and keep track of max value and emit an
...@@ -2726,7 +2736,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2726,7 +2736,6 @@ static void define_builtin_types(CodeGen *g) {
27262736
2727 {2737 {
2728 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);2738 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
2729 entry->deep_const = true;
2730 entry->zero_bits = true; // only allowed at compile time2739 entry->zero_bits = true; // only allowed at compile time
2731 buf_init_from_str(&entry->name, "@OS");2740 buf_init_from_str(&entry->name, "@OS");
2732 uint32_t field_count = target_os_count();2741 uint32_t field_count = target_os_count();
...@@ -2752,7 +2761,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2752,7 +2761,6 @@ static void define_builtin_types(CodeGen *g) {
27522761
2753 {2762 {
2754 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);2763 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
2755 entry->deep_const = true;
2756 entry->zero_bits = true; // only allowed at compile time2764 entry->zero_bits = true; // only allowed at compile time
2757 buf_init_from_str(&entry->name, "@Arch");2765 buf_init_from_str(&entry->name, "@Arch");
2758 uint32_t field_count = target_arch_count();2766 uint32_t field_count = target_arch_count();
...@@ -2784,7 +2792,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2784,7 +2792,6 @@ static void define_builtin_types(CodeGen *g) {
27842792
2785 {2793 {
2786 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);2794 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
2787 entry->deep_const = true;
2788 entry->zero_bits = true; // only allowed at compile time2795 entry->zero_bits = true; // only allowed at compile time
2789 buf_init_from_str(&entry->name, "@Environ");2796 buf_init_from_str(&entry->name, "@Environ");
2790 uint32_t field_count = target_environ_count();2797 uint32_t field_count = target_environ_count();
...@@ -2811,7 +2818,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2811,7 +2818,6 @@ static void define_builtin_types(CodeGen *g) {
28112818
2812 {2819 {
2813 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);2820 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
2814 entry->deep_const = true;
2815 entry->zero_bits = true; // only allowed at compile time2821 entry->zero_bits = true; // only allowed at compile time
2816 buf_init_from_str(&entry->name, "@ObjectFormat");2822 buf_init_from_str(&entry->name, "@ObjectFormat");
2817 uint32_t field_count = target_oformat_count();2823 uint32_t field_count = target_oformat_count();
...@@ -2838,7 +2844,6 @@ static void define_builtin_types(CodeGen *g) {...@@ -2838,7 +2844,6 @@ static void define_builtin_types(CodeGen *g) {
28382844
2839 {2845 {
2840 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);2846 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
2841 entry->deep_const = true;
2842 buf_init_from_str(&entry->name, "AtomicOrder");2847 buf_init_from_str(&entry->name, "AtomicOrder");
2843 uint32_t field_count = 6;2848 uint32_t field_count = 6;
2844 entry->data.enumeration.src_field_count = field_count;2849 entry->data.enumeration.src_field_count = field_count;
...@@ -2998,7 +3003,6 @@ static void define_builtin_fns(CodeGen *g) {...@@ -2998,7 +3003,6 @@ static void define_builtin_fns(CodeGen *g) {
2998 create_builtin_fn_with_arg_count(g, BuiltinFnIdUnreachable, "unreachable", 0);3003 create_builtin_fn_with_arg_count(g, BuiltinFnIdUnreachable, "unreachable", 0);
2999 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnTest, "setFnTest", 2);3004 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnTest, "setFnTest", 2);
3000 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnVisible, "setFnVisible", 2);3005 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnVisible, "setFnVisible", 2);
3001 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnStaticEval, "setFnStaticEval", 2);
3002 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnNoInline, "setFnNoInline", 2);3006 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnNoInline, "setFnNoInline", 2);
3003 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);3007 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);
3004}3008}
...@@ -3287,6 +3291,7 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {...@@ -3287,6 +3291,7 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
3287 case TypeTableEntryIdInvalid:3291 case TypeTableEntryIdInvalid:
3288 case TypeTableEntryIdMetaType:3292 case TypeTableEntryIdMetaType:
3289 case TypeTableEntryIdGenericFn:3293 case TypeTableEntryIdGenericFn:
3294 case TypeTableEntryIdBoundFn:
3290 case TypeTableEntryIdNamespace:3295 case TypeTableEntryIdNamespace:
3291 case TypeTableEntryIdBlock:3296 case TypeTableEntryIdBlock:
3292 case TypeTableEntryIdNumLitFloat:3297 case TypeTableEntryIdNumLitFloat:
src/eval.cpp+1
...@@ -56,6 +56,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty...@@ -56,6 +56,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty
56 case TypeTableEntryIdBlock:56 case TypeTableEntryIdBlock:
57 zig_panic("TODO");57 zig_panic("TODO");
58 case TypeTableEntryIdGenericFn:58 case TypeTableEntryIdGenericFn:
59 case TypeTableEntryIdBoundFn:
59 case TypeTableEntryIdInvalid:60 case TypeTableEntryIdInvalid:
60 case TypeTableEntryIdUnreachable:61 case TypeTableEntryIdUnreachable:
61 case TypeTableEntryIdVar:62 case TypeTableEntryIdVar:
src/ir.cpp+660-1415
...@@ -49,6 +49,10 @@ ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) {...@@ -49,6 +49,10 @@ ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) {
49 }49 }
50}50}
5151
52static bool ir_should_inline(IrBuilder *irb) {
53 return irb->exec->is_inline;
54}
55
52static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) {56static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) {
53 assert(basic_block);57 assert(basic_block);
54 assert(instruction);58 assert(instruction);
...@@ -160,6 +164,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr *...@@ -160,6 +164,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr *
160 return IrInstructionIdStructFieldPtr;164 return IrInstructionIdStructFieldPtr;
161}165}
162166
167static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumFieldPtr *) {
168 return IrInstructionIdEnumFieldPtr;
169}
170
163static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) {171static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) {
164 return IrInstructionIdElemPtr;172 return IrInstructionIdElemPtr;
165}173}
...@@ -276,6 +284,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) {...@@ -276,6 +284,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) {
276 return IrInstructionIdRef;284 return IrInstructionIdRef;
277}285}
278286
287static constexpr IrInstructionId ir_instruction_id(IrInstructionStructInit *) {
288 return IrInstructionIdStructInit;
289}
290
279template<typename T>291template<typename T>
280static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) {292static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) {
281 T *special_instruction = allocate<T>(1);293 T *special_instruction = allocate<T>(1);
...@@ -293,15 +305,14 @@ static T *ir_build_instruction(IrBuilder *irb, AstNode *source_node) {...@@ -293,15 +305,14 @@ static T *ir_build_instruction(IrBuilder *irb, AstNode *source_node) {
293 return special_instruction;305 return special_instruction;
294}306}
295307
296static IrInstruction *ir_build_cast(IrBuilder *irb, AstNode *source_node, IrInstruction *dest_type,308static IrInstruction *ir_build_cast(IrBuilder *irb, AstNode *source_node, TypeTableEntry *dest_type,
297 IrInstruction *value, CastOp cast_op)309 IrInstruction *value, CastOp cast_op)
298{310{
299 IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, source_node);311 IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, source_node);
300 cast_instruction->dest_type = dest_type;312 cast_instruction->dest_type = dest_type;
301 cast_instruction->value = value;313 cast_instruction->value = value;
302 cast_instruction->cast_op = cast_op;314 cast_instruction->cast_op = cast_op;
303315
304 ir_ref_instruction(dest_type);
305 ir_ref_instruction(value);316 ir_ref_instruction(value);
306317
307 return &cast_instruction->base;318 return &cast_instruction->base;
...@@ -353,10 +364,14 @@ static IrInstruction *ir_build_return_from(IrBuilder *irb, IrInstruction *old_in...@@ -353,10 +364,14 @@ static IrInstruction *ir_build_return_from(IrBuilder *irb, IrInstruction *old_in
353 return new_instruction;364 return new_instruction;
354}365}
355366
356static IrInstruction *ir_create_const(IrBuilder *irb, AstNode *source_node, TypeTableEntry *type_entry) {367static IrInstruction *ir_create_const(IrBuilder *irb, AstNode *source_node,
368 TypeTableEntry *type_entry, bool depends_on_compile_var)
369{
370 assert(type_entry);
357 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, source_node);371 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, source_node);
358 const_instruction->base.type_entry = type_entry;372 const_instruction->base.type_entry = type_entry;
359 const_instruction->base.static_value.special = ConstValSpecialStatic;373 const_instruction->base.static_value.special = ConstValSpecialStatic;
374 const_instruction->base.static_value.depends_on_compile_var = depends_on_compile_var;
360 return &const_instruction->base;375 return &const_instruction->base;
361}376}
362377
...@@ -452,6 +467,18 @@ static IrInstruction *ir_build_const_bool(IrBuilder *irb, AstNode *source_node,...@@ -452,6 +467,18 @@ static IrInstruction *ir_build_const_bool(IrBuilder *irb, AstNode *source_node,
452 return &const_instruction->base;467 return &const_instruction->base;
453}468}
454469
470static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, AstNode *source_node,
471 FnTableEntry *fn_entry, IrInstruction *first_arg, bool depends_on_compile_var)
472{
473 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
474 const_instruction->base.type_entry = get_bound_fn_type(irb->codegen, fn_entry);
475 const_instruction->base.static_value.special = ConstValSpecialStatic;
476 const_instruction->base.static_value.depends_on_compile_var = depends_on_compile_var;
477 const_instruction->base.static_value.data.x_bound_fn.fn = fn_entry;
478 const_instruction->base.static_value.data.x_bound_fn.first_arg = first_arg;
479 return &const_instruction->base;
480}
481
455static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, AstNode *source_node, Buf *str) {482static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, AstNode *source_node, Buf *str) {
456 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);483 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
457 TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8;484 TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8;
...@@ -595,26 +622,48 @@ static IrInstruction *ir_build_struct_field_ptr_from(IrBuilder *irb, IrInstructi...@@ -595,26 +622,48 @@ static IrInstruction *ir_build_struct_field_ptr_from(IrBuilder *irb, IrInstructi
595 return new_instruction;622 return new_instruction;
596}623}
597624
625static IrInstruction *ir_build_enum_field_ptr(IrBuilder *irb, AstNode *source_node,
626 IrInstruction *enum_ptr, TypeEnumField *field)
627{
628 IrInstructionEnumFieldPtr *instruction = ir_build_instruction<IrInstructionEnumFieldPtr>(irb, source_node);
629 instruction->enum_ptr = enum_ptr;
630 instruction->field = field;
631
632 ir_ref_instruction(enum_ptr);
633
634 return &instruction->base;
635}
636
637static IrInstruction *ir_build_enum_field_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,
638 IrInstruction *enum_ptr, TypeEnumField *type_enum_field)
639{
640 IrInstruction *new_instruction = ir_build_enum_field_ptr(irb, old_instruction->source_node,
641 enum_ptr, type_enum_field);
642 ir_link_new_instruction(new_instruction, old_instruction);
643 return new_instruction;
644}
645
598static IrInstruction *ir_build_call(IrBuilder *irb, AstNode *source_node,646static IrInstruction *ir_build_call(IrBuilder *irb, AstNode *source_node,
599 IrInstruction *fn, size_t arg_count, IrInstruction **args)647 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args)
600{648{
601 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, source_node);649 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, source_node);
602 call_instruction->fn = fn;650 call_instruction->fn_entry = fn_entry;
651 call_instruction->fn_ref = fn_ref;
603 call_instruction->arg_count = arg_count;652 call_instruction->arg_count = arg_count;
604 call_instruction->args = args;653 call_instruction->args = args;
605654
606 ir_ref_instruction(fn);655 if (fn_ref)
607 for (size_t i = 0; i < arg_count; i += 1) {656 ir_ref_instruction(fn_ref);
657 for (size_t i = 0; i < arg_count; i += 1)
608 ir_ref_instruction(args[i]);658 ir_ref_instruction(args[i]);
609 }
610659
611 return &call_instruction->base;660 return &call_instruction->base;
612}661}
613662
614static IrInstruction *ir_build_call_from(IrBuilder *irb, IrInstruction *old_instruction,663static IrInstruction *ir_build_call_from(IrBuilder *irb, IrInstruction *old_instruction,
615 IrInstruction *fn, size_t arg_count, IrInstruction **args)664 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args)
616{665{
617 IrInstruction *new_instruction = ir_build_call(irb, old_instruction->source_node, fn, arg_count, args);666 IrInstruction *new_instruction = ir_build_call(irb, old_instruction->source_node, fn_entry, fn_ref, arg_count, args);
618 ir_link_new_instruction(new_instruction, old_instruction);667 ir_link_new_instruction(new_instruction, old_instruction);
619 return new_instruction;668 return new_instruction;
620}669}
...@@ -706,24 +755,55 @@ static IrInstruction *ir_build_container_init_list(IrBuilder *irb, AstNode *sour...@@ -706,24 +755,55 @@ static IrInstruction *ir_build_container_init_list(IrBuilder *irb, AstNode *sour
706 return &container_init_list_instruction->base;755 return &container_init_list_instruction->base;
707}756}
708757
758static IrInstruction *ir_build_container_init_list_from(IrBuilder *irb, IrInstruction *old_instruction,
759 IrInstruction *container_type, size_t item_count, IrInstruction **items)
760{
761 IrInstruction *new_instruction = ir_build_container_init_list(irb, old_instruction->source_node,
762 container_type, item_count, items);
763 ir_link_new_instruction(new_instruction, old_instruction);
764 return new_instruction;
765}
766
709static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, AstNode *source_node,767static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, AstNode *source_node,
710 IrInstruction *container_type, size_t field_count, Buf **field_names, IrInstruction **field_values)768 IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields)
711{769{
712 IrInstructionContainerInitFields *container_init_fields_instruction =770 IrInstructionContainerInitFields *container_init_fields_instruction =
713 ir_build_instruction<IrInstructionContainerInitFields>(irb, source_node);771 ir_build_instruction<IrInstructionContainerInitFields>(irb, source_node);
714 container_init_fields_instruction->container_type = container_type;772 container_init_fields_instruction->container_type = container_type;
715 container_init_fields_instruction->field_count = field_count;773 container_init_fields_instruction->field_count = field_count;
716 container_init_fields_instruction->field_names = field_names;774 container_init_fields_instruction->fields = fields;
717 container_init_fields_instruction->field_values = field_values;
718775
719 ir_ref_instruction(container_type);776 ir_ref_instruction(container_type);
720 for (size_t i = 0; i < field_count; i += 1) {777 for (size_t i = 0; i < field_count; i += 1) {
721 ir_ref_instruction(field_values[i]);778 ir_ref_instruction(fields[i].value);
722 }779 }
723780
724 return &container_init_fields_instruction->base;781 return &container_init_fields_instruction->base;
725}782}
726783
784static IrInstruction *ir_build_struct_init(IrBuilder *irb, AstNode *source_node,
785 TypeTableEntry *struct_type, size_t field_count, IrInstructionStructInitField *fields)
786{
787 IrInstructionStructInit *struct_init_instruction = ir_build_instruction<IrInstructionStructInit>(irb, source_node);
788 struct_init_instruction->struct_type = struct_type;
789 struct_init_instruction->field_count = field_count;
790 struct_init_instruction->fields = fields;
791
792 for (size_t i = 0; i < field_count; i += 1)
793 ir_ref_instruction(fields[i].value);
794
795 return &struct_init_instruction->base;
796}
797
798static IrInstruction *ir_build_struct_init_from(IrBuilder *irb, IrInstruction *old_instruction,
799 TypeTableEntry *struct_type, size_t field_count, IrInstructionStructInitField *fields)
800{
801 IrInstruction *new_instruction = ir_build_struct_init(irb, old_instruction->source_node,
802 struct_type, field_count, fields);
803 ir_link_new_instruction(new_instruction, old_instruction);
804 return new_instruction;
805}
806
727static IrInstruction *ir_build_unreachable(IrBuilder *irb, AstNode *source_node) {807static IrInstruction *ir_build_unreachable(IrBuilder *irb, AstNode *source_node) {
728 IrInstructionUnreachable *unreachable_instruction =808 IrInstructionUnreachable *unreachable_instruction =
729 ir_build_instruction<IrInstructionUnreachable>(irb, source_node);809 ir_build_instruction<IrInstructionUnreachable>(irb, source_node);
...@@ -1442,7 +1522,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstN...@@ -1442,7 +1522,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstN
1442 ref_instruction = ir_build_const_fn(irb, source_node, fn_entry);1522 ref_instruction = ir_build_const_fn(irb, source_node, fn_entry);
1443 }1523 }
1444 if (lval != LValPurposeNone)1524 if (lval != LValPurposeNone)
1445 return ir_build_un_op(irb, source_node, IrUnOpAddressOf, ref_instruction);1525 return ir_build_ref(irb, source_node, ref_instruction);
1446 else1526 else
1447 return ref_instruction;1527 return ref_instruction;
1448 } else if (decl_node->type == NodeTypeContainerDecl) {1528 } else if (decl_node->type == NodeTypeContainerDecl) {
...@@ -1455,14 +1535,14 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstN...@@ -1455,14 +1535,14 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstN
1455 ref_instruction = ir_build_const_type(irb, source_node, decl_node->data.struct_decl.type_entry);1535 ref_instruction = ir_build_const_type(irb, source_node, decl_node->data.struct_decl.type_entry);
1456 }1536 }
1457 if (lval != LValPurposeNone)1537 if (lval != LValPurposeNone)
1458 return ir_build_un_op(irb, source_node, IrUnOpAddressOf, ref_instruction);1538 return ir_build_ref(irb, source_node, ref_instruction);
1459 else1539 else
1460 return ref_instruction;1540 return ref_instruction;
1461 } else if (decl_node->type == NodeTypeTypeDecl) {1541 } else if (decl_node->type == NodeTypeTypeDecl) {
1462 TypeTableEntry *child_type = decl_node->data.type_decl.child_type_entry;1542 TypeTableEntry *child_type = decl_node->data.type_decl.child_type_entry;
1463 IrInstruction *ref_instruction = ir_build_const_type(irb, source_node, child_type);1543 IrInstruction *ref_instruction = ir_build_const_type(irb, source_node, child_type);
1464 if (lval != LValPurposeNone)1544 if (lval != LValPurposeNone)
1465 return ir_build_un_op(irb, source_node, IrUnOpAddressOf, ref_instruction);1545 return ir_build_ref(irb, source_node, ref_instruction);
1466 else1546 else
1467 return ref_instruction;1547 return ref_instruction;
1468 } else {1548 } else {
...@@ -1712,7 +1792,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {...@@ -1712,7 +1792,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
1712 case BuiltinFnIdDivExact:1792 case BuiltinFnIdDivExact:
1713 case BuiltinFnIdTruncate:1793 case BuiltinFnIdTruncate:
1714 case BuiltinFnIdIntType:1794 case BuiltinFnIdIntType:
1715 case BuiltinFnIdSetFnStaticEval:
1716 case BuiltinFnIdSetFnNoInline:1795 case BuiltinFnIdSetFnNoInline:
1717 zig_panic("TODO IR gen more builtin functions");1796 zig_panic("TODO IR gen more builtin functions");
1718 }1797 }
...@@ -1726,9 +1805,9 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) {...@@ -1726,9 +1805,9 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) {
1726 return ir_gen_builtin_fn_call(irb, node);1805 return ir_gen_builtin_fn_call(irb, node);
17271806
1728 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;1807 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
1729 IrInstruction *fn = ir_gen_node(irb, fn_ref_node, node->block_context);1808 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, node->block_context);
1730 if (fn == irb->codegen->invalid_instruction)1809 if (fn_ref == irb->codegen->invalid_instruction)
1731 return fn;1810 return fn_ref;
17321811
1733 size_t arg_count = node->data.fn_call_expr.params.length;1812 size_t arg_count = node->data.fn_call_expr.params.length;
1734 IrInstruction **args = allocate<IrInstruction*>(arg_count);1813 IrInstruction **args = allocate<IrInstruction*>(arg_count);
...@@ -1737,7 +1816,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) {...@@ -1737,7 +1816,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) {
1737 args[i] = ir_gen_node(irb, arg_node, node->block_context);1816 args[i] = ir_gen_node(irb, arg_node, node->block_context);
1738 }1817 }
17391818
1740 return ir_build_call(irb, node, fn, arg_count, args);1819 return ir_build_call(irb, node, nullptr, fn_ref, arg_count, args);
1741}1820}
17421821
1743static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) {1822static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) {
...@@ -1754,7 +1833,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) {...@@ -1754,7 +1833,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) {
1754 IrBasicBlock *else_block = ir_build_basic_block(irb, "Else");1833 IrBasicBlock *else_block = ir_build_basic_block(irb, "Else");
1755 IrBasicBlock *endif_block = ir_build_basic_block(irb, "EndIf");1834 IrBasicBlock *endif_block = ir_build_basic_block(irb, "EndIf");
17561835
1757 bool is_inline = (node->block_context->fn_entry == nullptr);1836 bool is_inline = ir_should_inline(irb) || node->data.if_bool_expr.is_inline;
1758 ir_build_cond_br(irb, condition->source_node, condition, then_block, else_block, is_inline);1837 ir_build_cond_br(irb, condition->source_node, condition, then_block, else_block, is_inline);
17591838
1760 ir_set_cursor_at_end(irb, then_block);1839 ir_set_cursor_at_end(irb, then_block);
...@@ -1865,8 +1944,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node)...@@ -1865,8 +1944,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node)
18651944
1866 if (kind == ContainerInitKindStruct) {1945 if (kind == ContainerInitKindStruct) {
1867 size_t field_count = container_init_expr->entries.length;1946 size_t field_count = container_init_expr->entries.length;
1868 IrInstruction **values = allocate<IrInstruction *>(field_count);1947 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count);
1869 Buf **names = allocate<Buf *>(field_count);
1870 for (size_t i = 0; i < field_count; i += 1) {1948 for (size_t i = 0; i < field_count; i += 1) {
1871 AstNode *entry_node = container_init_expr->entries.at(i);1949 AstNode *entry_node = container_init_expr->entries.at(i);
1872 assert(entry_node->type == NodeTypeStructValueField);1950 assert(entry_node->type == NodeTypeStructValueField);
...@@ -1877,10 +1955,11 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node)...@@ -1877,10 +1955,11 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node)
1877 if (expr_value == irb->codegen->invalid_instruction)1955 if (expr_value == irb->codegen->invalid_instruction)
1878 return expr_value;1956 return expr_value;
18791957
1880 names[i] = name;1958 fields[i].name = name;
1881 values[i] = expr_value;1959 fields[i].value = expr_value;
1960 fields[i].source_node = entry_node;
1882 }1961 }
1883 return ir_build_container_init_fields(irb, node, container_type, field_count, names, values);1962 return ir_build_container_init_fields(irb, node, container_type, field_count, fields);
1884 } else if (kind == ContainerInitKindArray) {1963 } else if (kind == ContainerInitKindArray) {
1885 size_t item_count = container_init_expr->entries.length;1964 size_t item_count = container_init_expr->entries.length;
1886 IrInstruction **values = allocate<IrInstruction *>(item_count);1965 IrInstruction **values = allocate<IrInstruction *>(item_count);
...@@ -1919,7 +1998,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) {...@@ -1919,7 +1998,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) {
1919 bool is_shadowable = false;1998 bool is_shadowable = false;
1920 bool is_const = variable_declaration->is_const;1999 bool is_const = variable_declaration->is_const;
1921 bool is_extern = variable_declaration->is_extern;2000 bool is_extern = variable_declaration->is_extern;
1922 bool is_inline = variable_declaration->is_inline;2001 bool is_inline = ir_should_inline(irb) || variable_declaration->is_inline;
1923 VariableTableEntry *var = ir_add_local_var(irb, node, node->block_context,2002 VariableTableEntry *var = ir_add_local_var(irb, node, node->block_context,
1924 variable_declaration->symbol, is_const, is_const, is_shadowable, is_inline);2003 variable_declaration->symbol, is_const, is_const, is_shadowable, is_inline);
19252004
...@@ -1943,7 +2022,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) {...@@ -1943,7 +2022,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) {
1943 ir_build_basic_block(irb, "WhileContinue") : cond_block;2022 ir_build_basic_block(irb, "WhileContinue") : cond_block;
1944 IrBasicBlock *end_block = ir_build_basic_block(irb, "WhileEnd");2023 IrBasicBlock *end_block = ir_build_basic_block(irb, "WhileEnd");
19452024
1946 bool is_inline = node->data.while_expr.is_inline;2025 bool is_inline = ir_should_inline(irb) || node->data.while_expr.is_inline;
1947 ir_build_br(irb, node, cond_block, is_inline);2026 ir_build_br(irb, node, cond_block, is_inline);
19482027
1949 if (continue_expr_node) {2028 if (continue_expr_node) {
...@@ -1998,7 +2077,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {...@@ -1998,7 +2077,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {
1998 } else {2077 } else {
1999 elem_var_type = ir_build_ptr_type_child(irb, elem_node, pointer_type);2078 elem_var_type = ir_build_ptr_type_child(irb, elem_node, pointer_type);
2000 }2079 }
2001 bool is_inline = node->data.for_expr.is_inline;2080 bool is_inline = ir_should_inline(irb) || node->data.for_expr.is_inline;
20022081
2003 BlockContext *child_scope = new_block_context(node, parent_scope);2082 BlockContext *child_scope = new_block_context(node, parent_scope);
2004 child_scope->parent_loop_node = node;2083 child_scope->parent_loop_node = node;
...@@ -2219,7 +2298,7 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) {...@@ -2219,7 +2298,7 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) {
2219 IrBasicBlock *else_block = ir_build_basic_block(irb, "MaybeElse");2298 IrBasicBlock *else_block = ir_build_basic_block(irb, "MaybeElse");
2220 IrBasicBlock *endif_block = ir_build_basic_block(irb, "MaybeEndIf");2299 IrBasicBlock *endif_block = ir_build_basic_block(irb, "MaybeEndIf");
22212300
2222 bool is_inline = (node->block_context->fn_entry == nullptr);2301 bool is_inline = ir_should_inline(irb) || node->data.if_var_expr.is_inline;
2223 ir_build_cond_br(irb, node, is_nonnull_value, then_block, else_block, is_inline);2302 ir_build_cond_br(irb, node, is_nonnull_value, then_block, else_block, is_inline);
22242303
2225 ir_set_cursor_at_end(irb, then_block);2304 ir_set_cursor_at_end(irb, then_block);
...@@ -2322,7 +2401,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {...@@ -2322,7 +2401,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
23222401
2323 size_t prong_count = node->data.switch_expr.prongs.length;2402 size_t prong_count = node->data.switch_expr.prongs.length;
2324 ZigList<IrInstructionSwitchBrCase> cases = {0};2403 ZigList<IrInstructionSwitchBrCase> cases = {0};
2325 bool is_inline = node->data.switch_expr.is_inline || (node->block_context->fn_entry == nullptr);2404 bool is_inline = ir_should_inline(irb) || node->data.switch_expr.is_inline;
23262405
2327 ZigList<IrInstruction *> incoming_values = {0};2406 ZigList<IrInstruction *> incoming_values = {0};
2328 ZigList<IrBasicBlock *> incoming_blocks = {0};2407 ZigList<IrBasicBlock *> incoming_blocks = {0};
...@@ -2495,7 +2574,7 @@ static IrInstruction *ir_gen_label(IrBuilder *irb, AstNode *node) {...@@ -2495,7 +2574,7 @@ static IrInstruction *ir_gen_label(IrBuilder *irb, AstNode *node) {
2495 node->block_context->label_table.put(label_name, label);2574 node->block_context->label_table.put(label_name, label);
2496 }2575 }
24972576
2498 bool is_inline = (node->block_context->fn_entry == nullptr);2577 bool is_inline = ir_should_inline(irb);
2499 ir_build_br(irb, node, label_block, is_inline);2578 ir_build_br(irb, node, label_block, is_inline);
2500 ir_set_cursor_at_end(irb, label_block);2579 ir_set_cursor_at_end(irb, label_block);
2501 return ir_build_const_void(irb, node);2580 return ir_build_const_void(irb, node);
...@@ -2535,56 +2614,58 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContex...@@ -2535,56 +2614,58 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContex
2535 node->block_context = block_context;2614 node->block_context = block_context;
25362615
2537 switch (node->type) {2616 switch (node->type) {
2617 case NodeTypeStructValueField:
2618 zig_unreachable();
2538 case NodeTypeBlock:2619 case NodeTypeBlock:
2539 return ir_gen_block(irb, node);2620 return ir_lval_wrap(irb, ir_gen_block(irb, node), lval);
2540 case NodeTypeBinOpExpr:2621 case NodeTypeBinOpExpr:
2541 return ir_gen_bin_op(irb, node);2622 return ir_lval_wrap(irb, ir_gen_bin_op(irb, node), lval);
2542 case NodeTypeNumberLiteral:2623 case NodeTypeNumberLiteral:
2543 return ir_gen_num_lit(irb, node);2624 return ir_lval_wrap(irb, ir_gen_num_lit(irb, node), lval);
2544 case NodeTypeSymbol:2625 case NodeTypeSymbol:
2545 return ir_gen_symbol(irb, node, lval);2626 return ir_gen_symbol(irb, node, lval);
2546 case NodeTypeFnCallExpr:2627 case NodeTypeFnCallExpr:
2547 return ir_lval_wrap(irb, ir_gen_fn_call(irb, node), lval);2628 return ir_lval_wrap(irb, ir_gen_fn_call(irb, node), lval);
2548 case NodeTypeIfBoolExpr:2629 case NodeTypeIfBoolExpr:
2549 return ir_gen_if_bool_expr(irb, node);2630 return ir_lval_wrap(irb, ir_gen_if_bool_expr(irb, node), lval);
2550 case NodeTypePrefixOpExpr:2631 case NodeTypePrefixOpExpr:
2551 return ir_gen_prefix_op_expr(irb, node, lval);2632 return ir_gen_prefix_op_expr(irb, node, lval);
2552 case NodeTypeContainerInitExpr:2633 case NodeTypeContainerInitExpr:
2553 return ir_gen_container_init_expr(irb, node);2634 return ir_lval_wrap(irb, ir_gen_container_init_expr(irb, node), lval);
2554 case NodeTypeVariableDeclaration:2635 case NodeTypeVariableDeclaration:
2555 return ir_gen_var_decl(irb, node);2636 return ir_lval_wrap(irb, ir_gen_var_decl(irb, node), lval);
2556 case NodeTypeWhileExpr:2637 case NodeTypeWhileExpr:
2557 return ir_gen_while_expr(irb, node);2638 return ir_lval_wrap(irb, ir_gen_while_expr(irb, node), lval);
2558 case NodeTypeForExpr:2639 case NodeTypeForExpr:
2559 return ir_gen_for_expr(irb, node);2640 return ir_lval_wrap(irb, ir_gen_for_expr(irb, node), lval);
2560 case NodeTypeArrayAccessExpr:2641 case NodeTypeArrayAccessExpr:
2561 return ir_gen_array_access(irb, node, lval);2642 return ir_gen_array_access(irb, node, lval);
2562 case NodeTypeReturnExpr:2643 case NodeTypeReturnExpr:
2563 return ir_gen_return(irb, node);2644 return ir_lval_wrap(irb, ir_gen_return(irb, node), lval);
2564 case NodeTypeFieldAccessExpr:2645 case NodeTypeFieldAccessExpr:
2565 return ir_gen_field_access(irb, node, lval);2646 return ir_gen_field_access(irb, node, lval);
2566 case NodeTypeThisLiteral:2647 case NodeTypeThisLiteral:
2567 return ir_gen_this_literal(irb, node);2648 return ir_lval_wrap(irb, ir_gen_this_literal(irb, node), lval);
2568 case NodeTypeBoolLiteral:2649 case NodeTypeBoolLiteral:
2569 return ir_gen_bool_literal(irb, node);2650 return ir_lval_wrap(irb, ir_gen_bool_literal(irb, node), lval);
2570 case NodeTypeArrayType:2651 case NodeTypeArrayType:
2571 return ir_gen_array_type(irb, node);2652 return ir_lval_wrap(irb, ir_gen_array_type(irb, node), lval);
2572 case NodeTypeStringLiteral:2653 case NodeTypeStringLiteral:
2573 return ir_gen_string_literal(irb, node);2654 return ir_lval_wrap(irb, ir_gen_string_literal(irb, node), lval);
2574 case NodeTypeUndefinedLiteral:2655 case NodeTypeUndefinedLiteral:
2575 return ir_gen_undefined_literal(irb, node);2656 return ir_lval_wrap(irb, ir_gen_undefined_literal(irb, node), lval);
2576 case NodeTypeAsmExpr:2657 case NodeTypeAsmExpr:
2577 return ir_gen_asm_expr(irb, node);2658 return ir_lval_wrap(irb, ir_gen_asm_expr(irb, node), lval);
2578 case NodeTypeNullLiteral:2659 case NodeTypeNullLiteral:
2579 return ir_gen_null_literal(irb, node);2660 return ir_lval_wrap(irb, ir_gen_null_literal(irb, node), lval);
2580 case NodeTypeIfVarExpr:2661 case NodeTypeIfVarExpr:
2581 return ir_gen_if_var_expr(irb, node);2662 return ir_lval_wrap(irb, ir_gen_if_var_expr(irb, node), lval);
2582 case NodeTypeSwitchExpr:2663 case NodeTypeSwitchExpr:
2583 return ir_gen_switch_expr(irb, node);2664 return ir_lval_wrap(irb, ir_gen_switch_expr(irb, node), lval);
2584 case NodeTypeLabel:2665 case NodeTypeLabel:
2585 return ir_gen_label(irb, node);2666 return ir_lval_wrap(irb, ir_gen_label(irb, node), lval);
2586 case NodeTypeGoto:2667 case NodeTypeGoto:
2587 return ir_gen_goto(irb, node);2668 return ir_lval_wrap(irb, ir_gen_goto(irb, node), lval);
2588 case NodeTypeTypeLiteral:2669 case NodeTypeTypeLiteral:
2589 return ir_lval_wrap(irb, ir_gen_type_literal(irb, node), lval);2670 return ir_lval_wrap(irb, ir_gen_type_literal(irb, node), lval);
2590 case NodeTypeUnwrapErrorExpr:2671 case NodeTypeUnwrapErrorExpr:
...@@ -2604,7 +2685,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContex...@@ -2604,7 +2685,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContex
2604 case NodeTypeUse:2685 case NodeTypeUse:
2605 case NodeTypeContainerDecl:2686 case NodeTypeContainerDecl:
2606 case NodeTypeStructField:2687 case NodeTypeStructField:
2607 case NodeTypeStructValueField:
2608 case NodeTypeSwitchProng:2688 case NodeTypeSwitchProng:
2609 case NodeTypeSwitchRange:2689 case NodeTypeSwitchRange:
2610 case NodeTypeErrorValueDecl:2690 case NodeTypeErrorValueDecl:
...@@ -2642,7 +2722,7 @@ static bool ir_goto_pass2(IrBuilder *irb) {...@@ -2642,7 +2722,7 @@ static bool ir_goto_pass2(IrBuilder *irb) {
2642 }2722 }
2643 label->used = true;2723 label->used = true;
26442724
2645 bool is_inline = goto_node->data.goto_expr.is_inline || (goto_node->block_context->fn_entry == nullptr);2725 bool is_inline = ir_should_inline(irb) || goto_node->data.goto_expr.is_inline;
2646 IrInstruction *new_instruction = ir_create_br(irb, goto_node, label->bb, is_inline);2726 IrInstruction *new_instruction = ir_create_br(irb, goto_node, label->bb, is_inline);
2647 new_instruction->ref_count = old_instruction->ref_count;2727 new_instruction->ref_count = old_instruction->ref_count;
2648 *slot = new_instruction;2728 *slot = new_instruction;
...@@ -2703,6 +2783,21 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {...@@ -2703,6 +2783,21 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {
2703 return ir_gen(codegn, body_node, scope, ir_executable);2783 return ir_gen(codegn, body_node, scope, ir_executable);
2704}2784}
27052785
2786static IrInstruction *ir_eval_fn(IrAnalyze *ira, IrInstruction *source_instruction,
2787 size_t arg_count, IrInstruction **args)
2788{
2789 zig_panic("TODO ir_eval_fn");
2790}
2791
2792static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) {
2793 if (ir_should_inline(&ira->new_irb)) {
2794 add_node_error(ira->codegen, source_instruction->source_node,
2795 buf_sprintf("unable to evaluate constant expression"));
2796 return false;
2797 }
2798 return true;
2799}
2800
2706static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type) {2801static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type) {
2707 TypeTableEntry *other_type_underlying = get_underlying_type(other_type);2802 TypeTableEntry *other_type_underlying = get_underlying_type(other_type);
27082803
...@@ -2918,20 +3013,15 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -2918,20 +3013,15 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
2918}3013}
29193014
2920static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,3015static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
2921 IrInstruction *dest_type, CastOp cast_op, bool need_alloca)3016 TypeTableEntry *wanted_type, CastOp cast_op, bool need_alloca)
2922{3017{
2923 assert(dest_type->type_entry->id == TypeTableEntryIdMetaType);
2924 assert(dest_type->static_value.special != ConstValSpecialRuntime);
2925 TypeTableEntry *wanted_type = dest_type->static_value.data.x_type;
2926
2927 if (value->static_value.special != ConstValSpecialRuntime) {3018 if (value->static_value.special != ConstValSpecialRuntime) {
2928 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->source_node, wanted_type);3019 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->source_node, wanted_type, false);
2929 eval_const_expr_implicit_cast(cast_op, &value->static_value, value->type_entry,3020 eval_const_expr_implicit_cast(cast_op, &value->static_value, value->type_entry,
2930 &result->static_value, wanted_type);3021 &result->static_value, wanted_type);
2931 return result;3022 return result;
2932 } else {3023 } else {
2933 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->source_node,3024 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->source_node, wanted_type, value, cast_op);
2934 dest_type, value, cast_op);
2935 result->type_entry = wanted_type;3025 result->type_entry = wanted_type;
2936 if (need_alloca && source_instr->source_node->block_context->fn_entry) {3026 if (need_alloca && source_instr->source_node->block_context->fn_entry) {
2937 source_instr->source_node->block_context->fn_entry->alloca_list.append(result);3027 source_instr->source_node->block_context->fn_entry->alloca_list.append(result);
...@@ -3126,12 +3216,8 @@ static FnTableEntry *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) {...@@ -3126,12 +3216,8 @@ static FnTableEntry *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) {
3126}3216}
31273217
3128static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,3218static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
3129 IrInstruction *dest_type, IrInstruction *value)3219 TypeTableEntry *wanted_type, IrInstruction *value)
3130{3220{
3131 assert(dest_type->type_entry->id == TypeTableEntryIdMetaType);
3132 assert(dest_type->static_value.special != ConstValSpecialRuntime);
3133
3134 TypeTableEntry *wanted_type = dest_type->static_value.data.x_type;
3135 TypeTableEntry *actual_type = value->type_entry;3221 TypeTableEntry *actual_type = value->type_entry;
3136 TypeTableEntry *wanted_type_canon = get_underlying_type(wanted_type);3222 TypeTableEntry *wanted_type_canon = get_underlying_type(wanted_type);
3137 TypeTableEntry *actual_type_canon = get_underlying_type(actual_type);3223 TypeTableEntry *actual_type_canon = get_underlying_type(actual_type);
...@@ -3147,21 +3233,21 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3147,21 +3233,21 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
31473233
3148 // explicit match or non-const to const3234 // explicit match or non-const to const
3149 if (types_match_const_cast_only(wanted_type, actual_type)) {3235 if (types_match_const_cast_only(wanted_type, actual_type)) {
3150 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpNoop, false);3236 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
3151 }3237 }
31523238
3153 // explicit cast from bool to int3239 // explicit cast from bool to int
3154 if (wanted_type_canon->id == TypeTableEntryIdInt &&3240 if (wanted_type_canon->id == TypeTableEntryIdInt &&
3155 actual_type_canon->id == TypeTableEntryIdBool)3241 actual_type_canon->id == TypeTableEntryIdBool)
3156 {3242 {
3157 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpBoolToInt, false);3243 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpBoolToInt, false);
3158 }3244 }
31593245
3160 // explicit cast from pointer to isize or usize3246 // explicit cast from pointer to isize or usize
3161 if ((wanted_type_canon == isize_type || wanted_type_canon == usize_type) &&3247 if ((wanted_type_canon == isize_type || wanted_type_canon == usize_type) &&
3162 type_is_codegen_pointer(actual_type_canon))3248 type_is_codegen_pointer(actual_type_canon))
3163 {3249 {
3164 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpPtrToInt, false);3250 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpPtrToInt, false);
3165 }3251 }
31663252
31673253
...@@ -3169,7 +3255,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3169,7 +3255,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3169 if (wanted_type_canon->id == TypeTableEntryIdPointer &&3255 if (wanted_type_canon->id == TypeTableEntryIdPointer &&
3170 (actual_type_canon == isize_type || actual_type_canon == usize_type))3256 (actual_type_canon == isize_type || actual_type_canon == usize_type))
3171 {3257 {
3172 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpIntToPtr, false);3258 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpIntToPtr, false);
3173 }3259 }
31743260
3175 // explicit widening or shortening cast3261 // explicit widening or shortening cast
...@@ -3178,21 +3264,21 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3178,21 +3264,21 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3178 (wanted_type_canon->id == TypeTableEntryIdFloat &&3264 (wanted_type_canon->id == TypeTableEntryIdFloat &&
3179 actual_type_canon->id == TypeTableEntryIdFloat))3265 actual_type_canon->id == TypeTableEntryIdFloat))
3180 {3266 {
3181 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpWidenOrShorten, false);3267 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpWidenOrShorten, false);
3182 }3268 }
31833269
3184 // explicit cast from int to float3270 // explicit cast from int to float
3185 if (wanted_type_canon->id == TypeTableEntryIdFloat &&3271 if (wanted_type_canon->id == TypeTableEntryIdFloat &&
3186 actual_type_canon->id == TypeTableEntryIdInt)3272 actual_type_canon->id == TypeTableEntryIdInt)
3187 {3273 {
3188 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpIntToFloat, false);3274 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpIntToFloat, false);
3189 }3275 }
31903276
3191 // explicit cast from float to int3277 // explicit cast from float to int
3192 if (wanted_type_canon->id == TypeTableEntryIdInt &&3278 if (wanted_type_canon->id == TypeTableEntryIdInt &&
3193 actual_type_canon->id == TypeTableEntryIdFloat)3279 actual_type_canon->id == TypeTableEntryIdFloat)
3194 {3280 {
3195 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpFloatToInt, false);3281 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpFloatToInt, false);
3196 }3282 }
31973283
3198 // explicit cast from array to slice3284 // explicit cast from array to slice
...@@ -3202,7 +3288,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3202,7 +3288,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3202 wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type,3288 wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type,
3203 actual_type->data.array.child_type))3289 actual_type->data.array.child_type))
3204 {3290 {
3205 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpToUnknownSizeArray, true);3291 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpToUnknownSizeArray, true);
3206 }3292 }
32073293
3208 // explicit cast from []T to []u8 or []u8 to []T3294 // explicit cast from []T to []u8 or []u8 to []T
...@@ -3212,8 +3298,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3212,8 +3298,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3212 (wanted_type->data.structure.fields[0].type_entry->data.pointer.is_const ||3298 (wanted_type->data.structure.fields[0].type_entry->data.pointer.is_const ||
3213 !actual_type->data.structure.fields[0].type_entry->data.pointer.is_const))3299 !actual_type->data.structure.fields[0].type_entry->data.pointer.is_const))
3214 {3300 {
3215 mark_impure_fn(ira->codegen, source_instr->source_node->block_context, source_instr->source_node);3301 if (!ir_emit_global_runtime_side_effect(ira, source_instr))
3216 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpResizeSlice, true);3302 return ira->codegen->invalid_instruction;
3303 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpResizeSlice, true);
3217 }3304 }
32183305
3219 // explicit cast from [N]u8 to []T3306 // explicit cast from [N]u8 to []T
...@@ -3221,11 +3308,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3221,11 +3308,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3221 actual_type->id == TypeTableEntryIdArray &&3308 actual_type->id == TypeTableEntryIdArray &&
3222 is_u8(actual_type->data.array.child_type))3309 is_u8(actual_type->data.array.child_type))
3223 {3310 {
3224 mark_impure_fn(ira->codegen, source_instr->source_node->block_context, source_instr->source_node);3311 if (!ir_emit_global_runtime_side_effect(ira, source_instr))
3312 return ira->codegen->invalid_instruction;
3225 uint64_t child_type_size = type_size(ira->codegen,3313 uint64_t child_type_size = type_size(ira->codegen,
3226 wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type);3314 wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type);
3227 if (actual_type->data.array.len % child_type_size == 0) {3315 if (actual_type->data.array.len % child_type_size == 0) {
3228 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpBytesToSlice, true);3316 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpBytesToSlice, true);
3229 } else {3317 } else {
3230 add_node_error(ira->codegen, source_instr->source_node,3318 add_node_error(ira->codegen, source_instr->source_node,
3231 buf_sprintf("unable to convert %s to %s: size mismatch",3319 buf_sprintf("unable to convert %s to %s: size mismatch",
...@@ -3238,7 +3326,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3238,7 +3326,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3238 if ((actual_type->id == TypeTableEntryIdPointer || actual_type->id == TypeTableEntryIdFn) &&3326 if ((actual_type->id == TypeTableEntryIdPointer || actual_type->id == TypeTableEntryIdFn) &&
3239 (wanted_type->id == TypeTableEntryIdPointer || wanted_type->id == TypeTableEntryIdFn))3327 (wanted_type->id == TypeTableEntryIdPointer || wanted_type->id == TypeTableEntryIdFn))
3240 {3328 {
3241 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpPointerReinterpret, false);3329 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpPointerReinterpret, false);
3242 }3330 }
32433331
3244 // explicit cast from maybe pointer to another maybe pointer3332 // explicit cast from maybe pointer to another maybe pointer
...@@ -3249,13 +3337,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3249,13 +3337,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3249 (wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer ||3337 (wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer ||
3250 wanted_type->data.maybe.child_type->id == TypeTableEntryIdFn))3338 wanted_type->data.maybe.child_type->id == TypeTableEntryIdFn))
3251 {3339 {
3252 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpPointerReinterpret, false);3340 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpPointerReinterpret, false);
3253 }3341 }
32543342
3255 // explicit cast from child type of maybe type to maybe type3343 // explicit cast from child type of maybe type to maybe type
3256 if (wanted_type->id == TypeTableEntryIdMaybe) {3344 if (wanted_type->id == TypeTableEntryIdMaybe) {
3257 if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) {3345 if (types_match_const_cast_only(wanted_type->data.maybe.child_type, actual_type)) {
3258 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, dest_type,3346 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, wanted_type,
3259 CastOpMaybeWrap, true);3347 CastOpMaybeWrap, true);
3260 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonNull;3348 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonNull;
3261 return cast_instruction;3349 return cast_instruction;
...@@ -3263,7 +3351,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3263,7 +3351,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3263 actual_type->id == TypeTableEntryIdNumLitFloat)3351 actual_type->id == TypeTableEntryIdNumLitFloat)
3264 {3352 {
3265 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.maybe.child_type)) {3353 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.maybe.child_type)) {
3266 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, dest_type,3354 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, wanted_type,
3267 CastOpMaybeWrap, true);3355 CastOpMaybeWrap, true);
3268 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonNull;3356 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonNull;
3269 return cast_instruction;3357 return cast_instruction;
...@@ -3277,7 +3365,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3277,7 +3365,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3277 if (wanted_type->id == TypeTableEntryIdMaybe &&3365 if (wanted_type->id == TypeTableEntryIdMaybe &&
3278 actual_type->id == TypeTableEntryIdNullLit)3366 actual_type->id == TypeTableEntryIdNullLit)
3279 {3367 {
3280 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, dest_type,3368 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, wanted_type,
3281 CastOpNullToMaybe, true);3369 CastOpNullToMaybe, true);
3282 cast_instruction->return_knowledge = ReturnKnowledgeKnownNull;3370 cast_instruction->return_knowledge = ReturnKnowledgeKnownNull;
3283 return cast_instruction;3371 return cast_instruction;
...@@ -3286,7 +3374,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3286,7 +3374,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3286 // explicit cast from child type of error type to error type3374 // explicit cast from child type of error type to error type
3287 if (wanted_type->id == TypeTableEntryIdErrorUnion) {3375 if (wanted_type->id == TypeTableEntryIdErrorUnion) {
3288 if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) {3376 if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) {
3289 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, dest_type,3377 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, wanted_type,
3290 CastOpErrorWrap, true);3378 CastOpErrorWrap, true);
3291 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonError;3379 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonError;
3292 return cast_instruction;3380 return cast_instruction;
...@@ -3294,7 +3382,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3294,7 +3382,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3294 actual_type->id == TypeTableEntryIdNumLitFloat)3382 actual_type->id == TypeTableEntryIdNumLitFloat)
3295 {3383 {
3296 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error.child_type)) {3384 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error.child_type)) {
3297 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, dest_type,3385 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, wanted_type,
3298 CastOpErrorWrap, true);3386 CastOpErrorWrap, true);
3299 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonError;3387 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonError;
3300 return cast_instruction;3388 return cast_instruction;
...@@ -3308,7 +3396,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3308,7 +3396,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3308 if (wanted_type->id == TypeTableEntryIdErrorUnion &&3396 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
3309 actual_type->id == TypeTableEntryIdPureError)3397 actual_type->id == TypeTableEntryIdPureError)
3310 {3398 {
3311 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, dest_type,3399 IrInstruction *cast_instruction = ir_resolve_cast(ira, source_instr, value, wanted_type,
3312 CastOpPureErrorWrap, false);3400 CastOpPureErrorWrap, false);
3313 cast_instruction->return_knowledge = ReturnKnowledgeKnownError;3401 cast_instruction->return_knowledge = ReturnKnowledgeKnownError;
3314 return cast_instruction;3402 return cast_instruction;
...@@ -3333,7 +3421,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3333,7 +3421,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3333 } else {3421 } else {
3334 zig_unreachable();3422 zig_unreachable();
3335 }3423 }
3336 return ir_resolve_cast(ira, source_instr, value, dest_type, op, false);3424 return ir_resolve_cast(ira, source_instr, value, wanted_type, op, false);
3337 } else {3425 } else {
3338 return ira->codegen->invalid_instruction;3426 return ira->codegen->invalid_instruction;
3339 }3427 }
...@@ -3351,7 +3439,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3351,7 +3439,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3351 if (bignum_fits_in_bits(&bn, wanted_type->data.integral.bit_count,3439 if (bignum_fits_in_bits(&bn, wanted_type->data.integral.bit_count,
3352 wanted_type->data.integral.is_signed))3440 wanted_type->data.integral.is_signed))
3353 {3441 {
3354 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpErrToInt, false);3442 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpErrToInt, false);
3355 } else {3443 } else {
3356 add_node_error(ira->codegen, source_instr->source_node,3444 add_node_error(ira->codegen, source_instr->source_node,
3357 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name)));3445 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name)));
...@@ -3364,7 +3452,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3364,7 +3452,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3364 wanted_type->id == TypeTableEntryIdEnum &&3452 wanted_type->id == TypeTableEntryIdEnum &&
3365 wanted_type->data.enumeration.gen_field_count == 0)3453 wanted_type->data.enumeration.gen_field_count == 0)
3366 {3454 {
3367 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpIntToEnum, false);3455 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpIntToEnum, false);
3368 }3456 }
33693457
3370 // explicit cast from enum type with no payload to integer3458 // explicit cast from enum type with no payload to integer
...@@ -3372,12 +3460,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3372,12 +3460,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
3372 actual_type->id == TypeTableEntryIdEnum &&3460 actual_type->id == TypeTableEntryIdEnum &&
3373 actual_type->data.enumeration.gen_field_count == 0)3461 actual_type->data.enumeration.gen_field_count == 0)
3374 {3462 {
3375 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpEnumToInt, false);3463 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpEnumToInt, false);
3376 }3464 }
33773465
3378 // explicit cast from undefined to anything3466 // explicit cast from undefined to anything
3379 if (actual_type->id == TypeTableEntryIdUndefLit) {3467 if (actual_type->id == TypeTableEntryIdUndefLit) {
3380 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpNoop, false);3468 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
3381 }3469 }
33823470
3383 add_node_error(ira->codegen, source_instr->source_node,3471 add_node_error(ira->codegen, source_instr->source_node,
...@@ -3410,11 +3498,7 @@ static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value,...@@ -3410,11 +3498,7 @@ static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value,
3410 return ira->codegen->invalid_instruction;3498 return ira->codegen->invalid_instruction;
34113499
3412 case ImplicitCastMatchResultYes:3500 case ImplicitCastMatchResultYes:
3413 {3501 return ir_analyze_cast(ira, value, expected_type, value);
3414 IrInstruction *dest_type = ir_create_const_type(&ira->new_irb, value->source_node, expected_type);
3415 IrInstruction *cast_instruction = ir_analyze_cast(ira, value, dest_type, value);
3416 return cast_instruction;
3417 }
3418 case ImplicitCastMatchResultReportedError:3502 case ImplicitCastMatchResultReportedError:
3419 return ira->codegen->invalid_instruction;3503 return ira->codegen->invalid_instruction;
3420 }3504 }
...@@ -3422,6 +3506,58 @@ static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value,...@@ -3422,6 +3506,58 @@ static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value,
3422 zig_unreachable();3506 zig_unreachable();
3423}3507}
34243508
3509static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) {
3510 TypeTableEntry *type_entry = ptr->type_entry;
3511 if (type_entry->id == TypeTableEntryIdInvalid) {
3512 return ira->codegen->invalid_instruction;
3513 } else if (type_entry->id == TypeTableEntryIdPointer) {
3514 TypeTableEntry *child_type = type_entry->data.pointer.child_type;
3515 if (ptr->static_value.special != ConstValSpecialRuntime) {
3516 ConstExprValue *pointee = const_ptr_pointee(&ptr->static_value);
3517 if (pointee->special != ConstValSpecialRuntime) {
3518 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->source_node,
3519 child_type, pointee->depends_on_compile_var);
3520 result->static_value = *pointee;
3521 return result;
3522 }
3523 }
3524 IrInstruction *load_ptr_instruction = ir_build_load_ptr(&ira->new_irb, source_instruction->source_node, ptr);
3525 load_ptr_instruction->type_entry = child_type;
3526 return load_ptr_instruction;
3527 } else {
3528 add_node_error(ira->codegen, source_instruction->source_node,
3529 buf_sprintf("attempt to dereference non pointer type '%s'",
3530 buf_ptr(&type_entry->name)));
3531 return ira->codegen->invalid_instruction;
3532 }
3533}
3534
3535static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value) {
3536 if (value->type_entry->id == TypeTableEntryIdInvalid)
3537 return ira->codegen->builtin_types.entry_invalid;
3538
3539 bool is_inline = ir_should_inline(&ira->new_irb);
3540 if (is_inline || value->static_value.special != ConstValSpecialRuntime) {
3541 ConstExprValue *val = ir_resolve_const(ira, value);
3542 if (!val)
3543 return ira->codegen->builtin_types.entry_invalid;
3544 return ir_analyze_const_ptr(ira, source_instruction, val, value->type_entry, false);
3545 }
3546
3547 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, value->type_entry, true);
3548 if (handle_is_ptr(value->type_entry)) {
3549 // this instruction is a noop - codegen can pass the pointer we already have as the result
3550 ir_link_new_instruction(value, source_instruction);
3551 return ptr_type;
3552 } else {
3553 FnTableEntry *fn_entry = source_instruction->source_node->block_context->fn_entry;
3554 IrInstruction *new_instruction = ir_build_ref_from(&ira->new_irb, source_instruction, value);
3555 fn_entry->alloca_list.append(new_instruction);
3556 return ptr_type;
3557 }
3558}
3559
3560
3425static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) {3561static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) {
3426 if (value->type_entry->id == TypeTableEntryIdInvalid)3562 if (value->type_entry->id == TypeTableEntryIdInvalid)
3427 return false;3563 return false;
...@@ -3580,6 +3716,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -3580,6 +3716,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
3580 case TypeTableEntryIdNamespace:3716 case TypeTableEntryIdNamespace:
3581 case TypeTableEntryIdBlock:3717 case TypeTableEntryIdBlock:
3582 case TypeTableEntryIdGenericFn:3718 case TypeTableEntryIdGenericFn:
3719 case TypeTableEntryIdBoundFn:
3583 if (!is_equality_cmp) {3720 if (!is_equality_cmp) {
3584 add_node_error(ira->codegen, source_node,3721 add_node_error(ira->codegen, source_node,
3585 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));3722 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));
...@@ -3944,6 +4081,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -3944,6 +4081,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
3944 case TypeTableEntryIdUnion:4081 case TypeTableEntryIdUnion:
3945 case TypeTableEntryIdFn:4082 case TypeTableEntryIdFn:
3946 case TypeTableEntryIdGenericFn:4083 case TypeTableEntryIdGenericFn:
4084 case TypeTableEntryIdBoundFn:
3947 // OK4085 // OK
3948 break;4086 break;
3949 }4087 }
...@@ -3966,13 +4104,121 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -3966,13 +4104,121 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
3966 return ira->codegen->builtin_types.entry_void;4104 return ira->codegen->builtin_types.entry_void;
3967}4105}
39684106
4107static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction,
4108 FnTableEntry *fn_entry, TypeTableEntry *fn_type, IrInstruction *fn_ref,
4109 IrInstruction *first_arg_ptr, bool is_inline)
4110{
4111 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
4112 size_t first_arg_1_or_0 = first_arg_ptr ? 1 : 0;
4113 size_t src_param_count = fn_type_id->param_count;
4114 size_t call_param_count = call_instruction->arg_count + first_arg_1_or_0;
4115 AstNode *source_node = call_instruction->base.source_node;
4116
4117 AstNode *fn_proto_node = fn_entry ? fn_entry->proto_node : nullptr;;
4118
4119 if (fn_type_id->is_var_args) {
4120 if (call_param_count < src_param_count) {
4121 ErrorMsg *msg = add_node_error(ira->codegen, source_node,
4122 buf_sprintf("expected at least %zu arguments, found %zu", src_param_count, call_param_count));
4123 if (fn_proto_node) {
4124 add_error_note(ira->codegen, msg, fn_proto_node,
4125 buf_sprintf("declared here"));
4126 }
4127 return ira->codegen->builtin_types.entry_invalid;
4128 }
4129 } else if (src_param_count != call_param_count) {
4130 ErrorMsg *msg = add_node_error(ira->codegen, source_node,
4131 buf_sprintf("expected %zu arguments, found %zu", src_param_count, call_param_count));
4132 if (fn_proto_node) {
4133 add_error_note(ira->codegen, msg, fn_proto_node,
4134 buf_sprintf("declared here"));
4135 }
4136 return ira->codegen->builtin_types.entry_invalid;
4137 }
4138
4139 IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count);
4140 size_t next_arg_index = 0;
4141 if (first_arg_ptr) {
4142 IrInstruction *first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);
4143 if (first_arg->type_entry->id == TypeTableEntryIdInvalid)
4144 return ira->codegen->builtin_types.entry_invalid;
4145
4146 TypeTableEntry *param_type = fn_type_id->param_info[next_arg_index].type;
4147 if (param_type->id == TypeTableEntryIdInvalid)
4148 return ira->codegen->builtin_types.entry_invalid;
4149
4150 IrInstruction *casted_arg = ir_get_casted_value(ira, first_arg, param_type);
4151 if (casted_arg->type_entry->id == TypeTableEntryIdInvalid)
4152 return ira->codegen->builtin_types.entry_invalid;
4153
4154 if (is_inline && !ir_resolve_const(ira, casted_arg))
4155 return ira->codegen->builtin_types.entry_invalid;
4156
4157 casted_args[next_arg_index] = casted_arg;
4158 next_arg_index += 1;
4159 }
4160 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) {
4161 IrInstruction *old_arg = call_instruction->args[call_i]->other;
4162 if (old_arg->type_entry->id == TypeTableEntryIdInvalid)
4163 return ira->codegen->builtin_types.entry_invalid;
4164 IrInstruction *casted_arg;
4165 if (next_arg_index < src_param_count) {
4166 TypeTableEntry *param_type = fn_type_id->param_info[next_arg_index].type;
4167 if (param_type->id == TypeTableEntryIdInvalid)
4168 return ira->codegen->builtin_types.entry_invalid;
4169 casted_arg = ir_get_casted_value(ira, old_arg, param_type);
4170 if (casted_arg->type_entry->id == TypeTableEntryIdInvalid)
4171 return ira->codegen->builtin_types.entry_invalid;
4172 } else {
4173 casted_arg = old_arg;
4174 }
4175
4176 if (is_inline && !ir_resolve_const(ira, casted_arg))
4177 return ira->codegen->builtin_types.entry_invalid;
4178
4179 casted_args[next_arg_index] = casted_arg;
4180 next_arg_index += 1;
4181 }
4182
4183 assert(next_arg_index == call_param_count);
4184
4185 TypeTableEntry *return_type = fn_type_id->return_type;
4186 if (return_type->id == TypeTableEntryIdInvalid)
4187 return ira->codegen->builtin_types.entry_invalid;
4188
4189 if (is_inline) {
4190 IrInstruction *result = ir_eval_fn(ira, &call_instruction->base, call_param_count, casted_args);
4191 if (result->type_entry->id == TypeTableEntryIdInvalid)
4192 return ira->codegen->builtin_types.entry_invalid;
4193
4194 ConstExprValue *out_val = ir_build_const_from(ira, &call_instruction->base,
4195 result->static_value.depends_on_compile_var);
4196 *out_val = result->static_value;
4197 return ir_finish_anal(ira, return_type);
4198 }
4199
4200 IrInstruction *new_call_instruction = ir_build_call_from(&ira->new_irb, &call_instruction->base,
4201 fn_entry, fn_ref, call_param_count, casted_args);
4202
4203 if (type_has_bits(return_type) && handle_is_ptr(return_type))
4204 call_instruction->base.source_node->block_context->fn_entry->alloca_list.append(new_call_instruction);
4205
4206 return ir_finish_anal(ira, return_type);
4207}
4208
3969static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) {4209static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) {
3970 IrInstruction *fn_ref = call_instruction->fn->other;4210 IrInstruction *fn_ref = call_instruction->fn_ref->other;
3971 if (fn_ref->type_entry->id == TypeTableEntryIdInvalid)4211 if (fn_ref->type_entry->id == TypeTableEntryIdInvalid)
3972 return ira->codegen->builtin_types.entry_invalid;4212 return ira->codegen->builtin_types.entry_invalid;
39734213
3974 if (fn_ref->static_value.special != ConstValSpecialRuntime) {4214 bool is_inline = call_instruction->is_inline || ir_should_inline(&ira->new_irb);
4215
4216 if (is_inline || fn_ref->static_value.special != ConstValSpecialRuntime) {
3975 if (fn_ref->type_entry->id == TypeTableEntryIdMetaType) {4217 if (fn_ref->type_entry->id == TypeTableEntryIdMetaType) {
4218 TypeTableEntry *dest_type = ir_resolve_type(ira, fn_ref);
4219 if (!dest_type)
4220 return ira->codegen->builtin_types.entry_invalid;
4221
3976 size_t actual_param_count = call_instruction->arg_count;4222 size_t actual_param_count = call_instruction->arg_count;
39774223
3978 if (actual_param_count != 1) {4224 if (actual_param_count != 1) {
...@@ -3982,38 +4228,39 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction...@@ -3982,38 +4228,39 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
3982 }4228 }
39834229
3984 IrInstruction *arg = call_instruction->args[0]->other;4230 IrInstruction *arg = call_instruction->args[0]->other;
3985 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, fn_ref, arg);4231
3986 if (cast_instruction == ira->codegen->invalid_instruction)4232 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg);
4233 if (cast_instruction->type_entry->id == TypeTableEntryIdInvalid)
3987 return ira->codegen->builtin_types.entry_invalid;4234 return ira->codegen->builtin_types.entry_invalid;
39884235
3989 ir_link_new_instruction(cast_instruction, &call_instruction->base);4236 ir_link_new_instruction(cast_instruction, &call_instruction->base);
3990 return ir_finish_anal(ira, cast_instruction->type_entry);4237 return ir_finish_anal(ira, cast_instruction->type_entry);
3991 } else if (fn_ref->type_entry->id == TypeTableEntryIdFn) {4238 } else if (fn_ref->type_entry->id == TypeTableEntryIdFn) {
3992 // TODO fully port over the fn call analyze code to IR4239 FnTableEntry *fn_table_entry = ir_resolve_fn(ira, fn_ref);
3993 FnTableEntry *fn_table_entry = fn_ref->static_value.data.x_fn;4240 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry,
3994 TypeTableEntry *fn_type = fn_table_entry->type_entry;4241 fn_ref, nullptr, is_inline);
39954242 } else if (fn_ref->type_entry->id == TypeTableEntryIdBoundFn) {
3996 IrInstruction **casted_args = allocate<IrInstruction *>(call_instruction->arg_count);4243 assert(fn_ref->static_value.special == ConstValSpecialStatic);
3997 for (size_t i = 0; i < call_instruction->arg_count; i += 1) {4244 FnTableEntry *fn_table_entry = fn_ref->static_value.data.x_bound_fn.fn;
3998 TypeTableEntry *param_type = fn_type->data.fn.fn_type_id.param_info[i].type;4245 IrInstruction *first_arg_ptr = fn_ref->static_value.data.x_bound_fn.first_arg;
3999 IrInstruction *old_arg = call_instruction->args[i]->other;4246 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry,
4000 if (old_arg->type_entry->id == TypeTableEntryIdInvalid)4247 nullptr, first_arg_ptr, is_inline);
4001 return ira->codegen->builtin_types.entry_invalid;4248 } else if (fn_ref->type_entry->id == TypeTableEntryIdGenericFn) {
4002 casted_args[i] = ir_get_casted_value(ira, old_arg, param_type);4249 zig_panic("TODO generic fn call");
4003 }
4004
4005 ir_build_call_from(&ira->new_irb, &call_instruction->base,
4006 fn_ref, call_instruction->arg_count, casted_args);
4007
4008 return ir_finish_anal(ira, fn_type->data.fn.fn_type_id.return_type);
4009 } else {4250 } else {
4010 zig_panic("TODO analyze more fn call types");4251 add_node_error(ira->codegen, fn_ref->source_node,
4252 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->type_entry->name)));
4253 return ira->codegen->builtin_types.entry_invalid;
4011 }4254 }
4012 } else {4255 }
4013 //ir_build_call_from(&ira->new_irb, &call_instruction->base,
4014 // call_instruction->fn, call_instruction->arg_count, call_instruction->args);
40154256
4016 zig_panic("TODO analyze fn call");4257 if (fn_ref->type_entry->id == TypeTableEntryIdFn) {
4258 return ir_analyze_fn_call(ira, call_instruction, nullptr, fn_ref->type_entry,
4259 fn_ref, nullptr, false);
4260 } else {
4261 add_node_error(ira->codegen, fn_ref->source_node,
4262 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->type_entry->name)));
4263 return ira->codegen->builtin_types.entry_invalid;
4017 }4264 }
4018}4265}
40194266
...@@ -4071,6 +4318,7 @@ static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstruct...@@ -4071,6 +4318,7 @@ static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstruct
4071 case TypeTableEntryIdUnion:4318 case TypeTableEntryIdUnion:
4072 case TypeTableEntryIdFn:4319 case TypeTableEntryIdFn:
4073 case TypeTableEntryIdGenericFn:4320 case TypeTableEntryIdGenericFn:
4321 case TypeTableEntryIdBoundFn:
4074 {4322 {
4075 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base,4323 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base,
4076 value->static_value.depends_on_compile_var);4324 value->static_value.depends_on_compile_var);
...@@ -4119,6 +4367,7 @@ static TypeTableEntry *ir_analyze_unary_address_of(IrAnalyze *ira, IrInstruction...@@ -4119,6 +4367,7 @@ static TypeTableEntry *ir_analyze_unary_address_of(IrAnalyze *ira, IrInstruction
4119 case TypeTableEntryIdUnreachable:4367 case TypeTableEntryIdUnreachable:
4120 case TypeTableEntryIdVar:4368 case TypeTableEntryIdVar:
4121 case TypeTableEntryIdGenericFn:4369 case TypeTableEntryIdGenericFn:
4370 case TypeTableEntryIdBoundFn:
4122 add_node_error(ira->codegen, un_op_instruction->base.source_node,4371 add_node_error(ira->codegen, un_op_instruction->base.source_node,
4123 buf_sprintf("unable to get address of type '%s'", buf_ptr(&target_type->name)));4372 buf_sprintf("unable to get address of type '%s'", buf_ptr(&target_type->name)));
4124 // TODO if type decl, add note pointing to type decl declaration4373 // TODO if type decl, add note pointing to type decl declaration
...@@ -4217,6 +4466,7 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op...@@ -4217,6 +4466,7 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op
4217 case TypeTableEntryIdNamespace:4466 case TypeTableEntryIdNamespace:
4218 case TypeTableEntryIdBlock:4467 case TypeTableEntryIdBlock:
4219 case TypeTableEntryIdGenericFn:4468 case TypeTableEntryIdGenericFn:
4469 case TypeTableEntryIdBoundFn:
4220 {4470 {
4221 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base,4471 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base,
4222 value->static_value.depends_on_compile_var);4472 value->static_value.depends_on_compile_var);
...@@ -4626,7 +4876,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -4626,7 +4876,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
46264876
4627static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira,4877static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira,
4628 TypeTableEntry *bare_struct_type, Buf *field_name, IrInstructionFieldPtr *field_ptr_instruction,4878 TypeTableEntry *bare_struct_type, Buf *field_name, IrInstructionFieldPtr *field_ptr_instruction,
4629 TypeTableEntry *container_type)4879 IrInstruction *container_ptr, TypeTableEntry *container_type)
4630{4880{
4631 if (!is_slice(bare_struct_type)) {4881 if (!is_slice(bare_struct_type)) {
4632 BlockContext *container_block_context = get_container_block_context(bare_struct_type);4882 BlockContext *container_block_context = get_container_block_context(bare_struct_type);
...@@ -4634,7 +4884,15 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira,...@@ -4634,7 +4884,15 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira,
4634 auto entry = container_block_context->decl_table.maybe_get(field_name);4884 auto entry = container_block_context->decl_table.maybe_get(field_name);
4635 AstNode *fn_decl_node = entry ? entry->value : nullptr;4885 AstNode *fn_decl_node = entry ? entry->value : nullptr;
4636 if (fn_decl_node && fn_decl_node->type == NodeTypeFnProto) {4886 if (fn_decl_node && fn_decl_node->type == NodeTypeFnProto) {
4637 zig_panic("TODO member function call");4887 resolve_top_level_decl(ira->codegen, fn_decl_node, false);
4888 TopLevelDecl *tld = get_as_top_level_decl(fn_decl_node);
4889 if (tld->resolution == TldResolutionInvalid)
4890 return ira->codegen->builtin_types.entry_invalid;
4891 FnTableEntry *fn_entry = fn_decl_node->data.fn_proto.fn_table_entry;
4892 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;
4893 IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb,
4894 field_ptr_instruction->base.source_node, fn_entry, container_ptr, depends_on_compile_var);
4895 return ir_analyze_ref(ira, &field_ptr_instruction->base, bound_fn_value);
4638 }4896 }
4639 }4897 }
4640 add_node_error(ira->codegen, field_ptr_instruction->base.source_node,4898 add_node_error(ira->codegen, field_ptr_instruction->base.source_node,
...@@ -4643,14 +4901,12 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira,...@@ -4643,14 +4901,12 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira,
4643}4901}
46444902
46454903
4646static TypeTableEntry *ir_analyze_container_member_access(IrAnalyze *ira, Buf *field_name,4904static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,
4647 IrInstructionFieldPtr *field_ptr_instruction, TypeTableEntry *container_type)4905 IrInstructionFieldPtr *field_ptr_instruction, IrInstruction *container_ptr, TypeTableEntry *container_type)
4648{4906{
4649 IrInstruction *container_ptr = field_ptr_instruction->container_ptr->other;
4650 TypeTableEntry *bare_type = container_ref_type(container_type);4907 TypeTableEntry *bare_type = container_ref_type(container_type);
4651 if (!type_is_complete(bare_type)) {4908 if (!type_is_complete(bare_type))
4652 resolve_container_type(ira->codegen, bare_type);4909 resolve_container_type(ira->codegen, bare_type);
4653 }
46544910
4655 if (bare_type->id == TypeTableEntryIdStruct) {4911 if (bare_type->id == TypeTableEntryIdStruct) {
4656 TypeStructField *field = find_struct_type_field(bare_type, field_name);4912 TypeStructField *field = find_struct_type_field(bare_type, field_name);
...@@ -4659,10 +4915,17 @@ static TypeTableEntry *ir_analyze_container_member_access(IrAnalyze *ira, Buf *f...@@ -4659,10 +4915,17 @@ static TypeTableEntry *ir_analyze_container_member_access(IrAnalyze *ira, Buf *f
4659 return get_pointer_to_type(ira->codegen, field->type_entry, false);4915 return get_pointer_to_type(ira->codegen, field->type_entry, false);
4660 } else {4916 } else {
4661 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,4917 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
4662 field_ptr_instruction, container_type);4918 field_ptr_instruction, container_ptr, container_type);
4663 }4919 }
4664 } else if (bare_type->id == TypeTableEntryIdEnum) {4920 } else if (bare_type->id == TypeTableEntryIdEnum) {
4665 zig_panic("TODO enum field ptr");4921 TypeEnumField *field = find_enum_type_field(bare_type, field_name);
4922 if (field) {
4923 ir_build_enum_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
4924 return get_pointer_to_type(ira->codegen, field->type_entry, false);
4925 } else {
4926 return ir_analyze_container_member_access_inner(ira, bare_type, field_name,
4927 field_ptr_instruction, container_ptr, container_type);
4928 }
4666 } else if (bare_type->id == TypeTableEntryIdUnion) {4929 } else if (bare_type->id == TypeTableEntryIdUnion) {
4667 zig_panic("TODO");4930 zig_panic("TODO");
4668 } else {4931 } else {
...@@ -4733,7 +4996,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -4733,7 +4996,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
4733 if (container_type->id == TypeTableEntryIdInvalid) {4996 if (container_type->id == TypeTableEntryIdInvalid) {
4734 return container_type;4997 return container_type;
4735 } else if (is_container_ref(container_type)) {4998 } else if (is_container_ref(container_type)) {
4736 return ir_analyze_container_member_access(ira, field_name, field_ptr_instruction, container_type);4999 return ir_analyze_container_field_ptr(ira, field_name, field_ptr_instruction, container_ptr, container_type);
4737 } else if (container_type->id == TypeTableEntryIdArray) {5000 } else if (container_type->id == TypeTableEntryIdArray) {
4738 if (buf_eql_str(field_name, "len")) {5001 if (buf_eql_str(field_name, "len")) {
4739 ConstExprValue *len_val = allocate<ConstExprValue>(1);5002 ConstExprValue *len_val = allocate<ConstExprValue>(1);
...@@ -4749,24 +5012,38 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -4749,24 +5012,38 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
4749 return ira->codegen->builtin_types.entry_invalid;5012 return ira->codegen->builtin_types.entry_invalid;
4750 }5013 }
4751 } else if (container_type->id == TypeTableEntryIdMetaType) {5014 } else if (container_type->id == TypeTableEntryIdMetaType) {
4752 zig_panic("TODO type field access");5015 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr);
4753 //TypeTableEntry *child_type = ir_resolve_type(ira, container_ptr);5016 if (!container_ptr_val)
47545017 return ira->codegen->builtin_types.entry_invalid;
4755 //if (child_type->id == TypeTableEntryIdInvalid) {5018 ConstExprValue *child_val = const_ptr_pointee(container_ptr_val);
4756 // return ira->codegen->builtin_types.entry_invalid;5019 TypeTableEntry *child_type = child_val->data.x_type;
4757 //} else if (child_type->id == TypeTableEntryIdEnum) {5020
4758 // zig_panic("TODO enum type field");5021 if (child_type->id == TypeTableEntryIdInvalid) {
4759 //} else if (child_type->id == TypeTableEntryIdStruct) {5022 return ira->codegen->builtin_types.entry_invalid;
4760 // zig_panic("TODO struct type field");5023 } else if (child_type->id == TypeTableEntryIdEnum) {
4761 //} else if (child_type->id == TypeTableEntryIdPureError) {5024 zig_panic("TODO enum type field");
4762 // zig_panic("TODO error type field");5025 } else if (child_type->id == TypeTableEntryIdStruct) {
4763 //} else if (child_type->id == TypeTableEntryIdInt) {5026 BlockContext *container_block_context = get_container_block_context(child_type);
4764 // zig_panic("TODO integer type field");5027 auto entry = container_block_context->decl_table.maybe_get(field_name);
4765 //} else {5028 AstNode *decl_node = entry ? entry->value : nullptr;
4766 // add_node_error(ira->codegen, source_node,5029 if (decl_node) {
4767 // buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));5030 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;
4768 // return ira->codegen->builtin_types.entry_invalid;5031 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, decl_node, depends_on_compile_var);
4769 //}5032 } else {
5033 add_node_error(ira->codegen, source_node,
5034 buf_sprintf("container '%s' has no member called '%s'",
5035 buf_ptr(&child_type->name), buf_ptr(field_name)));
5036 return ira->codegen->builtin_types.entry_invalid;
5037 }
5038 } else if (child_type->id == TypeTableEntryIdPureError) {
5039 zig_panic("TODO error type field");
5040 } else if (child_type->id == TypeTableEntryIdInt) {
5041 zig_panic("TODO integer type field");
5042 } else {
5043 add_node_error(ira->codegen, source_node,
5044 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
5045 return ira->codegen->builtin_types.entry_invalid;
5046 }
4770 } else if (container_type->id == TypeTableEntryIdNamespace) {5047 } else if (container_type->id == TypeTableEntryIdNamespace) {
4771 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr);5048 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr);
4772 if (!container_ptr_val)5049 if (!container_ptr_val)
...@@ -4817,28 +5094,10 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -4817,28 +5094,10 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
48175094
4818static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *load_ptr_instruction) {5095static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *load_ptr_instruction) {
4819 IrInstruction *ptr = load_ptr_instruction->ptr->other;5096 IrInstruction *ptr = load_ptr_instruction->ptr->other;
4820 TypeTableEntry *type_entry = ptr->type_entry;5097 IrInstruction *result = ir_get_deref(ira, &load_ptr_instruction->base, ptr);
4821 if (type_entry->id == TypeTableEntryIdInvalid) {5098 ir_link_new_instruction(result, &load_ptr_instruction->base);
4822 return type_entry;5099 assert(result->type_entry);
4823 } else if (type_entry->id == TypeTableEntryIdPointer) {5100 return result->type_entry;
4824 TypeTableEntry *child_type = type_entry->data.pointer.child_type;
4825 if (ptr->static_value.special != ConstValSpecialRuntime) {
4826 ConstExprValue *pointee = const_ptr_pointee(&ptr->static_value);
4827 if (pointee->special != ConstValSpecialRuntime) {
4828 ConstExprValue *out_val = ir_build_const_from(ira, &load_ptr_instruction->base,
4829 pointee->depends_on_compile_var);
4830 *out_val = *pointee;
4831 return child_type;
4832 }
4833 }
4834 ir_build_load_ptr_from(&ira->new_irb, &load_ptr_instruction->base, ptr);
4835 return child_type;
4836 } else {
4837 add_node_error(ira->codegen, load_ptr_instruction->base.source_node,
4838 buf_sprintf("attempt to dereference non pointer type '%s'",
4839 buf_ptr(&type_entry->name)));
4840 return ira->codegen->builtin_types.entry_invalid;
4841 }
4842}5101}
48435102
4844static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstructionStorePtr *store_ptr_instruction) {5103static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstructionStorePtr *store_ptr_instruction) {
...@@ -4911,6 +5170,7 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi...@@ -4911,6 +5170,7 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi
4911 case TypeTableEntryIdNamespace:5170 case TypeTableEntryIdNamespace:
4912 case TypeTableEntryIdBlock:5171 case TypeTableEntryIdBlock:
4913 case TypeTableEntryIdGenericFn:5172 case TypeTableEntryIdGenericFn:
5173 case TypeTableEntryIdBoundFn:
4914 case TypeTableEntryIdMetaType:5174 case TypeTableEntryIdMetaType:
4915 case TypeTableEntryIdVoid:5175 case TypeTableEntryIdVoid:
4916 case TypeTableEntryIdBool:5176 case TypeTableEntryIdBool:
...@@ -5148,6 +5408,7 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,...@@ -5148,6 +5408,7 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
5148 case TypeTableEntryIdFn:5408 case TypeTableEntryIdFn:
5149 case TypeTableEntryIdNamespace:5409 case TypeTableEntryIdNamespace:
5150 case TypeTableEntryIdGenericFn:5410 case TypeTableEntryIdGenericFn:
5411 case TypeTableEntryIdBoundFn:
5151 {5412 {
5152 TypeTableEntry *result_type = get_slice_type(ira->codegen, resolved_child_type, is_const);5413 TypeTableEntry *result_type = get_slice_type(ira->codegen, resolved_child_type, is_const);
5153 ConstExprValue *out_val = ir_build_const_from(ira, &slice_type_instruction->base,5414 ConstExprValue *out_val = ir_build_const_from(ira, &slice_type_instruction->base,
...@@ -5161,8 +5422,9 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,...@@ -5161,8 +5422,9 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
51615422
5162static TypeTableEntry *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAsm *asm_instruction) {5423static TypeTableEntry *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAsm *asm_instruction) {
5163 assert(asm_instruction->base.source_node->type == NodeTypeAsmExpr);5424 assert(asm_instruction->base.source_node->type == NodeTypeAsmExpr);
5164 mark_impure_fn(ira->codegen, asm_instruction->base.source_node->block_context,5425
5165 asm_instruction->base.source_node);5426 if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base))
5427 return ira->codegen->builtin_types.entry_invalid;
51665428
5167 // TODO validate the output types and variable types5429 // TODO validate the output types and variable types
51685430
...@@ -5236,6 +5498,7 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,...@@ -5236,6 +5498,7 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,
5236 case TypeTableEntryIdFn:5498 case TypeTableEntryIdFn:
5237 case TypeTableEntryIdNamespace:5499 case TypeTableEntryIdNamespace:
5238 case TypeTableEntryIdGenericFn:5500 case TypeTableEntryIdGenericFn:
5501 case TypeTableEntryIdBoundFn:
5239 {5502 {
5240 TypeTableEntry *result_type = get_array_type(ira->codegen, child_type, size);5503 TypeTableEntry *result_type = get_array_type(ira->codegen, child_type, size);
5241 bool depends_on_compile_var = child_type_value->static_value.depends_on_compile_var ||5504 bool depends_on_compile_var = child_type_value->static_value.depends_on_compile_var ||
...@@ -5306,6 +5569,7 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,...@@ -5306,6 +5569,7 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,
5306 case TypeTableEntryIdNumLitFloat:5569 case TypeTableEntryIdNumLitFloat:
5307 case TypeTableEntryIdNumLitInt:5570 case TypeTableEntryIdNumLitInt:
5308 case TypeTableEntryIdGenericFn:5571 case TypeTableEntryIdGenericFn:
5572 case TypeTableEntryIdBoundFn:
5309 case TypeTableEntryIdMetaType:5573 case TypeTableEntryIdMetaType:
5310 case TypeTableEntryIdFn:5574 case TypeTableEntryIdFn:
5311 case TypeTableEntryIdNamespace:5575 case TypeTableEntryIdNamespace:
...@@ -5469,7 +5733,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,...@@ -5469,7 +5733,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,
5469 return ir_unreach_error(ira);5733 return ir_unreach_error(ira);
54705734
5471 size_t case_count = switch_br_instruction->case_count;5735 size_t case_count = switch_br_instruction->case_count;
5472 bool is_inline = switch_br_instruction->is_inline;5736 bool is_inline = ir_should_inline(&ira->new_irb) || switch_br_instruction->is_inline;
54735737
5474 if (is_inline || target_value->static_value.special != ConstValSpecialRuntime) {5738 if (is_inline || target_value->static_value.special != ConstValSpecialRuntime) {
5475 ConstExprValue *target_val = ir_resolve_const(ira, target_value);5739 ConstExprValue *target_val = ir_resolve_const(ira, target_value);
...@@ -5599,6 +5863,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -5599,6 +5863,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
5599 case TypeTableEntryIdUnion:5863 case TypeTableEntryIdUnion:
5600 case TypeTableEntryIdBlock:5864 case TypeTableEntryIdBlock:
5601 case TypeTableEntryIdGenericFn:5865 case TypeTableEntryIdGenericFn:
5866 case TypeTableEntryIdBoundFn:
5602 add_node_error(ira->codegen, switch_target_instruction->base.source_node,5867 add_node_error(ira->codegen, switch_target_instruction->base.source_node,
5603 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));5868 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));
5604 // TODO if this is a typedecl, add error note showing the declaration of the type decl5869 // TODO if this is a typedecl, add error note showing the declaration of the type decl
...@@ -5741,51 +6006,222 @@ static TypeTableEntry *ir_analyze_instruction_array_len(IrAnalyze *ira,...@@ -5741,51 +6006,222 @@ static TypeTableEntry *ir_analyze_instruction_array_len(IrAnalyze *ira,
57416006
5742static TypeTableEntry *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRef *ref_instruction) {6007static TypeTableEntry *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRef *ref_instruction) {
5743 IrInstruction *value = ref_instruction->value->other;6008 IrInstruction *value = ref_instruction->value->other;
5744 if (value->type_entry->id == TypeTableEntryIdInvalid)6009 return ir_analyze_ref(ira, &ref_instruction->base, value);
5745 return ira->codegen->builtin_types.entry_invalid;6010}
57466011
5747 FnTableEntry *fn_entry = ref_instruction->base.source_node->block_context->fn_entry;6012static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction,
5748 if (!fn_entry || value->static_value.special != ConstValSpecialRuntime) {6013 TypeTableEntry *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields,
5749 ConstExprValue *val = ir_resolve_const(ira, value);6014 bool depends_on_compile_var)
5750 if (!val)6015{
6016 size_t actual_field_count = container_type->data.structure.src_field_count;
6017
6018 IrInstruction *first_non_const_instruction = nullptr;
6019
6020 AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count);
6021
6022 IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count);
6023
6024 FnTableEntry *fn_entry = instruction->source_node->block_context->fn_entry;
6025 bool outside_fn = (fn_entry == nullptr);
6026
6027 ConstExprValue const_val = {};
6028 const_val.special = ConstValSpecialStatic;
6029 const_val.depends_on_compile_var = depends_on_compile_var;
6030 const_val.data.x_struct.fields = allocate<ConstExprValue>(actual_field_count);
6031 for (size_t i = 0; i < instr_field_count; i += 1) {
6032 IrInstructionContainerInitFieldsField *field = &fields[i];
6033
6034 IrInstruction *field_value = field->value->other;
6035 if (field_value->type_entry->id == TypeTableEntryIdInvalid)
6036 return ira->codegen->builtin_types.entry_invalid;
6037
6038 TypeStructField *type_field = find_struct_type_field(container_type, field->name);
6039 if (!type_field) {
6040 add_node_error(ira->codegen, field->source_node,
6041 buf_sprintf("no member named '%s' in '%s'",
6042 buf_ptr(field->name), buf_ptr(&container_type->name)));
6043 return ira->codegen->builtin_types.entry_invalid;
6044 }
6045
6046 if (type_field->type_entry->id == TypeTableEntryIdInvalid)
5751 return ira->codegen->builtin_types.entry_invalid;6047 return ira->codegen->builtin_types.entry_invalid;
5752 return ir_analyze_const_ptr(ira, &ref_instruction->base, val, value->type_entry, false);6048
6049 size_t field_index = type_field->src_index;
6050 AstNode *existing_assign_node = field_assign_nodes[field_index];
6051 if (existing_assign_node) {
6052 ErrorMsg *msg = add_node_error(ira->codegen, field->source_node, buf_sprintf("duplicate field"));
6053 add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here"));
6054 continue;
6055 }
6056 field_assign_nodes[field_index] = field->source_node;
6057
6058 new_fields[field_index].value = field_value;
6059 new_fields[field_index].type_struct_field = type_field;
6060
6061 if (const_val.special == ConstValSpecialStatic) {
6062 if (outside_fn || field_value->static_value.special != ConstValSpecialRuntime) {
6063 ConstExprValue *field_val = ir_resolve_const(ira, field_value);
6064 if (!field_val)
6065 return ira->codegen->builtin_types.entry_invalid;
6066
6067 const_val.data.x_struct.fields[field_index] = *field_val;
6068 const_val.depends_on_compile_var = const_val.depends_on_compile_var || field_val->depends_on_compile_var;
6069 } else {
6070 first_non_const_instruction = field_value;
6071 const_val.special = ConstValSpecialRuntime;
6072 }
6073 }
5753 }6074 }
57546075
5755 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, value->type_entry, true);6076 bool any_missing = false;
5756 if (handle_is_ptr(value->type_entry)) {6077 for (size_t i = 0; i < actual_field_count; i += 1) {
5757 // this instruction is a noop - codegen can pass the pointer we already have as the result6078 if (!field_assign_nodes[i]) {
5758 ir_link_new_instruction(value, &ref_instruction->base);6079 add_node_error(ira->codegen, instruction->source_node,
5759 return ptr_type;6080 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));
5760 } else {6081 any_missing = true;
5761 fn_entry->alloca_list.append(&ref_instruction->base);6082 }
5762 ir_build_ref_from(&ira->new_irb, &ref_instruction->base, value);6083 }
5763 return ptr_type;6084 if (any_missing)
6085 return ira->codegen->builtin_types.entry_invalid;
6086
6087 if (const_val.special == ConstValSpecialStatic) {
6088 ConstExprValue *out_val = ir_build_const_from(ira, instruction, const_val.depends_on_compile_var);
6089 *out_val = const_val;
6090 return container_type;
6091 }
6092
6093 if (outside_fn) {
6094 add_node_error(ira->codegen, first_non_const_instruction->source_node,
6095 buf_sprintf("unable to evaluate constant expression"));
6096 return ira->codegen->builtin_types.entry_invalid;
5764 }6097 }
6098
6099 IrInstruction *new_instruction = ir_build_struct_init_from(&ira->new_irb, instruction,
6100 container_type, actual_field_count, new_fields);
6101 fn_entry->alloca_list.append(new_instruction);
6102 return container_type;
5765}6103}
57666104
5767static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {6105static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira, IrInstructionContainerInitList *instruction) {
5768 switch (instruction->id) {6106 IrInstruction *container_type_value = instruction->container_type->other;
5769 case IrInstructionIdInvalid:6107 TypeTableEntry *container_type = ir_resolve_type(ira, container_type_value);
5770 zig_unreachable();6108 if (!container_type)
5771 case IrInstructionIdReturn:6109 return ira->codegen->builtin_types.entry_invalid;
5772 return ir_analyze_instruction_return(ira, (IrInstructionReturn *)instruction);6110
5773 case IrInstructionIdConst:6111 size_t elem_count = instruction->item_count;
5774 return ir_analyze_instruction_const(ira, (IrInstructionConst *)instruction);6112 bool depends_on_compile_var = container_type_value->static_value.depends_on_compile_var;
5775 case IrInstructionIdUnOp:6113
5776 return ir_analyze_instruction_un_op(ira, (IrInstructionUnOp *)instruction);6114 if (container_type->id == TypeTableEntryIdStruct && !is_slice(container_type) && elem_count == 0) {
5777 case IrInstructionIdBinOp:6115 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, depends_on_compile_var);
5778 return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction);6116 } else if (is_slice(container_type)) {
5779 case IrInstructionIdDeclVar:6117 TypeTableEntry *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry;
5780 return ir_analyze_instruction_decl_var(ira, (IrInstructionDeclVar *)instruction);6118 assert(pointer_type->id == TypeTableEntryIdPointer);
5781 case IrInstructionIdLoadPtr:6119 TypeTableEntry *child_type = pointer_type->data.pointer.child_type;
5782 return ir_analyze_instruction_load_ptr(ira, (IrInstructionLoadPtr *)instruction);6120
5783 case IrInstructionIdStorePtr:6121 ConstExprValue const_val = {};
5784 return ir_analyze_instruction_store_ptr(ira, (IrInstructionStorePtr *)instruction);6122 const_val.special = ConstValSpecialStatic;
5785 case IrInstructionIdElemPtr:6123 const_val.depends_on_compile_var = depends_on_compile_var;
5786 return ir_analyze_instruction_elem_ptr(ira, (IrInstructionElemPtr *)instruction);6124 const_val.data.x_array.elements = allocate<ConstExprValue>(elem_count);
5787 case IrInstructionIdVarPtr:6125 const_val.data.x_array.size = elem_count;
5788 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction);6126
6127 FnTableEntry *fn_entry = instruction->base.source_node->block_context->fn_entry;
6128 bool outside_fn = (fn_entry == nullptr);
6129
6130 IrInstruction **new_items = allocate<IrInstruction *>(elem_count);
6131
6132 IrInstruction *first_non_const_instruction = nullptr;
6133
6134 for (size_t i = 0; i < elem_count; i += 1) {
6135 IrInstruction *arg_value = instruction->items[i]->other;
6136 if (arg_value->type_entry->id == TypeTableEntryIdInvalid)
6137 return ira->codegen->builtin_types.entry_invalid;
6138
6139 new_items[i] = arg_value;
6140
6141 if (const_val.special == ConstValSpecialStatic) {
6142 if (outside_fn || arg_value->static_value.special != ConstValSpecialRuntime) {
6143 ConstExprValue *elem_val = ir_resolve_const(ira, arg_value);
6144 if (!elem_val)
6145 return ira->codegen->builtin_types.entry_invalid;
6146
6147 const_val.data.x_array.elements[i] = *elem_val;
6148 const_val.depends_on_compile_var = const_val.depends_on_compile_var || elem_val->depends_on_compile_var;
6149 } else {
6150 first_non_const_instruction = arg_value;
6151 const_val.special = ConstValSpecialRuntime;
6152 }
6153 }
6154 }
6155
6156 TypeTableEntry *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count);
6157 if (const_val.special == ConstValSpecialStatic) {
6158 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, const_val.depends_on_compile_var);
6159 *out_val = const_val;
6160 return fixed_size_array_type;
6161 }
6162
6163 if (outside_fn) {
6164 add_node_error(ira->codegen, first_non_const_instruction->source_node,
6165 buf_sprintf("unable to evaluate constant expression"));
6166 return ira->codegen->builtin_types.entry_invalid;
6167 }
6168
6169 IrInstruction *new_instruction = ir_build_container_init_list_from(&ira->new_irb, &instruction->base,
6170 container_type_value, elem_count, new_items);
6171 fn_entry->alloca_list.append(new_instruction);
6172 return fixed_size_array_type;
6173 } else if (container_type->id == TypeTableEntryIdArray) {
6174 // same as slice init but we make a compile error if the length is wrong
6175 zig_panic("TODO array container init");
6176 } else if (container_type->id == TypeTableEntryIdVoid) {
6177 if (elem_count != 0) {
6178 add_node_error(ira->codegen, instruction->base.source_node,
6179 buf_sprintf("void expression expects no arguments"));
6180 return ira->codegen->builtin_types.entry_invalid;
6181 }
6182 return ir_analyze_void(ira, &instruction->base);
6183 } else {
6184 add_node_error(ira->codegen, instruction->base.source_node,
6185 buf_sprintf("type '%s' does not support array initialization",
6186 buf_ptr(&container_type->name)));
6187 return ira->codegen->builtin_types.entry_invalid;
6188 }
6189}
6190
6191static TypeTableEntry *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, IrInstructionContainerInitFields *instruction) {
6192 IrInstruction *container_type_value = instruction->container_type->other;
6193 TypeTableEntry *container_type = ir_resolve_type(ira, container_type_value);
6194 if (!container_type)
6195 return ira->codegen->builtin_types.entry_invalid;
6196
6197 bool depends_on_compile_var = container_type_value->static_value.depends_on_compile_var;
6198
6199 return ir_analyze_container_init_fields(ira, &instruction->base, container_type,
6200 instruction->field_count, instruction->fields, depends_on_compile_var);
6201}
6202
6203static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
6204 switch (instruction->id) {
6205 case IrInstructionIdInvalid:
6206 zig_unreachable();
6207 case IrInstructionIdReturn:
6208 return ir_analyze_instruction_return(ira, (IrInstructionReturn *)instruction);
6209 case IrInstructionIdConst:
6210 return ir_analyze_instruction_const(ira, (IrInstructionConst *)instruction);
6211 case IrInstructionIdUnOp:
6212 return ir_analyze_instruction_un_op(ira, (IrInstructionUnOp *)instruction);
6213 case IrInstructionIdBinOp:
6214 return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction);
6215 case IrInstructionIdDeclVar:
6216 return ir_analyze_instruction_decl_var(ira, (IrInstructionDeclVar *)instruction);
6217 case IrInstructionIdLoadPtr:
6218 return ir_analyze_instruction_load_ptr(ira, (IrInstructionLoadPtr *)instruction);
6219 case IrInstructionIdStorePtr:
6220 return ir_analyze_instruction_store_ptr(ira, (IrInstructionStorePtr *)instruction);
6221 case IrInstructionIdElemPtr:
6222 return ir_analyze_instruction_elem_ptr(ira, (IrInstructionElemPtr *)instruction);
6223 case IrInstructionIdVarPtr:
6224 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction);
5789 case IrInstructionIdFieldPtr:6225 case IrInstructionIdFieldPtr:
5790 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction);6226 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction);
5791 case IrInstructionIdCall:6227 case IrInstructionIdCall:
...@@ -5844,10 +6280,14 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -5844,10 +6280,14 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
5844 return ir_analyze_instruction_array_len(ira, (IrInstructionArrayLen *)instruction);6280 return ir_analyze_instruction_array_len(ira, (IrInstructionArrayLen *)instruction);
5845 case IrInstructionIdRef:6281 case IrInstructionIdRef:
5846 return ir_analyze_instruction_ref(ira, (IrInstructionRef *)instruction);6282 return ir_analyze_instruction_ref(ira, (IrInstructionRef *)instruction);
5847 case IrInstructionIdCast:
5848 case IrInstructionIdContainerInitList:6283 case IrInstructionIdContainerInitList:
6284 return ir_analyze_instruction_container_init_list(ira, (IrInstructionContainerInitList *)instruction);
5849 case IrInstructionIdContainerInitFields:6285 case IrInstructionIdContainerInitFields:
6286 return ir_analyze_instruction_container_init_fields(ira, (IrInstructionContainerInitFields *)instruction);
6287 case IrInstructionIdCast:
5850 case IrInstructionIdStructFieldPtr:6288 case IrInstructionIdStructFieldPtr:
6289 case IrInstructionIdEnumFieldPtr:
6290 case IrInstructionIdStructInit:
5851 zig_panic("TODO analyze more instructions");6291 zig_panic("TODO analyze more instructions");
5852 }6292 }
5853 zig_unreachable();6293 zig_unreachable();
...@@ -5947,6 +6387,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -5947,6 +6387,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
5947 case IrInstructionIdCast:6387 case IrInstructionIdCast:
5948 case IrInstructionIdContainerInitList:6388 case IrInstructionIdContainerInitList:
5949 case IrInstructionIdContainerInitFields:6389 case IrInstructionIdContainerInitFields:
6390 case IrInstructionIdStructInit:
5950 case IrInstructionIdFieldPtr:6391 case IrInstructionIdFieldPtr:
5951 case IrInstructionIdElemPtr:6392 case IrInstructionIdElemPtr:
5952 case IrInstructionIdVarPtr:6393 case IrInstructionIdVarPtr:
...@@ -5955,6 +6396,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -5955,6 +6396,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
5955 case IrInstructionIdPtrTypeChild:6396 case IrInstructionIdPtrTypeChild:
5956 case IrInstructionIdArrayLen:6397 case IrInstructionIdArrayLen:
5957 case IrInstructionIdStructFieldPtr:6398 case IrInstructionIdStructFieldPtr:
6399 case IrInstructionIdEnumFieldPtr:
5958 case IrInstructionIdArrayType:6400 case IrInstructionIdArrayType:
5959 case IrInstructionIdSliceType:6401 case IrInstructionIdSliceType:
5960 case IrInstructionIdCompileVar:6402 case IrInstructionIdCompileVar:
...@@ -6393,46 +6835,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -6393,46 +6835,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
6393// return g->builtin_types.entry_void;6835// return g->builtin_types.entry_void;
6394//}6836//}
6395//6837//
6396//static TypeTableEntry *analyze_set_fn_static_eval(CodeGen *g, ImportTableEntry *import,
6397// BlockContext *context, AstNode *node)
6398//{
6399// AstNode **fn_node = &node->data.fn_call_expr.params.at(0);
6400// AstNode **value_node = &node->data.fn_call_expr.params.at(1);
6401//
6402// FnTableEntry *fn_entry = resolve_const_expr_fn(g, import, context, fn_node);
6403// if (!fn_entry) {
6404// return g->builtin_types.entry_invalid;
6405// }
6406//
6407// bool want_static_eval;
6408// bool ok = resolve_const_expr_bool(g, import, context, value_node, &want_static_eval);
6409// if (!ok) {
6410// return g->builtin_types.entry_invalid;
6411// }
6412//
6413// if (fn_entry->fn_static_eval_set_node) {
6414// ErrorMsg *msg = add_node_error(g, node, buf_sprintf("function static eval attribute set twice"));
6415// add_error_note(g, msg, fn_entry->fn_static_eval_set_node, buf_sprintf("first set here"));
6416// return g->builtin_types.entry_invalid;
6417// }
6418// fn_entry->fn_static_eval_set_node = node;
6419//
6420// if (want_static_eval && !context->fn_entry->is_pure) {
6421// add_node_error(g, node, buf_sprintf("attribute appears too late within function"));
6422// return g->builtin_types.entry_invalid;
6423// }
6424//
6425// if (want_static_eval) {
6426// fn_entry->want_pure = WantPureTrue;
6427// fn_entry->want_pure_attr_node = node;
6428// } else {
6429// fn_entry->want_pure = WantPureFalse;
6430// fn_entry->is_pure = false;
6431// }
6432//
6433// return g->builtin_types.entry_void;
6434//}
6435//
6436//static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,6838//static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
6437// TypeTableEntry *expected_type, AstNode *node)6839// TypeTableEntry *expected_type, AstNode *node)
6438//{6840//{
...@@ -6634,713 +7036,10 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -6634,713 +7036,10 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
6634// return analyze_set_fn_test(g, import, context, node);7036// return analyze_set_fn_test(g, import, context, node);
6635// case BuiltinFnIdSetFnNoInline:7037// case BuiltinFnIdSetFnNoInline:
6636// return analyze_set_fn_no_inline(g, import, context, node);7038// return analyze_set_fn_no_inline(g, import, context, node);
6637// case BuiltinFnIdSetFnStaticEval:
6638// return analyze_set_fn_static_eval(g, import, context, node);
6639// }7039// }
6640// zig_unreachable();7040// zig_unreachable();
6641//}7041//}
66427042
6643//static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry *import,
6644// BlockContext *context, AstNode *node)
6645//{
6646// assert(node->type == NodeTypeContainerInitExpr);
6647//
6648// AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
6649//
6650// ContainerInitKind kind = container_init_expr->kind;
6651//
6652// if (container_init_expr->type->type == NodeTypeFieldAccessExpr) {
6653// container_init_expr->type->data.field_access_expr.container_init_expr_node = node;
6654// }
6655//
6656// TypeTableEntry *container_meta_type = analyze_expression(g, import, context, nullptr,
6657// container_init_expr->type);
6658//
6659// if (container_meta_type->id == TypeTableEntryIdInvalid) {
6660// return g->builtin_types.entry_invalid;
6661// }
6662//
6663// if (node->data.container_init_expr.enum_type) {
6664// get_resolved_expr(node)->const_val = get_resolved_expr(container_init_expr->type)->const_val;
6665// return node->data.container_init_expr.enum_type;
6666// }
6667//
6668// TypeTableEntry *container_type = resolve_type(g, container_init_expr->type);
6669//
6670// if (container_type->id == TypeTableEntryIdInvalid) {
6671// return container_type;
6672// } else if (container_type->id == TypeTableEntryIdStruct &&
6673// !container_type->data.structure.is_slice &&
6674// (kind == ContainerInitKindStruct || (kind == ContainerInitKindArray &&
6675// container_init_expr->entries.length == 0)))
6676// {
6677// StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr;
6678// codegen->type_entry = container_type;
6679// codegen->source_node = node;
6680//
6681//
6682// size_t expr_field_count = container_init_expr->entries.length;
6683// size_t actual_field_count = container_type->data.structure.src_field_count;
6684//
6685// AstNode *non_const_expr_culprit = nullptr;
6686//
6687// size_t *field_use_counts = allocate<size_t>(actual_field_count);
6688// ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
6689// const_val->ok = true;
6690// const_val->data.x_struct.fields = allocate<ConstExprValue*>(actual_field_count);
6691// for (size_t i = 0; i < expr_field_count; i += 1) {
6692// AstNode *val_field_node = container_init_expr->entries.at(i);
6693// assert(val_field_node->type == NodeTypeStructValueField);
6694//
6695// val_field_node->block_context = context;
6696//
6697// TypeStructField *type_field = find_struct_type_field(container_type,
6698// val_field_node->data.struct_val_field.name);
6699//
6700// if (!type_field) {
6701// add_node_error(g, val_field_node,
6702// buf_sprintf("no member named '%s' in '%s'",
6703// buf_ptr(val_field_node->data.struct_val_field.name), buf_ptr(&container_type->name)));
6704// continue;
6705// }
6706//
6707// if (type_field->type_entry->id == TypeTableEntryIdInvalid) {
6708// return g->builtin_types.entry_invalid;
6709// }
6710//
6711// size_t field_index = type_field->src_index;
6712// field_use_counts[field_index] += 1;
6713// if (field_use_counts[field_index] > 1) {
6714// add_node_error(g, val_field_node, buf_sprintf("duplicate field"));
6715// continue;
6716// }
6717//
6718// val_field_node->data.struct_val_field.type_struct_field = type_field;
6719//
6720// analyze_expression(g, import, context, type_field->type_entry,
6721// val_field_node->data.struct_val_field.expr);
6722//
6723// if (const_val->ok) {
6724// ConstExprValue *field_val =
6725// &get_resolved_expr(val_field_node->data.struct_val_field.expr)->const_val;
6726// if (field_val->ok) {
6727// const_val->data.x_struct.fields[field_index] = field_val;
6728// const_val->depends_on_compile_var = const_val->depends_on_compile_var || field_val->depends_on_compile_var;
6729// } else {
6730// const_val->ok = false;
6731// non_const_expr_culprit = val_field_node->data.struct_val_field.expr;
6732// }
6733// }
6734// }
6735// if (!const_val->ok) {
6736// assert(non_const_expr_culprit);
6737// if (context->fn_entry) {
6738// context->fn_entry->struct_val_expr_alloca_list.append(codegen);
6739// } else {
6740// add_node_error(g, non_const_expr_culprit, buf_sprintf("unable to evaluate constant expression"));
6741// }
6742// }
6743//
6744// for (size_t i = 0; i < actual_field_count; i += 1) {
6745// if (field_use_counts[i] == 0) {
6746// add_node_error(g, node,
6747// buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));
6748// }
6749// }
6750// return container_type;
6751// } else if (container_type->id == TypeTableEntryIdStruct &&
6752// container_type->data.structure.is_slice &&
6753// kind == ContainerInitKindArray)
6754// {
6755// size_t elem_count = container_init_expr->entries.length;
6756//
6757// TypeTableEntry *pointer_type = container_type->data.structure.fields[0].type_entry;
6758// assert(pointer_type->id == TypeTableEntryIdPointer);
6759// TypeTableEntry *child_type = pointer_type->data.pointer.child_type;
6760//
6761// ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
6762// const_val->ok = true;
6763// const_val->data.x_array.fields = allocate<ConstExprValue*>(elem_count);
6764//
6765// for (size_t i = 0; i < elem_count; i += 1) {
6766// AstNode **elem_node = &container_init_expr->entries.at(i);
6767// analyze_expression(g, import, context, child_type, *elem_node);
6768//
6769// if (const_val->ok) {
6770// ConstExprValue *elem_const_val = &get_resolved_expr(*elem_node)->const_val;
6771// if (elem_const_val->ok) {
6772// const_val->data.x_array.fields[i] = elem_const_val;
6773// const_val->depends_on_compile_var = const_val->depends_on_compile_var ||
6774// elem_const_val->depends_on_compile_var;
6775// } else {
6776// const_val->ok = false;
6777// }
6778// }
6779// }
6780//
6781// TypeTableEntry *fixed_size_array_type = get_array_type(g, child_type, elem_count);
6782//
6783// StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr;
6784// codegen->type_entry = fixed_size_array_type;
6785// codegen->source_node = node;
6786// if (!const_val->ok) {
6787// if (!context->fn_entry) {
6788// add_node_error(g, node,
6789// buf_sprintf("unable to evaluate constant expression"));
6790// } else {
6791// context->fn_entry->struct_val_expr_alloca_list.append(codegen);
6792// }
6793// }
6794//
6795// return fixed_size_array_type;
6796// } else if (container_type->id == TypeTableEntryIdArray) {
6797// zig_panic("TODO array container init");
6798// return container_type;
6799// } else if (container_type->id == TypeTableEntryIdVoid) {
6800// if (container_init_expr->entries.length != 0) {
6801// add_node_error(g, node, buf_sprintf("void expression expects no arguments"));
6802// return g->builtin_types.entry_invalid;
6803// } else {
6804// return resolve_expr_const_val_as_void(g, node);
6805// }
6806// } else {
6807// add_node_error(g, node,
6808// buf_sprintf("type '%s' does not support %s initialization syntax",
6809// buf_ptr(&container_type->name), err_container_init_syntax_name(kind)));
6810// return g->builtin_types.entry_invalid;
6811// }
6812//}
6813
6814
6815
6816//static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
6817// TypeTableEntry *expected_type, AstNode *node)
6818//{
6819// assert(node->type == NodeTypeFieldAccessExpr);
6820//
6821// AstNode **struct_expr_node = &node->data.field_access_expr.struct_expr;
6822// TypeTableEntry *struct_type = analyze_expression(g, import, context, nullptr, *struct_expr_node);
6823// Buf *field_name = node->data.field_access_expr.field_name;
6824//
6825// if (struct_type->id == TypeTableEntryIdInvalid) {
6826// return struct_type;
6827// } else if (is_container_ref(struct_type)) {
6828// return analyze_container_member_access(g, field_name, node, struct_type);
6829// } else if (struct_type->id == TypeTableEntryIdArray) {
6830// if (buf_eql_str(field_name, "len")) {
6831// return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type,
6832// struct_type->data.array.len, false);
6833// } else {
6834// add_node_error(g, node,
6835// buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name),
6836// buf_ptr(&struct_type->name)));
6837// return g->builtin_types.entry_invalid;
6838// }
6839// } else if (struct_type->id == TypeTableEntryIdMetaType) {
6840// TypeTableEntry *child_type = resolve_type(g, *struct_expr_node);
6841//
6842// if (child_type->id == TypeTableEntryIdInvalid) {
6843// return g->builtin_types.entry_invalid;
6844// } else if (child_type->id == TypeTableEntryIdEnum) {
6845// AstNode *container_init_node = node->data.field_access_expr.container_init_expr_node;
6846// AstNode *value_node;
6847// if (container_init_node) {
6848// assert(container_init_node->type == NodeTypeContainerInitExpr);
6849// size_t param_count = container_init_node->data.container_init_expr.entries.length;
6850// if (param_count > 1) {
6851// AstNode *first_invalid_node = container_init_node->data.container_init_expr.entries.at(1);
6852// add_node_error(g, first_executing_node(first_invalid_node),
6853// buf_sprintf("enum values accept only one parameter"));
6854// return child_type;
6855// } else {
6856// if (param_count == 1) {
6857// value_node = container_init_node->data.container_init_expr.entries.at(0);
6858// } else {
6859// value_node = nullptr;
6860// }
6861// container_init_node->data.container_init_expr.enum_type = child_type;
6862// }
6863// } else {
6864// value_node = nullptr;
6865// }
6866// return analyze_enum_value_expr(g, import, context, node, value_node, child_type, field_name, node);
6867// } else if (child_type->id == TypeTableEntryIdStruct) {
6868// BlockContext *container_block_context = get_container_block_context(child_type);
6869// auto entry = container_block_context->decl_table.maybe_get(field_name);
6870// AstNode *decl_node = entry ? entry->value : nullptr;
6871// if (decl_node) {
6872// bool pointer_only = false;
6873// return analyze_decl_ref(g, node, decl_node, pointer_only, context, false);
6874// } else {
6875// add_node_error(g, node,
6876// buf_sprintf("container '%s' has no member called '%s'",
6877// buf_ptr(&child_type->name), buf_ptr(field_name)));
6878// return g->builtin_types.entry_invalid;
6879// }
6880// } else if (child_type->id == TypeTableEntryIdPureError) {
6881// return analyze_error_literal_expr(g, import, context, node, field_name);
6882// } else if (child_type->id == TypeTableEntryIdInt) {
6883// bool depends_on_compile_var =
6884// get_resolved_expr(*struct_expr_node)->const_val.depends_on_compile_var;
6885// if (buf_eql_str(field_name, "bit_count")) {
6886// return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type,
6887// child_type->data.integral.bit_count, depends_on_compile_var);
6888// } else if (buf_eql_str(field_name, "is_signed")) {
6889// return resolve_expr_const_val_as_bool(g, node, child_type->data.integral.is_signed,
6890// depends_on_compile_var);
6891// } else {
6892// add_node_error(g, node,
6893// buf_sprintf("type '%s' has no member called '%s'",
6894// buf_ptr(&child_type->name), buf_ptr(field_name)));
6895// return g->builtin_types.entry_invalid;
6896// }
6897// } else {
6898// add_node_error(g, node,
6899// buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));
6900// return g->builtin_types.entry_invalid;
6901// }
6902// } else {
6903// add_node_error(g, node,
6904// buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));
6905// return g->builtin_types.entry_invalid;
6906// }
6907//}
6908//
6909//static TypeTableEntry *bad_method_call(CodeGen *g, AstNode *node, TypeTableEntry *container_type,
6910// TypeTableEntry *expected_param_type, FnTableEntry *fn_table_entry)
6911//{
6912// ErrorMsg *msg = add_node_error(g, node,
6913// buf_sprintf("function called as method of '%s', but first parameter is of type '%s'",
6914// buf_ptr(&container_type->name),
6915// buf_ptr(&expected_param_type->name)));
6916// if (fn_table_entry) {
6917// add_error_note(g, msg, fn_table_entry->proto_node, buf_sprintf("function declared here"));
6918// }
6919// return g->builtin_types.entry_invalid;
6920//}
6921//
6922//// Before calling this function, set node->data.fn_call_expr.fn_table_entry if the function is known
6923//// at compile time. Otherwise this is a function pointer call.
6924//static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
6925// TypeTableEntry *expected_type, AstNode *node, TypeTableEntry *fn_type,
6926// AstNode *struct_node)
6927//{
6928// assert(node->type == NodeTypeFnCallExpr);
6929//
6930// if (fn_type->id == TypeTableEntryIdInvalid) {
6931// return fn_type;
6932// }
6933//
6934// // The function call might include inline parameters which we need to ignore according to the
6935// // fn_type.
6936// FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
6937// AstNode *generic_proto_node = fn_table_entry ?
6938// fn_table_entry->proto_node->data.fn_proto.generic_proto_node : nullptr;
6939//
6940// // count parameters
6941// size_t struct_node_1_or_0 = struct_node ? 1 : 0;
6942// size_t src_param_count = fn_type->data.fn.fn_type_id.param_count +
6943// (generic_proto_node ? generic_proto_node->data.fn_proto.inline_arg_count : 0);
6944// size_t call_param_count = node->data.fn_call_expr.params.length;
6945// size_t expect_arg_count = src_param_count - struct_node_1_or_0;
6946//
6947// bool ok_invocation = true;
6948//
6949// if (fn_type->data.fn.fn_type_id.is_var_args) {
6950// if (call_param_count < expect_arg_count) {
6951// ok_invocation = false;
6952// add_node_error(g, node,
6953// buf_sprintf("expected at least %zu arguments, found %zu", src_param_count, call_param_count));
6954// }
6955// } else if (expect_arg_count != call_param_count) {
6956// ok_invocation = false;
6957// add_node_error(g, node,
6958// buf_sprintf("expected %zu arguments, found %zu", expect_arg_count, call_param_count));
6959// }
6960//
6961// bool all_args_const_expr = true;
6962//
6963// if (struct_node) {
6964// Expr *struct_expr = get_resolved_expr(struct_node);
6965// ConstExprValue *struct_const_val = &struct_expr->const_val;
6966// if (!struct_const_val->ok) {
6967// all_args_const_expr = false;
6968// }
6969//
6970// FnTypeParamInfo *param_info = &fn_type->data.fn.fn_type_id.param_info[0];
6971// TypeTableEntry *expected_param_type = param_info->type;
6972// TypeTableEntry *container_bare_type = container_ref_type(struct_expr->type_entry);
6973// if (is_container_ref(expected_param_type)) {
6974// TypeTableEntry *param_bare_type = container_ref_type(expected_param_type);
6975// if (param_bare_type != container_bare_type) {
6976// return bad_method_call(g, node, container_bare_type, expected_param_type, fn_table_entry);
6977// }
6978// } else {
6979// return bad_method_call(g, node, container_bare_type, expected_param_type, fn_table_entry);
6980// }
6981// }
6982//
6983// // analyze each parameter. in the case of a method, we already analyzed the
6984// // first parameter in order to figure out which struct we were calling a method on.
6985// size_t next_type_i = struct_node_1_or_0;
6986// for (size_t call_i = 0; call_i < call_param_count; call_i += 1) {
6987// size_t proto_i = call_i + struct_node_1_or_0;
6988// AstNode **param_node = &node->data.fn_call_expr.params.at(call_i);
6989// // determine the expected type for each parameter
6990// TypeTableEntry *expected_param_type = nullptr;
6991// if (proto_i < src_param_count) {
6992// if (generic_proto_node &&
6993// generic_proto_node->data.fn_proto.params.at(proto_i)->data.param_decl.is_inline)
6994// {
6995// continue;
6996// }
6997//
6998// FnTypeParamInfo *param_info = &fn_type->data.fn.fn_type_id.param_info[next_type_i];
6999// next_type_i += 1;
7000//
7001// expected_param_type = param_info->type;
7002// }
7003// TypeTableEntry *param_type = analyze_expression(g, import, context, expected_param_type, *param_node);
7004// if (param_type->id == TypeTableEntryIdInvalid) {
7005// return param_type;
7006// }
7007//
7008// ConstExprValue *const_arg_val = &get_resolved_expr(*param_node)->const_val;
7009// if (!const_arg_val->ok) {
7010// all_args_const_expr = false;
7011// }
7012// }
7013//
7014// TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type;
7015//
7016// if (return_type->id == TypeTableEntryIdInvalid) {
7017// return return_type;
7018// }
7019//
7020// ConstExprValue *result_val = &get_resolved_expr(node)->const_val;
7021// if (ok_invocation && fn_table_entry && fn_table_entry->is_pure && fn_table_entry->want_pure != WantPureFalse) {
7022// if (fn_table_entry->anal_state == FnAnalStateReady) {
7023// analyze_fn_body(g, fn_table_entry);
7024// if (fn_table_entry->proto_node->data.fn_proto.skip) {
7025// return g->builtin_types.entry_invalid;
7026// }
7027// }
7028// if (all_args_const_expr) {
7029// if (fn_table_entry->is_pure && fn_table_entry->anal_state == FnAnalStateComplete) {
7030// if (eval_fn(g, node, fn_table_entry, result_val, 1000, struct_node)) {
7031// // function evaluation generated an error
7032// return g->builtin_types.entry_invalid;
7033// }
7034// return return_type;
7035// }
7036// }
7037// }
7038// if (!ok_invocation || !fn_table_entry || !fn_table_entry->is_pure || fn_table_entry->want_pure == WantPureFalse) {
7039// // calling an impure fn is impure
7040// mark_impure_fn(g, context, node);
7041// if (fn_table_entry && fn_table_entry->want_pure == WantPureTrue) {
7042// return g->builtin_types.entry_invalid;
7043// }
7044// }
7045//
7046// // TODO
7047// //if (handle_is_ptr(return_type)) {
7048// // if (context->fn_entry) {
7049// // context->fn_entry->cast_alloca_list.append(node);
7050// // } else if (!result_val->ok) {
7051// // add_node_error(g, node, buf_sprintf("unable to evaluate constant expression"));
7052// // }
7053// //}
7054//
7055// return return_type;
7056//}
7057//
7058//static TypeTableEntry *analyze_fn_call_with_inline_args(CodeGen *g, ImportTableEntry *import,
7059// BlockContext *parent_context, TypeTableEntry *expected_type, AstNode *call_node,
7060// FnTableEntry *fn_table_entry, AstNode *struct_node)
7061//{
7062// assert(call_node->type == NodeTypeFnCallExpr);
7063// assert(fn_table_entry);
7064//
7065// AstNode *decl_node = fn_table_entry->proto_node;
7066//
7067// // count parameters
7068// size_t struct_node_1_or_0 = (struct_node ? 1 : 0);
7069// size_t src_param_count = decl_node->data.fn_proto.params.length;
7070// size_t call_param_count = call_node->data.fn_call_expr.params.length;
7071//
7072// if (src_param_count != call_param_count + struct_node_1_or_0) {
7073// add_node_error(g, call_node,
7074// buf_sprintf("expected %zu arguments, found %zu", src_param_count - struct_node_1_or_0, call_param_count));
7075// return g->builtin_types.entry_invalid;
7076// }
7077//
7078// size_t inline_or_var_type_arg_count = decl_node->data.fn_proto.inline_or_var_type_arg_count;
7079// assert(inline_or_var_type_arg_count > 0);
7080//
7081// BlockContext *child_context = decl_node->owner->block_context;
7082// size_t next_generic_param_index = 0;
7083//
7084// GenericFnTypeId *generic_fn_type_id = allocate<GenericFnTypeId>(1);
7085// generic_fn_type_id->decl_node = decl_node;
7086// generic_fn_type_id->generic_param_count = inline_or_var_type_arg_count;
7087// generic_fn_type_id->generic_params = allocate<GenericParamValue>(inline_or_var_type_arg_count);
7088//
7089// size_t next_impl_i = 0;
7090// for (size_t call_i = 0; call_i < call_param_count; call_i += 1) {
7091// size_t proto_i = call_i + struct_node_1_or_0;
7092// AstNode *generic_param_decl_node = decl_node->data.fn_proto.params.at(proto_i);
7093// assert(generic_param_decl_node->type == NodeTypeParamDecl);
7094//
7095// AstNode **generic_param_type_node = &generic_param_decl_node->data.param_decl.type;
7096// TypeTableEntry *expected_param_type = analyze_type_expr(g, decl_node->owner, child_context,
7097// *generic_param_type_node);
7098// if (expected_param_type->id == TypeTableEntryIdInvalid) {
7099// return expected_param_type;
7100// }
7101//
7102// bool is_var_type = (expected_param_type->id == TypeTableEntryIdVar);
7103// bool is_inline = generic_param_decl_node->data.param_decl.is_inline;
7104// if (!is_inline && !is_var_type) {
7105// next_impl_i += 1;
7106// continue;
7107// }
7108//
7109//
7110// AstNode **param_node = &call_node->data.fn_call_expr.params.at(call_i);
7111// TypeTableEntry *param_type = analyze_expression(g, import, parent_context,
7112// is_var_type ? nullptr : expected_param_type, *param_node);
7113// if (param_type->id == TypeTableEntryIdInvalid) {
7114// return param_type;
7115// }
7116//
7117// // set child_context so that the previous param is in scope
7118// child_context = new_block_context(generic_param_decl_node, child_context);
7119//
7120// ConstExprValue *const_val = &get_resolved_expr(*param_node)->const_val;
7121// if (is_inline && !const_val->ok) {
7122// add_node_error(g, *param_node,
7123// buf_sprintf("unable to evaluate constant expression for inline parameter"));
7124//
7125// return g->builtin_types.entry_invalid;
7126// }
7127//
7128// VariableTableEntry *var = add_local_var_shadowable(g, generic_param_decl_node, decl_node->owner, child_context,
7129// generic_param_decl_node->data.param_decl.name, param_type, true, *param_node, true);
7130// // This generic function instance could be called with anything, so when this variable is read it
7131// // needs to know that it depends on compile time variable data.
7132// var->force_depends_on_compile_var = true;
7133//
7134// GenericParamValue *generic_param_value =
7135// &generic_fn_type_id->generic_params[next_generic_param_index];
7136// generic_param_value->type = param_type;
7137// generic_param_value->node = is_inline ? *param_node : nullptr;
7138// generic_param_value->impl_index = next_impl_i;
7139// next_generic_param_index += 1;
7140//
7141// if (!is_inline) {
7142// next_impl_i += 1;
7143// }
7144// }
7145//
7146// assert(next_generic_param_index == inline_or_var_type_arg_count);
7147//
7148// auto entry = g->generic_table.maybe_get(generic_fn_type_id);
7149// FnTableEntry *impl_fn;
7150// if (entry) {
7151// AstNode *impl_decl_node = entry->value;
7152// assert(impl_decl_node->type == NodeTypeFnProto);
7153// impl_fn = impl_decl_node->data.fn_proto.fn_table_entry;
7154// } else {
7155// AstNode *decl_node = generic_fn_type_id->decl_node;
7156// AstNode *impl_fn_def_node = ast_clone_subtree_special(decl_node->data.fn_proto.fn_def_node,
7157// &g->next_node_index, AstCloneSpecialOmitInlineParams);
7158// AstNode *impl_decl_node = impl_fn_def_node->data.fn_def.fn_proto;
7159// impl_decl_node->data.fn_proto.inline_arg_count = 0;
7160// impl_decl_node->data.fn_proto.inline_or_var_type_arg_count = 0;
7161// impl_decl_node->data.fn_proto.generic_proto_node = decl_node;
7162//
7163// // replace var arg types with actual types
7164// for (size_t generic_arg_i = 0; generic_arg_i < inline_or_var_type_arg_count; generic_arg_i += 1) {
7165// GenericParamValue *generic_param_value = &generic_fn_type_id->generic_params[generic_arg_i];
7166// if (!generic_param_value->node) {
7167// size_t impl_i = generic_param_value->impl_index;
7168// AstNode *impl_param_decl_node = impl_decl_node->data.fn_proto.params.at(impl_i);
7169// assert(impl_param_decl_node->type == NodeTypeParamDecl);
7170//
7171// impl_param_decl_node->data.param_decl.type = create_ast_type_node(g, import,
7172// generic_param_value->type, impl_param_decl_node);
7173// normalize_parent_ptrs(impl_param_decl_node);
7174// }
7175// }
7176//
7177// preview_fn_proto_instance(g, import, impl_decl_node, child_context);
7178// g->generic_table.put(generic_fn_type_id, impl_decl_node);
7179// impl_fn = impl_decl_node->data.fn_proto.fn_table_entry;
7180// }
7181//
7182// call_node->data.fn_call_expr.fn_entry = impl_fn;
7183// return analyze_fn_call_ptr(g, import, parent_context, expected_type, call_node,
7184// impl_fn->type_entry, struct_node);
7185//}
7186//
7187//static TypeTableEntry *analyze_generic_fn_call(CodeGen *g, ImportTableEntry *import, BlockContext *parent_context,
7188// TypeTableEntry *expected_type, AstNode *node, TypeTableEntry *generic_fn_type)
7189//{
7190// assert(node->type == NodeTypeFnCallExpr);
7191// assert(generic_fn_type->id == TypeTableEntryIdGenericFn);
7192//
7193// AstNode *decl_node = generic_fn_type->data.generic_fn.decl_node;
7194// assert(decl_node->type == NodeTypeContainerDecl);
7195// ZigList<AstNode *> *generic_params = &decl_node->data.struct_decl.generic_params;
7196//
7197// size_t expected_param_count = generic_params->length;
7198// size_t actual_param_count = node->data.fn_call_expr.params.length;
7199//
7200// if (actual_param_count != expected_param_count) {
7201// add_node_error(g, first_executing_node(node),
7202// buf_sprintf("expected %zu arguments, found %zu", expected_param_count, actual_param_count));
7203// return g->builtin_types.entry_invalid;
7204// }
7205//
7206// GenericFnTypeId *generic_fn_type_id = allocate<GenericFnTypeId>(1);
7207// generic_fn_type_id->decl_node = decl_node;
7208// generic_fn_type_id->generic_param_count = actual_param_count;
7209// generic_fn_type_id->generic_params = allocate<GenericParamValue>(actual_param_count);
7210//
7211// BlockContext *child_context = decl_node->owner->block_context;
7212// for (size_t i = 0; i < actual_param_count; i += 1) {
7213// AstNode *generic_param_decl_node = generic_params->at(i);
7214// assert(generic_param_decl_node->type == NodeTypeParamDecl);
7215//
7216// AstNode **generic_param_type_node = &generic_param_decl_node->data.param_decl.type;
7217//
7218// TypeTableEntry *expected_param_type = analyze_type_expr(g, decl_node->owner,
7219// child_context, *generic_param_type_node);
7220// if (expected_param_type->id == TypeTableEntryIdInvalid) {
7221// return expected_param_type;
7222// }
7223//
7224//
7225//
7226// AstNode **param_node = &node->data.fn_call_expr.params.at(i);
7227//
7228// TypeTableEntry *param_type = analyze_expression(g, import, parent_context, expected_param_type,
7229// *param_node);
7230// if (param_type->id == TypeTableEntryIdInvalid) {
7231// return param_type;
7232// }
7233//
7234// // set child_context so that the previous param is in scope
7235// child_context = new_block_context(generic_param_decl_node, child_context);
7236//
7237// ConstExprValue *const_val = &get_resolved_expr(*param_node)->const_val;
7238// if (const_val->ok) {
7239// VariableTableEntry *var = add_local_var(g, generic_param_decl_node, decl_node->owner, child_context,
7240// generic_param_decl_node->data.param_decl.name, param_type, true, *param_node);
7241// var->force_depends_on_compile_var = true;
7242// } else {
7243// add_node_error(g, *param_node, buf_sprintf("unable to evaluate constant expression"));
7244//
7245// return g->builtin_types.entry_invalid;
7246// }
7247//
7248// GenericParamValue *generic_param_value = &generic_fn_type_id->generic_params[i];
7249// generic_param_value->type = param_type;
7250// generic_param_value->node = *param_node;
7251// }
7252//
7253// auto entry = g->generic_table.maybe_get(generic_fn_type_id);
7254// if (entry) {
7255// AstNode *impl_decl_node = entry->value;
7256// assert(impl_decl_node->type == NodeTypeContainerDecl);
7257// TypeTableEntry *type_entry = impl_decl_node->data.struct_decl.type_entry;
7258// return resolve_expr_const_val_as_type(g, node, type_entry, false);
7259// }
7260//
7261// // make a type from the generic parameters supplied
7262// assert(decl_node->type == NodeTypeContainerDecl);
7263// AstNode *impl_decl_node = ast_clone_subtree(decl_node, &g->next_node_index);
7264// g->generic_table.put(generic_fn_type_id, impl_decl_node);
7265// scan_struct_decl(g, import, child_context, impl_decl_node);
7266// TypeTableEntry *type_entry = impl_decl_node->data.struct_decl.type_entry;
7267// resolve_struct_type(g, import, type_entry);
7268// return resolve_expr_const_val_as_type(g, node, type_entry, false);
7269//}
7270//
7271//static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
7272// TypeTableEntry *expected_type, AstNode *node)
7273//{
7274// AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
7275//
7276// if (node->data.fn_call_expr.is_builtin) {
7277// zig_panic("moved builtin fn call code to ir.cpp");
7278// }
7279//
7280// TypeTableEntry *invoke_type_entry = analyze_expression(g, import, context, nullptr, fn_ref_expr);
7281// if (invoke_type_entry->id == TypeTableEntryIdInvalid) {
7282// return g->builtin_types.entry_invalid;
7283// }
7284//
7285// // use constant expression evaluator to figure out the function at compile time.
7286// // otherwise we treat this as a function pointer.
7287// ConstExprValue *const_val = &get_resolved_expr(fn_ref_expr)->const_val;
7288//
7289// if (const_val->ok) {
7290// if (invoke_type_entry->id == TypeTableEntryIdMetaType) {
7291// zig_unreachable();
7292// } else if (invoke_type_entry->id == TypeTableEntryIdFn) {
7293// AstNode *struct_node;
7294// if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&
7295// fn_ref_expr->data.field_access_expr.is_member_fn)
7296// {
7297// struct_node = fn_ref_expr->data.field_access_expr.struct_expr;
7298// } else {
7299// struct_node = nullptr;
7300// }
7301//
7302// FnTableEntry *fn_table_entry = const_val->data.x_fn;
7303// node->data.fn_call_expr.fn_entry = fn_table_entry;
7304// return analyze_fn_call_ptr(g, import, context, expected_type, node,
7305// fn_table_entry->type_entry, struct_node);
7306// } else if (invoke_type_entry->id == TypeTableEntryIdGenericFn) {
7307// TypeTableEntry *generic_fn_type = const_val->data.x_type;
7308// AstNode *decl_node = generic_fn_type->data.generic_fn.decl_node;
7309// if (decl_node->type == NodeTypeFnProto) {
7310// AstNode *struct_node;
7311// if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&
7312// fn_ref_expr->data.field_access_expr.is_member_fn)
7313// {
7314// struct_node = fn_ref_expr->data.field_access_expr.struct_expr;
7315// } else {
7316// struct_node = nullptr;
7317// }
7318//
7319// FnTableEntry *fn_table_entry = decl_node->data.fn_proto.fn_table_entry;
7320// if (fn_table_entry->proto_node->data.fn_proto.skip) {
7321// return g->builtin_types.entry_invalid;
7322// }
7323// return analyze_fn_call_with_inline_args(g, import, context, expected_type, node,
7324// fn_table_entry, struct_node);
7325// } else {
7326// return analyze_generic_fn_call(g, import, context, expected_type, node, const_val->data.x_type);
7327// }
7328// } else {
7329// add_node_error(g, fn_ref_expr,
7330// buf_sprintf("type '%s' not a function", buf_ptr(&invoke_type_entry->name)));
7331// return g->builtin_types.entry_invalid;
7332// }
7333// }
7334//
7335// // function pointer
7336// if (invoke_type_entry->id == TypeTableEntryIdFn) {
7337// return analyze_fn_call_ptr(g, import, context, expected_type, node, invoke_type_entry, nullptr);
7338// } else {
7339// add_node_error(g, fn_ref_expr,
7340// buf_sprintf("type '%s' not a function", buf_ptr(&invoke_type_entry->name)));
7341// return g->builtin_types.entry_invalid;
7342// }
7343//}
7344//static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,7043//static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
7345// TypeTableEntry *expected_type, AstNode *node)7044// TypeTableEntry *expected_type, AstNode *node)
7346//{7045//{
...@@ -7476,68 +7175,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -7476,68 +7175,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
7476// return enum_type;7175// return enum_type;
7477//}7176//}
7478//7177//
7479//static TypeTableEntry *analyze_container_member_access_inner(CodeGen *g,
7480// TypeTableEntry *bare_struct_type, Buf *field_name, AstNode *node, TypeTableEntry *struct_type)
7481//{
7482// assert(node->type == NodeTypeFieldAccessExpr);
7483// if (!is_slice(bare_struct_type)) {
7484// BlockContext *container_block_context = get_container_block_context(bare_struct_type);
7485// assert(container_block_context);
7486// auto entry = container_block_context->decl_table.maybe_get(field_name);
7487// AstNode *fn_decl_node = entry ? entry->value : nullptr;
7488// if (fn_decl_node && fn_decl_node->type == NodeTypeFnProto) {
7489// resolve_top_level_decl(g, fn_decl_node, false);
7490// TopLevelDecl *tld = get_as_top_level_decl(fn_decl_node);
7491// if (tld->resolution == TldResolutionInvalid) {
7492// return g->builtin_types.entry_invalid;
7493// }
7494//
7495// node->data.field_access_expr.is_member_fn = true;
7496// FnTableEntry *fn_entry = fn_decl_node->data.fn_proto.fn_table_entry;
7497// if (fn_entry->type_entry->id == TypeTableEntryIdGenericFn) {
7498// return resolve_expr_const_val_as_generic_fn(g, node, fn_entry->type_entry, false);
7499// } else {
7500// return resolve_expr_const_val_as_fn(g, node, fn_entry, false);
7501// }
7502// }
7503// }
7504// add_node_error(g, node,
7505// buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&bare_struct_type->name)));
7506// return g->builtin_types.entry_invalid;
7507//}
7508//
7509//static TypeTableEntry *analyze_container_member_access(CodeGen *g,
7510// Buf *field_name, AstNode *node, TypeTableEntry *struct_type)
7511//{
7512// TypeTableEntry *bare_type = container_ref_type(struct_type);
7513// if (!type_is_complete(bare_type)) {
7514// resolve_container_type(g, bare_type);
7515// }
7516//
7517// node->data.field_access_expr.bare_container_type = bare_type;
7518//
7519// if (bare_type->id == TypeTableEntryIdStruct) {
7520// node->data.field_access_expr.type_struct_field = find_struct_type_field(bare_type, field_name);
7521// if (node->data.field_access_expr.type_struct_field) {
7522// return node->data.field_access_expr.type_struct_field->type_entry;
7523// } else {
7524// return analyze_container_member_access_inner(g, bare_type, field_name,
7525// node, struct_type);
7526// }
7527// } else if (bare_type->id == TypeTableEntryIdEnum) {
7528// node->data.field_access_expr.type_enum_field = find_enum_type_field(bare_type, field_name);
7529// if (node->data.field_access_expr.type_enum_field) {
7530// return node->data.field_access_expr.type_enum_field->type_entry;
7531// } else {
7532// return analyze_container_member_access_inner(g, bare_type, field_name,
7533// node, struct_type);
7534// }
7535// } else if (bare_type->id == TypeTableEntryIdUnion) {
7536// zig_panic("TODO");
7537// } else {
7538// zig_unreachable();
7539// }
7540//}
7541//7178//
7542//static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,7179//static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
7543// AstNode *node)7180// AstNode *node)
...@@ -7887,19 +7524,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -7887,19 +7524,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
7887// return g->builtin_types.entry_invalid;7524// return g->builtin_types.entry_invalid;
7888//}7525//}
7889//7526//
7890//static TypeTableEntry *analyze_fn_proto_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
7891// TypeTableEntry *expected_type, AstNode *node)
7892//{
7893// TypeTableEntry *type_entry = analyze_fn_proto_type(g, import, context, expected_type, node,
7894// false, false, nullptr);
7895//
7896// if (type_entry->id == TypeTableEntryIdInvalid) {
7897// return type_entry;
7898// }
7899//
7900// return resolve_expr_const_val_as_type(g, node, type_entry, false);
7901//}
7902//
7903//static void validate_voided_expr(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry) {7527//static void validate_voided_expr(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry) {
7904// if (type_entry->id == TypeTableEntryIdMetaType) {7528// if (type_entry->id == TypeTableEntryIdMetaType) {
7905// add_node_error(g, first_executing_node(source_node), buf_sprintf("expected expression, found type"));7529// add_node_error(g, first_executing_node(source_node), buf_sprintf("expected expression, found type"));
...@@ -8239,92 +7863,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -8239,92 +7863,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
8239// }7863// }
8240//}7864//}
8241//7865//
8242//static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
8243// assert(node->type == NodeTypeFnCallExpr);
8244//
8245// if (node->data.fn_call_expr.is_builtin) {
8246// return gen_builtin_fn_call_expr(g, node);
8247// }
8248//
8249// FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
8250// TypeTableEntry *struct_type = nullptr;
8251// AstNode *first_param_expr = nullptr;
8252//
8253// AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
8254// if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&
8255// fn_ref_expr->data.field_access_expr.is_member_fn)
8256// {
8257// first_param_expr = fn_ref_expr->data.field_access_expr.struct_expr;
8258// struct_type = get_expr_type(first_param_expr);
8259// }
8260//
8261// TypeTableEntry *fn_type;
8262// LLVMValueRef fn_val;
8263// AstNode *generic_proto_node;
8264// if (fn_table_entry) {
8265// fn_val = fn_table_entry->fn_value;
8266// fn_type = fn_table_entry->type_entry;
8267// generic_proto_node = fn_table_entry->proto_node->data.fn_proto.generic_proto_node;
8268// } else {
8269// fn_val = gen_expr(g, fn_ref_expr);
8270// fn_type = get_expr_type(fn_ref_expr);
8271// generic_proto_node = nullptr;
8272// }
8273//
8274// TypeTableEntry *src_return_type = fn_type->data.fn.fn_type_id.return_type;
8275//
8276// bool ret_has_bits = type_has_bits(src_return_type);
8277//
8278// size_t fn_call_param_count = node->data.fn_call_expr.params.length;
8279// bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type);
8280// size_t actual_param_count = fn_call_param_count + (struct_type ? 1 : 0) + (first_arg_ret ? 1 : 0);
8281// bool is_var_args = fn_type->data.fn.fn_type_id.is_var_args;
8282//
8283// // don't really include void values
8284// LLVMValueRef *gen_param_values = allocate<LLVMValueRef>(actual_param_count);
8285//
8286// size_t gen_param_index = 0;
8287// if (first_arg_ret) {
8288// gen_param_values[gen_param_index] = node->data.fn_call_expr.tmp_ptr;
8289// gen_param_index += 1;
8290// }
8291// if (struct_type && type_has_bits(struct_type)) {
8292// gen_param_values[gen_param_index] = gen_expr(g, first_param_expr);
8293// assert(gen_param_values[gen_param_index]);
8294// gen_param_index += 1;
8295// }
8296//
8297// for (size_t call_i = 0; call_i < fn_call_param_count; call_i += 1) {
8298// size_t proto_i = call_i + (struct_type ? 1 : 0);
8299// if (generic_proto_node &&
8300// generic_proto_node->data.fn_proto.params.at(proto_i)->data.param_decl.is_inline)
8301// {
8302// continue;
8303// }
8304// AstNode *expr_node = node->data.fn_call_expr.params.at(call_i);
8305// LLVMValueRef param_value = gen_expr(g, expr_node);
8306// assert(param_value);
8307// TypeTableEntry *param_type = get_expr_type(expr_node);
8308// if (is_var_args || type_has_bits(param_type)) {
8309// gen_param_values[gen_param_index] = param_value;
8310// gen_param_index += 1;
8311// }
8312// }
8313//
8314// LLVMValueRef result = ZigLLVMBuildCall(g->builder, fn_val,
8315// gen_param_values, gen_param_index, fn_type->data.fn.calling_convention, "");
8316//
8317// if (src_return_type->id == TypeTableEntryIdUnreachable) {
8318// return LLVMBuildUnreachable(g->builder);
8319// } else if (!ret_has_bits) {
8320// return nullptr;
8321// } else if (first_arg_ret) {
8322// return node->data.fn_call_expr.tmp_ptr;
8323// } else {
8324// return result;
8325// }
8326//}
8327//
8328//static LLVMValueRef gen_array_base_ptr(CodeGen *g, AstNode *node) {7866//static LLVMValueRef gen_array_base_ptr(CodeGen *g, AstNode *node) {
8329// TypeTableEntry *type_entry = get_expr_type(node);7867// TypeTableEntry *type_entry = get_expr_type(node);
8330//7868//
...@@ -8356,46 +7894,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -8356,46 +7894,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
8356// return gen_array_elem_ptr(g, node, array_ptr, array_type, subscript_value);7894// return gen_array_elem_ptr(g, node, array_ptr, array_type, subscript_value);
8357//}7895//}
8358//7896//
8359//static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **out_type_entry) {
8360// assert(node->type == NodeTypeFieldAccessExpr);
8361//
8362// AstNode *struct_expr_node = node->data.field_access_expr.struct_expr;
8363//
8364// *out_type_entry = node->data.field_access_expr.type_struct_field->type_entry;
8365// if (!type_has_bits(*out_type_entry)) {
8366// return nullptr;
8367// }
8368//
8369// LLVMValueRef struct_ptr;
8370// if (struct_expr_node->type == NodeTypeSymbol) {
8371// VariableTableEntry *var = get_resolved_expr(struct_expr_node)->variable;
8372// assert(var);
8373//
8374// if (var->type->id == TypeTableEntryIdPointer) {
8375// struct_ptr = LLVMBuildLoad(g->builder, var->value_ref, "");
8376// } else {
8377// struct_ptr = var->value_ref;
8378// }
8379// } else if (struct_expr_node->type == NodeTypeFieldAccessExpr) {
8380// struct_ptr = gen_field_access_expr(g, struct_expr_node, true);
8381// TypeTableEntry *field_type = get_expr_type(struct_expr_node);
8382// if (field_type->id == TypeTableEntryIdPointer) {
8383// // we have a double pointer so we must dereference it once
8384// struct_ptr = LLVMBuildLoad(g->builder, struct_ptr, "");
8385// }
8386// } else {
8387// struct_ptr = gen_expr(g, struct_expr_node);
8388// }
8389//
8390// assert(LLVMGetTypeKind(LLVMTypeOf(struct_ptr)) == LLVMPointerTypeKind);
8391// assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(struct_ptr))) == LLVMStructTypeKind);
8392//
8393// size_t gen_field_index = node->data.field_access_expr.type_struct_field->gen_index;
8394// assert(gen_field_index != SIZE_MAX);
8395//
8396// return LLVMBuildStructGEP(g->builder, struct_ptr, gen_field_index, "");
8397//}
8398//
8399//static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {7897//static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {
8400// assert(node->type == NodeTypeSliceExpr);7898// assert(node->type == NodeTypeSliceExpr);
8401//7899//
...@@ -8771,87 +8269,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -8771,87 +8269,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
8771// zig_unreachable();8269// zig_unreachable();
8772//}8270//}
8773//8271//
8774//static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMValueRef cond_value,
8775// AstNode *then_node, AstNode *else_node)
8776//{
8777// assert(then_node);
8778// assert(else_node);
8779//
8780// TypeTableEntry *then_type = get_expr_type(then_node);
8781// TypeTableEntry *else_type = get_expr_type(else_node);
8782//
8783// bool use_then_value = type_has_bits(then_type);
8784// bool use_else_value = type_has_bits(else_type);
8785//
8786// LLVMBasicBlockRef then_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Then");
8787// LLVMBasicBlockRef else_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Else");
8788//
8789// LLVMBasicBlockRef endif_block = nullptr;
8790// bool then_endif_reachable = then_type->id != TypeTableEntryIdUnreachable;
8791// bool else_endif_reachable = else_type->id != TypeTableEntryIdUnreachable;
8792// if (then_endif_reachable || else_endif_reachable) {
8793// endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf");
8794// }
8795//
8796// LLVMBuildCondBr(g->builder, cond_value, then_block, else_block);
8797//
8798// LLVMPositionBuilderAtEnd(g->builder, then_block);
8799// LLVMValueRef then_expr_result = gen_expr(g, then_node);
8800// if (then_endif_reachable) {
8801// clear_debug_source_node(g);
8802// LLVMBuildBr(g->builder, endif_block);
8803// }
8804// LLVMBasicBlockRef after_then_block = LLVMGetInsertBlock(g->builder);
8805//
8806// LLVMPositionBuilderAtEnd(g->builder, else_block);
8807// LLVMValueRef else_expr_result = gen_expr(g, else_node);
8808// if (else_endif_reachable) {
8809// clear_debug_source_node(g);
8810// LLVMBuildBr(g->builder, endif_block);
8811// }
8812// LLVMBasicBlockRef after_else_block = LLVMGetInsertBlock(g->builder);
8813//
8814// if (then_endif_reachable || else_endif_reachable) {
8815// LLVMPositionBuilderAtEnd(g->builder, endif_block);
8816// if (use_then_value && use_else_value) {
8817// LLVMValueRef phi = LLVMBuildPhi(g->builder, LLVMTypeOf(then_expr_result), "");
8818// LLVMValueRef incoming_values[2] = {then_expr_result, else_expr_result};
8819// LLVMBasicBlockRef incoming_blocks[2] = {after_then_block, after_else_block};
8820// LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2);
8821// return phi;
8822// } else if (use_then_value) {
8823// return then_expr_result;
8824// } else if (use_else_value) {
8825// return else_expr_result;
8826// }
8827// }
8828//
8829// return nullptr;
8830//}
8831//
8832//static LLVMValueRef gen_if_bool_expr(CodeGen *g, AstNode *node) {
8833// assert(node->type == NodeTypeIfBoolExpr);
8834// assert(node->data.if_bool_expr.condition);
8835// assert(node->data.if_bool_expr.then_block);
8836//
8837// ConstExprValue *const_val = &get_resolved_expr(node->data.if_bool_expr.condition)->const_val;
8838// if (const_val->ok) {
8839// if (const_val->data.x_bool) {
8840// return gen_expr(g, node->data.if_bool_expr.then_block);
8841// } else if (node->data.if_bool_expr.else_node) {
8842// return gen_expr(g, node->data.if_bool_expr.else_node);
8843// } else {
8844// return nullptr;
8845// }
8846// } else {
8847// LLVMValueRef cond_value = gen_expr(g, node->data.if_bool_expr.condition);
8848//
8849// return gen_if_bool_expr_raw(g, node, cond_value,
8850// node->data.if_bool_expr.then_block,
8851// node->data.if_bool_expr.else_node);
8852// }
8853//}
8854//
8855//static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *implicit_return_type) {8272//static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *implicit_return_type) {
8856// assert(block_node->type == NodeTypeBlock);8273// assert(block_node->type == NodeTypeBlock);
8857//8274//
...@@ -8876,140 +8293,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -8876,140 +8293,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
8876// }8293// }
8877//}8294//}
8878//8295//
8879//static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) {
8880// assert(node->type == NodeTypeContainerInitExpr);
8881//
8882// TypeTableEntry *type_entry = get_expr_type(node);
8883//
8884//
8885// if (node->data.container_init_expr.enum_type) {
8886// size_t param_count = node->data.container_init_expr.entries.length;
8887// AstNode *arg1_node;
8888// if (param_count == 1) {
8889// arg1_node = node->data.container_init_expr.entries.at(0);
8890// } else {
8891// assert(param_count == 0);
8892// arg1_node = nullptr;
8893// }
8894// return gen_enum_value_expr(g, node->data.container_init_expr.type,
8895// node->data.container_init_expr.enum_type, arg1_node);
8896// }
8897//
8898//
8899// if (type_entry->id == TypeTableEntryIdStruct) {
8900// assert(node->data.container_init_expr.kind == ContainerInitKindStruct);
8901//
8902// size_t src_field_count = type_entry->data.structure.src_field_count;
8903// assert(src_field_count == node->data.container_init_expr.entries.length);
8904//
8905// StructValExprCodeGen *struct_val_expr_node = &node->data.container_init_expr.resolved_struct_val_expr;
8906// LLVMValueRef tmp_struct_ptr = struct_val_expr_node->ptr;
8907//
8908// for (size_t i = 0; i < src_field_count; i += 1) {
8909// AstNode *field_node = node->data.container_init_expr.entries.at(i);
8910// assert(field_node->type == NodeTypeStructValueField);
8911// TypeStructField *type_struct_field = field_node->data.struct_val_field.type_struct_field;
8912// if (type_struct_field->type_entry->id == TypeTableEntryIdVoid) {
8913// continue;
8914// }
8915// assert(buf_eql_buf(type_struct_field->name, field_node->data.struct_val_field.name));
8916//
8917// set_debug_source_node(g, field_node);
8918// LLVMValueRef field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, type_struct_field->gen_index, "");
8919// AstNode *expr_node = field_node->data.struct_val_field.expr;
8920// LLVMValueRef value = gen_expr(g, expr_node);
8921// gen_assign_raw(g, field_node, BinOpTypeAssign, field_ptr, value,
8922// type_struct_field->type_entry, get_expr_type(expr_node));
8923// }
8924//
8925// return tmp_struct_ptr;
8926// } else if (type_entry->id == TypeTableEntryIdVoid) {
8927// assert(node->data.container_init_expr.entries.length == 0);
8928// return nullptr;
8929// } else if (type_entry->id == TypeTableEntryIdArray) {
8930// StructValExprCodeGen *struct_val_expr_node = &node->data.container_init_expr.resolved_struct_val_expr;
8931// LLVMValueRef tmp_array_ptr = struct_val_expr_node->ptr;
8932//
8933// size_t field_count = type_entry->data.array.len;
8934// assert(field_count == node->data.container_init_expr.entries.length);
8935//
8936// TypeTableEntry *child_type = type_entry->data.array.child_type;
8937//
8938// for (size_t i = 0; i < field_count; i += 1) {
8939// AstNode *field_node = node->data.container_init_expr.entries.at(i);
8940// LLVMValueRef elem_val = gen_expr(g, field_node);
8941//
8942// LLVMValueRef indices[] = {
8943// LLVMConstNull(g->builtin_types.entry_usize->type_ref),
8944// LLVMConstInt(g->builtin_types.entry_usize->type_ref, i, false),
8945// };
8946// set_debug_source_node(g, field_node);
8947// LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, tmp_array_ptr, indices, 2, "");
8948// gen_assign_raw(g, field_node, BinOpTypeAssign, elem_ptr, elem_val,
8949// child_type, get_expr_type(field_node));
8950// }
8951//
8952// return tmp_array_ptr;
8953// } else {
8954// zig_unreachable();
8955// }
8956//}
8957//
8958//static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) {
8959// assert(node->type == NodeTypeWhileExpr);
8960// assert(node->data.while_expr.condition);
8961// assert(node->data.while_expr.body);
8962//
8963// //AstNode *continue_expr_node = node->data.while_expr.continue_expr;
8964//
8965// bool condition_always_true = node->data.while_expr.condition_always_true;
8966// //bool contains_break = node->data.while_expr.contains_break;
8967// if (condition_always_true) {
8968// // generate a forever loop
8969// zig_panic("TODO IR");
8970//
8971// //LLVMBasicBlockRef body_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileBody");
8972// //LLVMBasicBlockRef continue_block = continue_expr_node ?
8973// // LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileContinue") : body_block;
8974// //LLVMBasicBlockRef end_block = nullptr;
8975// //if (contains_break) {
8976// // end_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "WhileEnd");
8977// //}
8978//
8979// //set_debug_source_node(g, node);
8980// //LLVMBuildBr(g->builder, body_block);
8981//
8982// //if (continue_expr_node) {
8983// // LLVMPositionBuilderAtEnd(g->builder, continue_block);
8984//
8985// // gen_expr(g, continue_expr_node);
8986//
8987// // set_debug_source_node(g, node);
8988// // LLVMBuildBr(g->builder, body_block);
8989// //}
8990//
8991// //LLVMPositionBuilderAtEnd(g->builder, body_block);
8992// //g->break_block_stack.append(end_block);
8993// //g->continue_block_stack.append(continue_block);
8994// //gen_expr(g, node->data.while_expr.body);
8995// //g->break_block_stack.pop();
8996// //g->continue_block_stack.pop();
8997//
8998// //if (get_expr_type(node->data.while_expr.body)->id != TypeTableEntryIdUnreachable) {
8999// // set_debug_source_node(g, node);
9000// // LLVMBuildBr(g->builder, continue_block);
9001// //}
9002//
9003// //if (contains_break) {
9004// // LLVMPositionBuilderAtEnd(g->builder, end_block);
9005// //}
9006// } else {
9007// zig_panic("moved to ir.cpp");
9008// }
9009//
9010// return nullptr;
9011//}
9012
9013//static LLVMValueRef gen_break(CodeGen *g, AstNode *node) {8296//static LLVMValueRef gen_break(CodeGen *g, AstNode *node) {
9014// assert(node->type == NodeTypeBreak);8297// assert(node->type == NodeTypeBreak);
9015// LLVMBasicBlockRef dest_block = g->break_block_stack.last();8298// LLVMBasicBlockRef dest_block = g->break_block_stack.last();
...@@ -9164,44 +8447,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -9164,44 +8447,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
9164// }8447// }
9165//}8448//}
9166//8449//
9167//static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node, bool is_lvalue) {
9168// assert(node->type == NodeTypeFieldAccessExpr);
9169//
9170// AstNode *struct_expr = node->data.field_access_expr.struct_expr;
9171// TypeTableEntry *struct_type = get_expr_type(struct_expr);
9172//
9173// if (struct_type->id == TypeTableEntryIdArray) {
9174// Buf *name = node->data.field_access_expr.field_name;
9175// assert(buf_eql_str(name, "len"));
9176// return LLVMConstInt(g->builtin_types.entry_usize->type_ref,
9177// struct_type->data.array.len, false);
9178// } else if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer &&
9179// struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct))
9180// {
9181// TypeTableEntry *type_entry;
9182// LLVMValueRef ptr = gen_field_ptr(g, node, &type_entry);
9183// if (is_lvalue || handle_is_ptr(type_entry)) {
9184// return ptr;
9185// } else {
9186// return LLVMBuildLoad(g->builder, ptr, "");
9187// }
9188// } else if (struct_type->id == TypeTableEntryIdMetaType) {
9189// assert(!is_lvalue);
9190// TypeTableEntry *child_type = get_type_for_type_node(struct_expr);
9191// if (child_type->id == TypeTableEntryIdEnum) {
9192// return gen_enum_value_expr(g, node, child_type, nullptr);
9193// } else {
9194// zig_unreachable();
9195// }
9196// } else if (struct_type->id == TypeTableEntryIdNamespace) {
9197// VariableTableEntry *variable = get_resolved_expr(node)->variable;
9198// assert(variable);
9199// return gen_variable(g, node, variable);
9200// } else {
9201// zig_unreachable();
9202// }
9203//}
9204//
9205//static LLVMValueRef gen_return(CodeGen *g, AstNode *source_node, LLVMValueRef value, ReturnKnowledge rk) {8450//static LLVMValueRef gen_return(CodeGen *g, AstNode *source_node, LLVMValueRef value, ReturnKnowledge rk) {
9206// BlockContext *defer_inner_block = source_node->block_context;8451// BlockContext *defer_inner_block = source_node->block_context;
9207// BlockContext *defer_outer_block = source_node->block_context->fn_entry->fn_def_node->block_context;8452// BlockContext *defer_outer_block = source_node->block_context->fn_entry->fn_def_node->block_context;
src/ir_print.cpp+109-33
...@@ -7,6 +7,8 @@ struct IrPrint {...@@ -7,6 +7,8 @@ struct IrPrint {
7 int indent_size;7 int indent_size;
8};8};
99
10static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction);
11
10static void ir_print_indent(IrPrint *irp) {12static void ir_print_indent(IrPrint *irp) {
11 for (int i = 0; i < irp->indent; i += 1) {13 for (int i = 0; i < irp->indent; i += 1) {
12 fprintf(irp->f, " ");14 fprintf(irp->f, " ");
...@@ -35,25 +37,30 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const...@@ -35,25 +37,30 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
35 break;37 break;
36 }38 }
37 switch (type_entry->id) {39 switch (type_entry->id) {
40 case TypeTableEntryIdTypeDecl:
41 return ir_print_const_value(irp, type_entry->data.type_decl.canonical_type, const_val);
38 case TypeTableEntryIdInvalid:42 case TypeTableEntryIdInvalid:
39 fprintf(irp->f, "(invalid)");43 fprintf(irp->f, "(invalid)");
40 break;44 return;
45 case TypeTableEntryIdVar:
46 fprintf(irp->f, "(var)");
47 return;
41 case TypeTableEntryIdVoid:48 case TypeTableEntryIdVoid:
42 fprintf(irp->f, "{}");49 fprintf(irp->f, "{}");
43 break;50 return;
44 case TypeTableEntryIdNumLitFloat:51 case TypeTableEntryIdNumLitFloat:
45 fprintf(irp->f, "%f", const_val->data.x_bignum.data.x_float);52 fprintf(irp->f, "%f", const_val->data.x_bignum.data.x_float);
46 break;53 return;
47 case TypeTableEntryIdNumLitInt:54 case TypeTableEntryIdNumLitInt:
48 {55 {
49 BigNum *bignum = &const_val->data.x_bignum;56 BigNum *bignum = &const_val->data.x_bignum;
50 const char *negative_str = bignum->is_negative ? "-" : "";57 const char *negative_str = bignum->is_negative ? "-" : "";
51 fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint);58 fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint);
52 break;59 return;
53 }60 }
54 case TypeTableEntryIdMetaType:61 case TypeTableEntryIdMetaType:
55 fprintf(irp->f, "%s", buf_ptr(&const_val->data.x_type->name));62 fprintf(irp->f, "%s", buf_ptr(&const_val->data.x_type->name));
56 break;63 return;
57 case TypeTableEntryIdInt:64 case TypeTableEntryIdInt:
58 {65 {
59 BigNum *bignum = &const_val->data.x_bignum;66 BigNum *bignum = &const_val->data.x_bignum;
...@@ -61,31 +68,38 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const...@@ -61,31 +68,38 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
61 const char *negative_str = bignum->is_negative ? "-" : "";68 const char *negative_str = bignum->is_negative ? "-" : "";
62 fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint);69 fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint);
63 }70 }
64 break;71 return;
72 case TypeTableEntryIdFloat:
73 {
74 BigNum *bignum = &const_val->data.x_bignum;
75 assert(bignum->kind == BigNumKindFloat);
76 fprintf(irp->f, "%f", bignum->data.x_float);
77 }
78 return;
65 case TypeTableEntryIdUnreachable:79 case TypeTableEntryIdUnreachable:
66 fprintf(irp->f, "@unreachable()");80 fprintf(irp->f, "@unreachable()");
67 break;81 return;
68 case TypeTableEntryIdBool:82 case TypeTableEntryIdBool:
69 {83 {
70 const char *value = const_val->data.x_bool ? "true" : "false";84 const char *value = const_val->data.x_bool ? "true" : "false";
71 fprintf(irp->f, "%s", value);85 fprintf(irp->f, "%s", value);
72 break;86 return;
73 }87 }
74 case TypeTableEntryIdPointer:88 case TypeTableEntryIdPointer:
75 fprintf(irp->f, "&");89 fprintf(irp->f, "&");
76 ir_print_const_value(irp, type_entry->data.pointer.child_type, const_ptr_pointee(const_val));90 ir_print_const_value(irp, type_entry->data.pointer.child_type, const_ptr_pointee(const_val));
77 break;91 return;
78 case TypeTableEntryIdFn:92 case TypeTableEntryIdFn:
79 {93 {
80 FnTableEntry *fn_entry = const_val->data.x_fn;94 FnTableEntry *fn_entry = const_val->data.x_fn;
81 fprintf(irp->f, "%s", buf_ptr(&fn_entry->symbol_name));95 fprintf(irp->f, "%s", buf_ptr(&fn_entry->symbol_name));
82 break;96 return;
83 }97 }
84 case TypeTableEntryIdBlock:98 case TypeTableEntryIdBlock:
85 {99 {
86 AstNode *node = const_val->data.x_block->node;100 AstNode *node = const_val->data.x_block->node;
87 fprintf(irp->f, "(scope:%zu:%zu)", node->line + 1, node->column + 1);101 fprintf(irp->f, "(scope:%zu:%zu)", node->line + 1, node->column + 1);
88 break;102 return;
89 }103 }
90 case TypeTableEntryIdArray:104 case TypeTableEntryIdArray:
91 {105 {
...@@ -99,12 +113,17 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const...@@ -99,12 +113,17 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
99 ir_print_const_value(irp, child_type, child_value);113 ir_print_const_value(irp, child_type, child_value);
100 }114 }
101 fprintf(irp->f, "}");115 fprintf(irp->f, "}");
102 break;116 return;
103 }117 }
104 case TypeTableEntryIdNullLit:118 case TypeTableEntryIdNullLit:
105 {119 {
106 fprintf(irp->f, "null");120 fprintf(irp->f, "null");
107 break;121 return;
122 }
123 case TypeTableEntryIdUndefLit:
124 {
125 fprintf(irp->f, "undefined");
126 return;
108 }127 }
109 case TypeTableEntryIdMaybe:128 case TypeTableEntryIdMaybe:
110 {129 {
...@@ -113,26 +132,56 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const...@@ -113,26 +132,56 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
113 } else {132 } else {
114 fprintf(irp->f, "null");133 fprintf(irp->f, "null");
115 }134 }
116 break;135 return;
117 }136 }
118 case TypeTableEntryIdNamespace:137 case TypeTableEntryIdNamespace:
119 {138 {
120 ImportTableEntry *import = const_val->data.x_import;139 ImportTableEntry *import = const_val->data.x_import;
121 fprintf(irp->f, "(namespace: %s)", buf_ptr(import->path));140 fprintf(irp->f, "(namespace: %s)", buf_ptr(import->path));
122 break;141 return;
142 }
143 case TypeTableEntryIdGenericFn:
144 {
145 TypeTableEntry *type_entry = const_val->data.x_type;
146 AstNode *decl_node = type_entry->data.generic_fn.decl_node;
147 assert(decl_node->type == NodeTypeFnProto);
148 fprintf(irp->f, "%s", buf_ptr(decl_node->data.fn_proto.name));
149 return;
150 }
151 case TypeTableEntryIdBoundFn:
152 {
153 FnTableEntry *fn_entry = const_val->data.x_bound_fn.fn;
154 fprintf(irp->f, "bound %s to ", buf_ptr(&fn_entry->symbol_name));
155 ir_print_other_instruction(irp, const_val->data.x_bound_fn.first_arg);
156 return;
123 }157 }
124 case TypeTableEntryIdVar:
125 case TypeTableEntryIdFloat:
126 case TypeTableEntryIdStruct:158 case TypeTableEntryIdStruct:
127 case TypeTableEntryIdUndefLit:159 {
128 case TypeTableEntryIdErrorUnion:160 fprintf(irp->f, "(struct %s constant)", buf_ptr(&type_entry->name));
129 case TypeTableEntryIdPureError:161 return;
162 }
130 case TypeTableEntryIdEnum:163 case TypeTableEntryIdEnum:
164 {
165 fprintf(irp->f, "(enum %s constant)", buf_ptr(&type_entry->name));
166 return;
167 }
168 case TypeTableEntryIdErrorUnion:
169 {
170 fprintf(irp->f, "(error union %s constant)", buf_ptr(&type_entry->name));
171 return;
172 }
131 case TypeTableEntryIdUnion:173 case TypeTableEntryIdUnion:
132 case TypeTableEntryIdTypeDecl:174 {
133 case TypeTableEntryIdGenericFn:175 fprintf(irp->f, "(union %s constant)", buf_ptr(&type_entry->name));
134 zig_panic("TODO render more constant types in IR printer");176 return;
177 }
178 case TypeTableEntryIdPureError:
179 {
180 fprintf(irp->f, "(pure error constant)");
181 return;
182 }
135 }183 }
184 zig_unreachable();
136}185}
137186
138static void ir_print_const_instruction(IrPrint *irp, IrInstruction *instruction) {187static void ir_print_const_instruction(IrPrint *irp, IrInstruction *instruction) {
...@@ -285,12 +334,16 @@ static void ir_print_decl_var(IrPrint *irp, IrInstructionDeclVar *decl_var_instr...@@ -285,12 +334,16 @@ static void ir_print_decl_var(IrPrint *irp, IrInstructionDeclVar *decl_var_instr
285static void ir_print_cast(IrPrint *irp, IrInstructionCast *cast_instruction) {334static void ir_print_cast(IrPrint *irp, IrInstructionCast *cast_instruction) {
286 fprintf(irp->f, "cast ");335 fprintf(irp->f, "cast ");
287 ir_print_other_instruction(irp, cast_instruction->value);336 ir_print_other_instruction(irp, cast_instruction->value);
288 fprintf(irp->f, " to ");337 fprintf(irp->f, " to %s", buf_ptr(&cast_instruction->dest_type->name));
289 ir_print_other_instruction(irp, cast_instruction->dest_type);
290}338}
291339
292static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {340static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {
293 ir_print_other_instruction(irp, call_instruction->fn);341 if (call_instruction->fn_entry) {
342 fprintf(irp->f, "%s", buf_ptr(&call_instruction->fn_entry->symbol_name));
343 } else {
344 assert(call_instruction->fn_ref);
345 ir_print_other_instruction(irp, call_instruction->fn_ref);
346 }
294 fprintf(irp->f, "(");347 fprintf(irp->f, "(");
295 for (size_t i = 0; i < call_instruction->arg_count; i += 1) {348 for (size_t i = 0; i < call_instruction->arg_count; i += 1) {
296 IrInstruction *arg = call_instruction->args[i];349 IrInstruction *arg = call_instruction->args[i];
...@@ -347,13 +400,24 @@ static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerI...@@ -347,13 +400,24 @@ static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerI
347 ir_print_other_instruction(irp, instruction->container_type);400 ir_print_other_instruction(irp, instruction->container_type);
348 fprintf(irp->f, "{");401 fprintf(irp->f, "{");
349 for (size_t i = 0; i < instruction->field_count; i += 1) {402 for (size_t i = 0; i < instruction->field_count; i += 1) {
350 Buf *name = instruction->field_names[i];403 IrInstructionContainerInitFieldsField *field = &instruction->fields[i];
351 IrInstruction *field_value = instruction->field_values[i];
352 const char *comma = (i == 0) ? "" : ", ";404 const char *comma = (i == 0) ? "" : ", ";
353 fprintf(irp->f, "%s.%s = ", comma, buf_ptr(name));405 fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field->name));
354 ir_print_other_instruction(irp, field_value);406 ir_print_other_instruction(irp, field->value);
355 }407 }
356 fprintf(irp->f, "}");408 fprintf(irp->f, "} // container init");
409}
410
411static void ir_print_struct_init(IrPrint *irp, IrInstructionStructInit *instruction) {
412 fprintf(irp->f, "%s {", buf_ptr(&instruction->struct_type->name));
413 for (size_t i = 0; i < instruction->field_count; i += 1) {
414 IrInstructionStructInitField *field = &instruction->fields[i];
415 Buf *field_name = field->type_struct_field->name;
416 const char *comma = (i == 0) ? "" : ", ";
417 fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field_name));
418 ir_print_other_instruction(irp, field->value);
419 }
420 fprintf(irp->f, "} // struct init");
357}421}
358422
359static void ir_print_unreachable(IrPrint *irp, IrInstructionUnreachable *instruction) {423static void ir_print_unreachable(IrPrint *irp, IrInstructionUnreachable *instruction) {
...@@ -406,10 +470,9 @@ static void ir_print_ptr_type_child(IrPrint *irp, IrInstructionPtrTypeChild *ins...@@ -406,10 +470,9 @@ static void ir_print_ptr_type_child(IrPrint *irp, IrInstructionPtrTypeChild *ins
406}470}
407471
408static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction) {472static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction) {
409 fprintf(irp->f, "@FieldPtr(&");473 fprintf(irp->f, "fieldptr ");
410 ir_print_other_instruction(irp, instruction->container_ptr);474 ir_print_other_instruction(irp, instruction->container_ptr);
411 fprintf(irp->f, ".%s", buf_ptr(instruction->field_name));475 fprintf(irp->f, ".%s", buf_ptr(instruction->field_name));
412 fprintf(irp->f, ")");
413}476}
414477
415static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr *instruction) {478static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr *instruction) {
...@@ -419,6 +482,13 @@ static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr...@@ -419,6 +482,13 @@ static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr
419 fprintf(irp->f, ")");482 fprintf(irp->f, ")");
420}483}
421484
485static void ir_print_enum_field_ptr(IrPrint *irp, IrInstructionEnumFieldPtr *instruction) {
486 fprintf(irp->f, "@EnumFieldPtr(&");
487 ir_print_other_instruction(irp, instruction->enum_ptr);
488 fprintf(irp->f, ".%s", buf_ptr(instruction->field->name));
489 fprintf(irp->f, ")");
490}
491
422static void ir_print_set_fn_test(IrPrint *irp, IrInstructionSetFnTest *instruction) {492static void ir_print_set_fn_test(IrPrint *irp, IrInstructionSetFnTest *instruction) {
423 fprintf(irp->f, "@setFnTest(");493 fprintf(irp->f, "@setFnTest(");
424 ir_print_other_instruction(irp, instruction->fn_value);494 ir_print_other_instruction(irp, instruction->fn_value);
...@@ -632,6 +702,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -632,6 +702,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
632 case IrInstructionIdContainerInitFields:702 case IrInstructionIdContainerInitFields:
633 ir_print_container_init_fields(irp, (IrInstructionContainerInitFields *)instruction);703 ir_print_container_init_fields(irp, (IrInstructionContainerInitFields *)instruction);
634 break;704 break;
705 case IrInstructionIdStructInit:
706 ir_print_struct_init(irp, (IrInstructionStructInit *)instruction);
707 break;
635 case IrInstructionIdUnreachable:708 case IrInstructionIdUnreachable:
636 ir_print_unreachable(irp, (IrInstructionUnreachable *)instruction);709 ir_print_unreachable(irp, (IrInstructionUnreachable *)instruction);
637 break;710 break;
...@@ -662,6 +735,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -662,6 +735,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
662 case IrInstructionIdStructFieldPtr:735 case IrInstructionIdStructFieldPtr:
663 ir_print_struct_field_ptr(irp, (IrInstructionStructFieldPtr *)instruction);736 ir_print_struct_field_ptr(irp, (IrInstructionStructFieldPtr *)instruction);
664 break;737 break;
738 case IrInstructionIdEnumFieldPtr:
739 ir_print_enum_field_ptr(irp, (IrInstructionEnumFieldPtr *)instruction);
740 break;
665 case IrInstructionIdSetFnTest:741 case IrInstructionIdSetFnTest:
666 ir_print_set_fn_test(irp, (IrInstructionSetFnTest *)instruction);742 ir_print_set_fn_test(irp, (IrInstructionSetFnTest *)instruction);
667 break;743 break;
test/self_hosted2.zig+13
...@@ -84,6 +84,18 @@ end:...@@ -84,6 +84,18 @@ end:
84}84}
85var goto_counter: i32 = 0;85var goto_counter: i32 = 0;
8686
87
88
89struct FooA {
90 fn add(a: i32, b: i32) -> i32 { a + b }
91}
92const foo_a = FooA {};
93
94fn testStructStatic() {
95 const result = FooA.add(3, 4);
96 assert(result == 7);
97}
98
87fn assert(ok: bool) {99fn assert(ok: bool) {
88 if (!ok)100 if (!ok)
89 @unreachable();101 @unreachable();
...@@ -98,6 +110,7 @@ fn runAllTests() {...@@ -98,6 +110,7 @@ fn runAllTests() {
98 testInlineSwitch();110 testInlineSwitch();
99 testNamespaceFnCall();111 testNamespaceFnCall();
100 gotoAndLabels();112 gotoAndLabels();
113 testStructStatic();
101}114}
102115
103export nakedcc fn _start() -> unreachable {116export nakedcc fn _start() -> unreachable {