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 {
4141 bool invalid;
4242 ZigList<LabelTableEntry *> all_labels;
4343 ZigList<AstNode *> goto_list;
44 bool is_inline;
4445};
4546
4647enum OutType {
......@@ -82,6 +83,11 @@ struct ConstErrValue {
8283 ConstExprValue *payload;
8384};
8485
86struct ConstBoundFnValue {
87 FnTableEntry *fn;
88 IrInstruction *first_arg;
89};
90
8591enum ConstValSpecial {
8692 ConstValSpecialRuntime,
8793 ConstValSpecialStatic,
......@@ -100,6 +106,7 @@ struct ConstExprValue {
100106 BigNum x_bignum;
101107 bool x_bool;
102108 FnTableEntry *x_fn;
109 ConstBoundFnValue x_bound_fn;
103110 TypeTableEntry *x_type;
104111 ConstExprValue *x_maybe;
105112 ConstErrValue x_err;
......@@ -494,6 +501,7 @@ struct AstNodeIfBoolExpr {
494501 AstNode *condition;
495502 AstNode *then_block;
496503 AstNode *else_node; // null, block node, or other if expr node
504 bool is_inline; // TODO
497505
498506 // populated by semantic analyzer
499507};
......@@ -503,6 +511,7 @@ struct AstNodeIfVarExpr {
503511 AstNode *then_block;
504512 AstNode *else_node; // null, block node, or other if expr node
505513 bool var_is_ptr;
514 bool is_inline; // TODO
506515
507516 // populated by semantic analyzer
508517 TypeTableEntry *type;
......@@ -941,12 +950,18 @@ struct TypeTableEntryFn {
941950
942951 LLVMTypeRef raw_type_ref;
943952 LLVMCallConv calling_convention;
953
954 TypeTableEntry *bound_fn_parent;
944955};
945956
946957struct TypeTableEntryGenericFn {
947958 AstNode *decl_node;
948959};
949960
961struct TypeTableEntryBoundFn {
962 TypeTableEntry *fn_type;
963};
964
950965struct TypeTableEntryTypeDecl {
951966 TypeTableEntry *child_type;
952967 TypeTableEntry *canonical_type;
......@@ -978,6 +993,7 @@ enum TypeTableEntryId {
978993 TypeTableEntryIdNamespace,
979994 TypeTableEntryIdBlock,
980995 TypeTableEntryIdGenericFn,
996 TypeTableEntryIdBoundFn,
981997};
982998
983999struct TypeTableEntry {
......@@ -988,7 +1004,6 @@ struct TypeTableEntry {
9881004 ZigLLVMDIType *di_type;
9891005
9901006 bool zero_bits;
991 bool deep_const;
9921007
9931008 union {
9941009 TypeTableEntryPointer pointer;
......@@ -1003,6 +1018,7 @@ struct TypeTableEntry {
10031018 TypeTableEntryFn fn;
10041019 TypeTableEntryTypeDecl type_decl;
10051020 TypeTableEntryGenericFn generic_fn;
1021 TypeTableEntryBoundFn bound_fn;
10061022 } data;
10071023
10081024 // use these fields to make sure we don't duplicate type table entries for the same type
......@@ -1043,12 +1059,6 @@ enum FnAnalState {
10431059};
10441060
10451061
1046enum WantPure {
1047 WantPureAuto,
1048 WantPureFalse,
1049 WantPureTrue,
1050};
1051
10521062enum FnInline {
10531063 FnInlineAuto,
10541064 FnInlineAlways,
......@@ -1067,10 +1077,6 @@ struct FnTableEntry {
10671077 bool internal_linkage;
10681078 bool is_extern;
10691079 bool is_test;
1070 bool is_pure;
1071 WantPure want_pure;
1072 AstNode *want_pure_attr_node;
1073 AstNode *want_pure_return_type;
10741080 FnInline fn_inline;
10751081 FnAnalState anal_state;
10761082 IrExecutable ir_executable;
......@@ -1085,6 +1091,9 @@ struct FnTableEntry {
10851091 ZigList<VariableTableEntry *> variable_list;
10861092};
10871093
1094uint32_t fn_table_entry_hash(FnTableEntry*);
1095bool fn_table_entry_eql(FnTableEntry *a, FnTableEntry *b);
1096
10881097enum BuiltinFnId {
10891098 BuiltinFnIdInvalid,
10901099 BuiltinFnIdMemcpy,
......@@ -1122,7 +1131,6 @@ enum BuiltinFnId {
11221131 BuiltinFnIdUnreachable,
11231132 BuiltinFnIdSetFnTest,
11241133 BuiltinFnIdSetFnVisible,
1125 BuiltinFnIdSetFnStaticEval,
11261134 BuiltinFnIdSetFnNoInline,
11271135 BuiltinFnIdSetDebugSafety,
11281136};
......@@ -1385,6 +1393,7 @@ enum IrInstructionId {
13851393 IrInstructionIdStorePtr,
13861394 IrInstructionIdFieldPtr,
13871395 IrInstructionIdStructFieldPtr,
1396 IrInstructionIdEnumFieldPtr,
13881397 IrInstructionIdElemPtr,
13891398 IrInstructionIdVarPtr,
13901399 IrInstructionIdCall,
......@@ -1393,6 +1402,7 @@ enum IrInstructionId {
13931402 IrInstructionIdCast,
13941403 IrInstructionIdContainerInitList,
13951404 IrInstructionIdContainerInitFields,
1405 IrInstructionIdStructInit,
13961406 IrInstructionIdUnreachable,
13971407 IrInstructionIdTypeOf,
13981408 IrInstructionIdToPtrType,
......@@ -1578,6 +1588,14 @@ struct IrInstructionStructFieldPtr {
15781588 bool is_const;
15791589};
15801590
1591struct IrInstructionEnumFieldPtr {
1592 IrInstruction base;
1593
1594 IrInstruction *enum_ptr;
1595 TypeEnumField *field;
1596 bool is_const;
1597};
1598
15811599struct IrInstructionElemPtr {
15821600 IrInstruction base;
15831601
......@@ -1597,9 +1615,12 @@ struct IrInstructionVarPtr {
15971615struct IrInstructionCall {
15981616 IrInstruction base;
15991617
1600 IrInstruction *fn;
1618 IrInstruction *fn_ref;
1619 FnTableEntry *fn_entry;
16011620 size_t arg_count;
16021621 IrInstruction **args;
1622 bool is_inline;
1623 LLVMValueRef tmp_ptr;
16031624};
16041625
16051626struct IrInstructionConst {
......@@ -1615,11 +1636,12 @@ struct IrInstructionReturn {
16151636 IrInstruction *value;
16161637};
16171638
1639// TODO get rid of this instruction, replace with instructions for each op code
16181640struct IrInstructionCast {
16191641 IrInstruction base;
16201642
16211643 IrInstruction *value;
1622 IrInstruction *dest_type;
1644 TypeTableEntry *dest_type;
16231645 CastOp cast_op;
16241646 LLVMValueRef tmp_ptr;
16251647};
......@@ -1630,6 +1652,14 @@ struct IrInstructionContainerInitList {
16301652 IrInstruction *container_type;
16311653 size_t item_count;
16321654 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;
16331663};
16341664
16351665struct IrInstructionContainerInitFields {
......@@ -1637,8 +1667,21 @@ struct IrInstructionContainerInitFields {
16371667
16381668 IrInstruction *container_type;
16391669 size_t field_count;
1640 Buf **field_names;
1641 IrInstruction **field_values;
1670 IrInstructionContainerInitFieldsField *fields;
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;
16421685};
16431686
16441687struct IrInstructionUnreachable {
......@@ -1790,4 +1833,7 @@ static const size_t slice_len_index = 1;
17901833static const size_t maybe_child_index = 0;
17911834static 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
17931839#endif
src/analyze.cpp+39-72
......@@ -84,46 +84,11 @@ AstNode *first_executing_node(AstNode *node) {
8484 zig_unreachable();
8585}
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
11487ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
11588 // if this assert fails, then parseh generated code that
11689 // failed semantic analysis, which isn't supposed to happen
11790 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
12792 ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column,
12893 node->owner->source_code, node->owner->line_offsets, msg);
12994
......@@ -217,6 +182,7 @@ bool type_is_complete(TypeTableEntry *type_entry) {
217182 case TypeTableEntryIdNamespace:
218183 case TypeTableEntryIdBlock:
219184 case TypeTableEntryIdGenericFn:
185 case TypeTableEntryIdBoundFn:
220186 return true;
221187 }
222188 zig_unreachable();
......@@ -241,7 +207,6 @@ TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
241207static TypeTableEntry *get_generic_fn_type(CodeGen *g, AstNode *decl_node) {
242208 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdGenericFn);
243209 buf_init_from_str(&entry->name, "(generic function)");
244 entry->deep_const = true;
245210 entry->zero_bits = true;
246211 entry->data.generic_fn.decl_node = decl_node;
247212 return entry;
......@@ -255,8 +220,6 @@ TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool
255220 } else {
256221 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer);
257222
258 entry->deep_const = is_const && child_type->deep_const;
259
260223 const char *const_str = is_const ? "const " : "";
261224 buf_resize(&entry->name, 0);
262225 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) {
298261 assert(child_type->type_ref);
299262 assert(child_type->di_type);
300263
301 entry->deep_const = child_type->deep_const;
302
303264 buf_resize(&entry->name, 0);
304265 buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name));
305266
......@@ -383,8 +344,6 @@ TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
383344
384345 entry->data.error.child_type = child_type;
385346
386 entry->deep_const = child_type->deep_const;
387
388347 if (!type_has_bits(child_type)) {
389348 entry->type_ref = g->err_tag_type->type_ref;
390349 entry->di_type = g->err_tag_type->di_type;
......@@ -456,7 +415,6 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
456415 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray);
457416 entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref, array_size) : nullptr;
458417 entry->zero_bits = (array_size == 0) || child_type->zero_bits;
459 entry->deep_const = child_type->deep_const;
460418
461419 buf_resize(&entry->name, 0);
462420 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
507465 TypeTableEntry *var_peer = get_slice_type(g, child_type, false);
508466 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct);
509467
510 entry->deep_const = child_type->deep_const;
511
512468 buf_resize(&entry->name, 0);
513469 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 *
657613
658614 buf_init_from_str(&entry->name, name);
659615
660 entry->deep_const = child_type->deep_const;
661616 entry->type_ref = child_type->type_ref;
662617 entry->di_type = child_type->di_type;
663618 entry->zero_bits = child_type->zero_bits;
......@@ -673,6 +628,23 @@ TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *
673628 return entry;
674629}
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
676648// accepts ownership of fn_type_id memory
677649TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id, bool gen_debug_info) {
678650 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
681653 }
682654
683655 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn);
684 fn_type->deep_const = true;
685656 fn_type->data.fn.fn_type_id = *fn_type_id;
686657
687658 if (fn_type_id->is_cold) {
......@@ -838,6 +809,7 @@ static IrInstruction *analyze_const_value(CodeGen *g, BlockContext *scope, AstNo
838809 TypeTableEntry *expected_type)
839810{
840811 IrExecutable ir_executable = {0};
812 ir_executable.is_inline = true;
841813 ir_gen(g, node, scope, &ir_executable);
842814
843815 if (ir_executable.invalid)
......@@ -851,6 +823,7 @@ static IrInstruction *analyze_const_value(CodeGen *g, BlockContext *scope, AstNo
851823 fprintf(stderr, "}\n");
852824 }
853825 IrExecutable analyzed_executable = {0};
826 analyzed_executable.is_inline = true;
854827 analyzed_executable.backward_branch_quota = default_backward_branch_quota;
855828 TypeTableEntry *result_type = ir_analyze(g, &ir_executable, &analyzed_executable, expected_type, node);
856829 if (result_type->id == TypeTableEntryIdInvalid)
......@@ -884,8 +857,7 @@ static TypeTableEntry *analyze_type_expr(CodeGen *g, ImportTableEntry *import, B
884857
885858static bool fn_wants_full_static_eval(FnTableEntry *fn_table_entry) {
886859 assert(fn_table_entry);
887 AstNodeFnProto *fn_proto = &fn_table_entry->proto_node->data.fn_proto;
888 return fn_proto->inline_arg_count == fn_proto->params.length && fn_table_entry->want_pure == WantPureTrue;
860 return false;
889861}
890862
891863// 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
931903 case TypeTableEntryIdNamespace:
932904 case TypeTableEntryIdBlock:
933905 case TypeTableEntryIdGenericFn:
906 case TypeTableEntryIdBoundFn:
934907 if (!fn_proto->skip) {
935908 fn_proto->skip = true;
936909 add_node_error(g, child->data.param_decl.type,
......@@ -991,6 +964,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
991964 case TypeTableEntryIdNamespace:
992965 case TypeTableEntryIdBlock:
993966 case TypeTableEntryIdGenericFn:
967 case TypeTableEntryIdBoundFn:
994968 case TypeTableEntryIdVar:
995969 if (!fn_proto->skip) {
996970 fn_proto->skip = true;
......@@ -1023,9 +997,6 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
1023997 }
1024998
1025999 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
10291000 ErrorMsg *err_msg = nullptr;
10301001 for (size_t i = 0; i < fn_proto->params.length; i += 1) {
10311002 AstNode *param_decl_node = fn_proto->params.at(i);
......@@ -1046,8 +1017,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
10461017 }
10471018 }
10481019
1049
1050 bool gen_debug_info = !(fn_table_entry && fn_wants_full_static_eval(fn_table_entry));
1020 bool gen_debug_info = fn_table_entry && !fn_wants_full_static_eval(fn_table_entry);
10511021 return get_fn_type(g, &fn_type_id, gen_debug_info);
10521022}
10531023
......@@ -1167,8 +1137,6 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
11671137 assert(decl_node->type == NodeTypeContainerDecl);
11681138 assert(enum_type->di_type);
11691139
1170 enum_type->deep_const = true;
1171
11721140 uint32_t field_count = decl_node->data.struct_decl.fields.length;
11731141
11741142 enum_type->data.enumeration.src_field_count = field_count;
......@@ -1198,11 +1166,6 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
11981166 type_enum_field->type_entry = field_type;
11991167 type_enum_field->value = i;
12001168
1201 if (!field_type->deep_const) {
1202 enum_type->deep_const = false;
1203 }
1204
1205
12061169 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);
12071170
12081171 if (field_type->id == TypeTableEntryIdStruct) {
......@@ -1362,8 +1325,6 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
13621325 assert(decl_node->type == NodeTypeContainerDecl);
13631326 assert(struct_type->di_type);
13641327
1365 struct_type->deep_const = true;
1366
13671328 size_t field_count = decl_node->data.struct_decl.fields.length;
13681329
13691330 struct_type->data.structure.src_field_count = field_count;
......@@ -1389,10 +1350,6 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
13891350 type_struct_field->src_index = i;
13901351 type_struct_field->gen_index = SIZE_MAX;
13911352
1392 if (!field_type->deep_const) {
1393 struct_type->deep_const = false;
1394 }
1395
13961353 if (field_type->id == TypeTableEntryIdStruct) {
13971354 resolve_struct_type(g, import, field_type);
13981355 } else if (field_type->id == TypeTableEntryIdEnum) {
......@@ -1537,7 +1494,6 @@ static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstN
15371494 fn_table_entry->proto_node = proto_node;
15381495 fn_table_entry->fn_def_node = fn_def_node;
15391496 fn_table_entry->is_extern = is_extern;
1540 fn_table_entry->is_pure = fn_def_node != nullptr;
15411497
15421498 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
18521808 case TypeTableEntryIdUnion:
18531809 case TypeTableEntryIdFn:
18541810 case TypeTableEntryIdGenericFn:
1811 case TypeTableEntryIdBoundFn:
18551812 return type_entry;
18561813 }
18571814 zig_unreachable();
......@@ -2100,6 +2057,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {
21002057 case TypeTableEntryIdNamespace:
21012058 case TypeTableEntryIdBlock:
21022059 case TypeTableEntryIdGenericFn:
2060 case TypeTableEntryIdBoundFn:
21032061 return false;
21042062
21052063 case TypeTableEntryIdBool:
......@@ -2314,6 +2272,7 @@ static bool is_container(TypeTableEntry *type_entry) {
23142272 case TypeTableEntryIdNamespace:
23152273 case TypeTableEntryIdBlock:
23162274 case TypeTableEntryIdGenericFn:
2275 case TypeTableEntryIdBoundFn:
23172276 return false;
23182277 }
23192278 zig_unreachable();
......@@ -2361,6 +2320,7 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
23612320 case TypeTableEntryIdNamespace:
23622321 case TypeTableEntryIdBlock:
23632322 case TypeTableEntryIdGenericFn:
2323 case TypeTableEntryIdBoundFn:
23642324 case TypeTableEntryIdInvalid:
23652325 case TypeTableEntryIdVar:
23662326 zig_unreachable();
......@@ -2429,10 +2389,6 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
24292389 if (fn_type->data.fn.gen_param_info) {
24302390 var->gen_arg_index = fn_type->data.fn.gen_param_info[i].gen_index;
24312391 }
2432
2433 if (!type->deep_const) {
2434 fn_table_entry->is_pure = false;
2435 }
24362392 }
24372393
24382394 TypeTableEntry *expected_type = fn_type->data.fn.fn_type_id.return_type;
......@@ -2768,6 +2724,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
27682724 case TypeTableEntryIdNamespace:
27692725 case TypeTableEntryIdBlock:
27702726 case TypeTableEntryIdGenericFn:
2727 case TypeTableEntryIdBoundFn:
27712728 case TypeTableEntryIdVar:
27722729 zig_unreachable();
27732730 case TypeTableEntryIdUnreachable:
......@@ -2820,6 +2777,14 @@ static uint32_t hash_size(size_t x) {
28202777 return x % UINT32_MAX;
28212778}
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
28232788uint32_t fn_type_id_hash(FnTypeId *id) {
28242789 uint32_t result = 0;
28252790 result += id->is_extern ? 3349388391 : 0;
......@@ -2912,6 +2877,7 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)
29122877 case TypeTableEntryIdBlock:
29132878 return hash_ptr(const_val->data.x_block);
29142879 case TypeTableEntryIdGenericFn:
2880 case TypeTableEntryIdBoundFn:
29152881 case TypeTableEntryIdInvalid:
29162882 case TypeTableEntryIdUnreachable:
29172883 case TypeTableEntryIdVar:
......@@ -2990,6 +2956,7 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)
29902956 case TypeTableEntryIdNamespace:
29912957 case TypeTableEntryIdBlock:
29922958 case TypeTableEntryIdGenericFn:
2959 case TypeTableEntryIdBoundFn:
29932960 case TypeTableEntryIdVar:
29942961 zig_unreachable();
29952962 case TypeTableEntryIdArray:
src/analyze.hpp+1-1
......@@ -31,6 +31,7 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import,
3131 ContainerKind kind, AstNode *decl_node, const char *name);
3232TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);
3333TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type);
34TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry);
3435bool handle_is_ptr(TypeTableEntry *type_entry);
3536void find_libc_include_path(CodeGen *g);
3637void find_libc_lib_path(CodeGen *g);
......@@ -52,7 +53,6 @@ VariableTableEntry *find_variable(CodeGen *g, BlockContext *orig_context, Buf *n
5253AstNode *find_decl(BlockContext *context, Buf *name);
5354void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only);
5455TopLevelDecl *get_as_top_level_decl(AstNode *node);
55void mark_impure_fn(CodeGen *g, BlockContext *context, AstNode *node);
5656bool type_is_codegen_pointer(TypeTableEntry *type);
5757TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);
5858TypeTableEntry *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
13681368}
13691369
13701370static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {
1371 LLVMValueRef fn_val = ir_llvm_value(g, instruction->fn);
1372 TypeTableEntry *fn_type = instruction->fn->type_entry;
1371 LLVMValueRef fn_val;
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
13731382 TypeTableEntry *src_return_type = fn_type->data.fn.fn_type_id.return_type;
13741383 bool ret_has_bits = type_has_bits(src_return_type);
1375 size_t fn_call_param_count = instruction->arg_count;
13761384 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);
13781386 bool is_var_args = fn_type->data.fn.fn_type_id.is_var_args;
13791387 LLVMValueRef *gen_param_values = allocate<LLVMValueRef>(actual_param_count);
13801388 size_t gen_param_index = 0;
13811389 if (first_arg_ret) {
1382 zig_panic("TODO");
1383 //gen_param_values[gen_param_index] = node->data.fn_call_expr.tmp_ptr;
1384 //gen_param_index += 1;
1390 gen_param_values[gen_param_index] = instruction->tmp_ptr;
1391 gen_param_index += 1;
13851392 }
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) {
13871394 IrInstruction *param_instruction = instruction->args[call_i];
1388 LLVMValueRef param_value = ir_llvm_value(g, param_instruction);
1389 assert(param_value);
13901395 TypeTableEntry *param_type = param_instruction->type_entry;
13911396 if (is_var_args || type_has_bits(param_type)) {
1397 LLVMValueRef param_value = ir_llvm_value(g, param_instruction);
1398 assert(param_value);
13921399 gen_param_values[gen_param_index] = param_value;
13931400 gen_param_index += 1;
13941401 }
......@@ -1402,8 +1409,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
14021409 } else if (!ret_has_bits) {
14031410 return nullptr;
14041411 } else if (first_arg_ret) {
1405 zig_panic("TODO");
1406 //return node->data.fn_call_expr.tmp_ptr;
1412 return instruction->tmp_ptr;
14071413 } else {
14081414 return result;
14091415 }
......@@ -1422,6 +1428,22 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executa
14221428 return LLVMBuildStructGEP(g->builder, struct_ptr, field->gen_index, "");
14231429}
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
14251447static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok) {
14261448 const char *ptr = buf_ptr(node->data.asm_expr.asm_template) + tok->start + 2;
14271449 size_t len = tok->end - tok->start - 2;
......@@ -1691,6 +1713,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
16911713 case IrInstructionIdSwitchTarget:
16921714 case IrInstructionIdStaticEval:
16931715 case IrInstructionIdImport:
1716 case IrInstructionIdContainerInitFields:
16941717 zig_unreachable();
16951718 case IrInstructionIdReturn:
16961719 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
......@@ -1720,6 +1743,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
17201743 return ir_render_call(g, executable, (IrInstructionCall *)instruction);
17211744 case IrInstructionIdStructFieldPtr:
17221745 return ir_render_struct_field_ptr(g, executable, (IrInstructionStructFieldPtr *)instruction);
1746 case IrInstructionIdEnumFieldPtr:
1747 return ir_render_enum_field_ptr(g, executable, (IrInstructionEnumFieldPtr *)instruction);
17231748 case IrInstructionIdAsm:
17241749 return ir_render_asm(g, executable, (IrInstructionAsm *)instruction);
17251750 case IrInstructionIdTestNull:
......@@ -1738,7 +1763,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
17381763 return ir_render_ref(g, executable, (IrInstructionRef *)instruction);
17391764 case IrInstructionIdSwitchVar:
17401765 case IrInstructionIdContainerInitList:
1741 case IrInstructionIdContainerInitFields:
1766 case IrInstructionIdStructInit:
17421767 case IrInstructionIdEnumTag:
17431768 case IrInstructionIdArrayLen:
17441769 zig_panic("TODO render more IR instructions to LLVM");
......@@ -1960,6 +1985,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
19601985 case TypeTableEntryIdNamespace:
19611986 case TypeTableEntryIdBlock:
19621987 case TypeTableEntryIdGenericFn:
1988 case TypeTableEntryIdBoundFn:
19631989 case TypeTableEntryIdVar:
19641990 zig_unreachable();
19651991
......@@ -2197,7 +2223,6 @@ static void do_code_gen(CodeGen *g) {
21972223
21982224 TypeTableEntry *fn_type = fn_table_entry->type_entry;
21992225
2200 bool is_sret = false;
22012226 if (!type_has_bits(fn_type->data.fn.fn_type_id.return_type)) {
22022227 // nothing to do
22032228 } else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer) {
......@@ -2208,10 +2233,6 @@ static void do_code_gen(CodeGen *g) {
22082233 LLVMValueRef first_arg = LLVMGetParam(fn_table_entry->fn_value, 0);
22092234 LLVMAddAttribute(first_arg, LLVMStructRetAttribute);
22102235 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);
22152236 }
22162237
22172238
......@@ -2234,9 +2255,7 @@ static void do_code_gen(CodeGen *g) {
22342255 if (param_is_noalias) {
22352256 LLVMAddAttribute(argument_val, LLVMNoAliasAttribute);
22362257 }
2237 if ((param_type->id == TypeTableEntryIdPointer && (param_type->data.pointer.is_const || fn_table_entry->is_pure)) ||
2238 is_byval)
2239 {
2258 if ((param_type->id == TypeTableEntryIdPointer && param_type->data.pointer.is_const) || is_byval) {
22402259 LLVMAddAttribute(argument_val, LLVMReadOnlyAttribute);
22412260 }
22422261 if (param_type->id == TypeTableEntryIdPointer) {
......@@ -2339,6 +2358,15 @@ static void do_code_gen(CodeGen *g) {
23392358 } else if (instruction->id == IrInstructionIdRef) {
23402359 IrInstructionRef *ref_instruction = (IrInstructionRef *)instruction;
23412360 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;
23422370 } else {
23432371 zig_unreachable();
23442372 }
......@@ -2464,46 +2492,39 @@ static void define_builtin_types(CodeGen *g) {
24642492 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNamespace);
24652493 buf_init_from_str(&entry->name, "(namespace)");
24662494 entry->zero_bits = true;
2467 entry->deep_const = true;
24682495 g->builtin_types.entry_namespace = entry;
24692496 }
24702497 {
24712498 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBlock);
24722499 buf_init_from_str(&entry->name, "(block)");
24732500 entry->zero_bits = true;
2474 entry->deep_const = true;
24752501 g->builtin_types.entry_block = entry;
24762502 }
24772503 {
24782504 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);
24792505 buf_init_from_str(&entry->name, "(float literal)");
24802506 entry->zero_bits = true;
2481 entry->deep_const = true;
24822507 g->builtin_types.entry_num_lit_float = entry;
24832508 }
24842509 {
24852510 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitInt);
24862511 buf_init_from_str(&entry->name, "(integer literal)");
24872512 entry->zero_bits = true;
2488 entry->deep_const = true;
24892513 g->builtin_types.entry_num_lit_int = entry;
24902514 }
24912515 {
24922516 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUndefLit);
24932517 buf_init_from_str(&entry->name, "(undefined)");
2494 entry->deep_const = true;
24952518 g->builtin_types.entry_undef = entry;
24962519 }
24972520 {
24982521 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNullLit);
24992522 buf_init_from_str(&entry->name, "(null)");
2500 entry->deep_const = true;
25012523 g->builtin_types.entry_null = entry;
25022524 }
25032525 {
25042526 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVar);
25052527 buf_init_from_str(&entry->name, "(var)");
2506 entry->deep_const = true;
25072528 g->builtin_types.entry_var = entry;
25082529 }
25092530
......@@ -2514,7 +2535,6 @@ static void define_builtin_types(CodeGen *g) {
25142535
25152536 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
25162537 entry->type_ref = LLVMIntType(size_in_bits);
2517 entry->deep_const = true;
25182538
25192539 const char u_or_i = is_signed ? 'i' : 'u';
25202540 buf_resize(&entry->name, 0);
......@@ -2554,7 +2574,6 @@ static void define_builtin_types(CodeGen *g) {
25542574
25552575 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
25562576 entry->type_ref = LLVMIntType(size_in_bits);
2557 entry->deep_const = true;
25582577
25592578 buf_init_from_str(&entry->name, info->name);
25602579
......@@ -2574,7 +2593,6 @@ static void define_builtin_types(CodeGen *g) {
25742593 {
25752594 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBool);
25762595 entry->type_ref = LLVMInt1Type();
2577 entry->deep_const = true;
25782596 buf_init_from_str(&entry->name, "bool");
25792597 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref);
25802598 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) {
25902608 bool is_signed = is_signed_list[sign_i];
25912609
25922610 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
2593 entry->deep_const = true;
25942611 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
25952612
25962613 const char u_or_i = is_signed ? 'i' : 'u';
......@@ -2616,7 +2633,6 @@ static void define_builtin_types(CodeGen *g) {
26162633 }
26172634 {
26182635 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
2619 entry->deep_const = true;
26202636 entry->type_ref = LLVMFloatType();
26212637 buf_init_from_str(&entry->name, "f32");
26222638 entry->data.floating.bit_count = 32;
......@@ -2632,7 +2648,6 @@ static void define_builtin_types(CodeGen *g) {
26322648 }
26332649 {
26342650 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
2635 entry->deep_const = true;
26362651 entry->type_ref = LLVMDoubleType();
26372652 buf_init_from_str(&entry->name, "f64");
26382653 entry->data.floating.bit_count = 64;
......@@ -2648,7 +2663,6 @@ static void define_builtin_types(CodeGen *g) {
26482663 }
26492664 {
26502665 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
2651 entry->deep_const = true;
26522666 entry->type_ref = LLVMX86FP80Type();
26532667 buf_init_from_str(&entry->name, "c_long_double");
26542668 entry->data.floating.bit_count = 80;
......@@ -2664,7 +2678,6 @@ static void define_builtin_types(CodeGen *g) {
26642678 }
26652679 {
26662680 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
2667 entry->deep_const = true;
26682681 entry->type_ref = LLVMVoidType();
26692682 entry->zero_bits = true;
26702683 buf_init_from_str(&entry->name, "void");
......@@ -2677,7 +2690,6 @@ static void define_builtin_types(CodeGen *g) {
26772690 }
26782691 {
26792692 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUnreachable);
2680 entry->deep_const = true;
26812693 entry->type_ref = LLVMVoidType();
26822694 entry->zero_bits = true;
26832695 buf_init_from_str(&entry->name, "unreachable");
......@@ -2687,7 +2699,6 @@ static void define_builtin_types(CodeGen *g) {
26872699 }
26882700 {
26892701 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMetaType);
2690 entry->deep_const = true;
26912702 buf_init_from_str(&entry->name, "type");
26922703 entry->zero_bits = true;
26932704 g->builtin_types.entry_type = entry;
......@@ -2710,7 +2721,6 @@ static void define_builtin_types(CodeGen *g) {
27102721
27112722 {
27122723 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPureError);
2713 entry->deep_const = true;
27142724 buf_init_from_str(&entry->name, "error");
27152725
27162726 // 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) {
27262736
27272737 {
27282738 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
2729 entry->deep_const = true;
27302739 entry->zero_bits = true; // only allowed at compile time
27312740 buf_init_from_str(&entry->name, "@OS");
27322741 uint32_t field_count = target_os_count();
......@@ -2752,7 +2761,6 @@ static void define_builtin_types(CodeGen *g) {
27522761
27532762 {
27542763 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
2755 entry->deep_const = true;
27562764 entry->zero_bits = true; // only allowed at compile time
27572765 buf_init_from_str(&entry->name, "@Arch");
27582766 uint32_t field_count = target_arch_count();
......@@ -2784,7 +2792,6 @@ static void define_builtin_types(CodeGen *g) {
27842792
27852793 {
27862794 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
2787 entry->deep_const = true;
27882795 entry->zero_bits = true; // only allowed at compile time
27892796 buf_init_from_str(&entry->name, "@Environ");
27902797 uint32_t field_count = target_environ_count();
......@@ -2811,7 +2818,6 @@ static void define_builtin_types(CodeGen *g) {
28112818
28122819 {
28132820 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
2814 entry->deep_const = true;
28152821 entry->zero_bits = true; // only allowed at compile time
28162822 buf_init_from_str(&entry->name, "@ObjectFormat");
28172823 uint32_t field_count = target_oformat_count();
......@@ -2838,7 +2844,6 @@ static void define_builtin_types(CodeGen *g) {
28382844
28392845 {
28402846 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnum);
2841 entry->deep_const = true;
28422847 buf_init_from_str(&entry->name, "AtomicOrder");
28432848 uint32_t field_count = 6;
28442849 entry->data.enumeration.src_field_count = field_count;
......@@ -2998,7 +3003,6 @@ static void define_builtin_fns(CodeGen *g) {
29983003 create_builtin_fn_with_arg_count(g, BuiltinFnIdUnreachable, "unreachable", 0);
29993004 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnTest, "setFnTest", 2);
30003005 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnVisible, "setFnVisible", 2);
3001 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnStaticEval, "setFnStaticEval", 2);
30023006 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnNoInline, "setFnNoInline", 2);
30033007 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);
30043008}
......@@ -3287,6 +3291,7 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
32873291 case TypeTableEntryIdInvalid:
32883292 case TypeTableEntryIdMetaType:
32893293 case TypeTableEntryIdGenericFn:
3294 case TypeTableEntryIdBoundFn:
32903295 case TypeTableEntryIdNamespace:
32913296 case TypeTableEntryIdBlock:
32923297 case TypeTableEntryIdNumLitFloat:
src/eval.cpp+1
......@@ -56,6 +56,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty
5656 case TypeTableEntryIdBlock:
5757 zig_panic("TODO");
5858 case TypeTableEntryIdGenericFn:
59 case TypeTableEntryIdBoundFn:
5960 case TypeTableEntryIdInvalid:
6061 case TypeTableEntryIdUnreachable:
6162 case TypeTableEntryIdVar:
src/ir.cpp+660-1415
......@@ -49,6 +49,10 @@ ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) {
4949 }
5050}
5151
52static bool ir_should_inline(IrBuilder *irb) {
53 return irb->exec->is_inline;
54}
55
5256static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) {
5357 assert(basic_block);
5458 assert(instruction);
......@@ -160,6 +164,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr *
160164 return IrInstructionIdStructFieldPtr;
161165}
162166
167static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumFieldPtr *) {
168 return IrInstructionIdEnumFieldPtr;
169}
170
163171static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) {
164172 return IrInstructionIdElemPtr;
165173}
......@@ -276,6 +284,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) {
276284 return IrInstructionIdRef;
277285}
278286
287static constexpr IrInstructionId ir_instruction_id(IrInstructionStructInit *) {
288 return IrInstructionIdStructInit;
289}
290
279291template<typename T>
280292static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) {
281293 T *special_instruction = allocate<T>(1);
......@@ -293,15 +305,14 @@ static T *ir_build_instruction(IrBuilder *irb, AstNode *source_node) {
293305 return special_instruction;
294306}
295307
296static IrInstruction *ir_build_cast(IrBuilder *irb, AstNode *source_node, IrInstruction *dest_type,
297 IrInstruction *value, CastOp cast_op)
308static IrInstruction *ir_build_cast(IrBuilder *irb, AstNode *source_node, TypeTableEntry *dest_type,
309 IrInstruction *value, CastOp cast_op)
298310{
299311 IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, source_node);
300312 cast_instruction->dest_type = dest_type;
301313 cast_instruction->value = value;
302314 cast_instruction->cast_op = cast_op;
303315
304 ir_ref_instruction(dest_type);
305316 ir_ref_instruction(value);
306317
307318 return &cast_instruction->base;
......@@ -353,10 +364,14 @@ static IrInstruction *ir_build_return_from(IrBuilder *irb, IrInstruction *old_in
353364 return new_instruction;
354365}
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);
357371 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, source_node);
358372 const_instruction->base.type_entry = type_entry;
359373 const_instruction->base.static_value.special = ConstValSpecialStatic;
374 const_instruction->base.static_value.depends_on_compile_var = depends_on_compile_var;
360375 return &const_instruction->base;
361376}
362377
......@@ -452,6 +467,18 @@ static IrInstruction *ir_build_const_bool(IrBuilder *irb, AstNode *source_node,
452467 return &const_instruction->base;
453468}
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
455482static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, AstNode *source_node, Buf *str) {
456483 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
457484 TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8;
......@@ -595,26 +622,48 @@ static IrInstruction *ir_build_struct_field_ptr_from(IrBuilder *irb, IrInstructi
595622 return new_instruction;
596623}
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
598646static 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)
600648{
601649 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;
603652 call_instruction->arg_count = arg_count;
604653 call_instruction->args = args;
605654
606 ir_ref_instruction(fn);
607 for (size_t i = 0; i < arg_count; i += 1) {
655 if (fn_ref)
656 ir_ref_instruction(fn_ref);
657 for (size_t i = 0; i < arg_count; i += 1)
608658 ir_ref_instruction(args[i]);
609 }
610659
611660 return &call_instruction->base;
612661}
613662
614663static 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)
616665{
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);
618667 ir_link_new_instruction(new_instruction, old_instruction);
619668 return new_instruction;
620669}
......@@ -706,24 +755,55 @@ static IrInstruction *ir_build_container_init_list(IrBuilder *irb, AstNode *sour
706755 return &container_init_list_instruction->base;
707756}
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
709767static 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)
711769{
712770 IrInstructionContainerInitFields *container_init_fields_instruction =
713771 ir_build_instruction<IrInstructionContainerInitFields>(irb, source_node);
714772 container_init_fields_instruction->container_type = container_type;
715773 container_init_fields_instruction->field_count = field_count;
716 container_init_fields_instruction->field_names = field_names;
717 container_init_fields_instruction->field_values = field_values;
774 container_init_fields_instruction->fields = fields;
718775
719776 ir_ref_instruction(container_type);
720777 for (size_t i = 0; i < field_count; i += 1) {
721 ir_ref_instruction(field_values[i]);
778 ir_ref_instruction(fields[i].value);
722779 }
723780
724781 return &container_init_fields_instruction->base;
725782}
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
727807static IrInstruction *ir_build_unreachable(IrBuilder *irb, AstNode *source_node) {
728808 IrInstructionUnreachable *unreachable_instruction =
729809 ir_build_instruction<IrInstructionUnreachable>(irb, source_node);
......@@ -1442,7 +1522,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstN
14421522 ref_instruction = ir_build_const_fn(irb, source_node, fn_entry);
14431523 }
14441524 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);
14461526 else
14471527 return ref_instruction;
14481528 } else if (decl_node->type == NodeTypeContainerDecl) {
......@@ -1455,14 +1535,14 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstN
14551535 ref_instruction = ir_build_const_type(irb, source_node, decl_node->data.struct_decl.type_entry);
14561536 }
14571537 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);
14591539 else
14601540 return ref_instruction;
14611541 } else if (decl_node->type == NodeTypeTypeDecl) {
14621542 TypeTableEntry *child_type = decl_node->data.type_decl.child_type_entry;
14631543 IrInstruction *ref_instruction = ir_build_const_type(irb, source_node, child_type);
14641544 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);
14661546 else
14671547 return ref_instruction;
14681548 } else {
......@@ -1712,7 +1792,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
17121792 case BuiltinFnIdDivExact:
17131793 case BuiltinFnIdTruncate:
17141794 case BuiltinFnIdIntType:
1715 case BuiltinFnIdSetFnStaticEval:
17161795 case BuiltinFnIdSetFnNoInline:
17171796 zig_panic("TODO IR gen more builtin functions");
17181797 }
......@@ -1726,9 +1805,9 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) {
17261805 return ir_gen_builtin_fn_call(irb, node);
17271806
17281807 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);
1730 if (fn == irb->codegen->invalid_instruction)
1731 return fn;
1808 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, node->block_context);
1809 if (fn_ref == irb->codegen->invalid_instruction)
1810 return fn_ref;
17321811
17331812 size_t arg_count = node->data.fn_call_expr.params.length;
17341813 IrInstruction **args = allocate<IrInstruction*>(arg_count);
......@@ -1737,7 +1816,7 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) {
17371816 args[i] = ir_gen_node(irb, arg_node, node->block_context);
17381817 }
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);
17411820}
17421821
17431822static 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) {
17541833 IrBasicBlock *else_block = ir_build_basic_block(irb, "Else");
17551834 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;
17581837 ir_build_cond_br(irb, condition->source_node, condition, then_block, else_block, is_inline);
17591838
17601839 ir_set_cursor_at_end(irb, then_block);
......@@ -1865,8 +1944,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node)
18651944
18661945 if (kind == ContainerInitKindStruct) {
18671946 size_t field_count = container_init_expr->entries.length;
1868 IrInstruction **values = allocate<IrInstruction *>(field_count);
1869 Buf **names = allocate<Buf *>(field_count);
1947 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count);
18701948 for (size_t i = 0; i < field_count; i += 1) {
18711949 AstNode *entry_node = container_init_expr->entries.at(i);
18721950 assert(entry_node->type == NodeTypeStructValueField);
......@@ -1877,10 +1955,11 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node)
18771955 if (expr_value == irb->codegen->invalid_instruction)
18781956 return expr_value;
18791957
1880 names[i] = name;
1881 values[i] = expr_value;
1958 fields[i].name = name;
1959 fields[i].value = expr_value;
1960 fields[i].source_node = entry_node;
18821961 }
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);
18841963 } else if (kind == ContainerInitKindArray) {
18851964 size_t item_count = container_init_expr->entries.length;
18861965 IrInstruction **values = allocate<IrInstruction *>(item_count);
......@@ -1919,7 +1998,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) {
19191998 bool is_shadowable = false;
19201999 bool is_const = variable_declaration->is_const;
19212000 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;
19232002 VariableTableEntry *var = ir_add_local_var(irb, node, node->block_context,
19242003 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) {
19432022 ir_build_basic_block(irb, "WhileContinue") : cond_block;
19442023 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;
19472026 ir_build_br(irb, node, cond_block, is_inline);
19482027
19492028 if (continue_expr_node) {
......@@ -1998,7 +2077,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {
19982077 } else {
19992078 elem_var_type = ir_build_ptr_type_child(irb, elem_node, pointer_type);
20002079 }
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
20032082 BlockContext *child_scope = new_block_context(node, parent_scope);
20042083 child_scope->parent_loop_node = node;
......@@ -2219,7 +2298,7 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) {
22192298 IrBasicBlock *else_block = ir_build_basic_block(irb, "MaybeElse");
22202299 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;
22232302 ir_build_cond_br(irb, node, is_nonnull_value, then_block, else_block, is_inline);
22242303
22252304 ir_set_cursor_at_end(irb, then_block);
......@@ -2322,7 +2401,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
23222401
23232402 size_t prong_count = node->data.switch_expr.prongs.length;
23242403 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
23272406 ZigList<IrInstruction *> incoming_values = {0};
23282407 ZigList<IrBasicBlock *> incoming_blocks = {0};
......@@ -2495,7 +2574,7 @@ static IrInstruction *ir_gen_label(IrBuilder *irb, AstNode *node) {
24952574 node->block_context->label_table.put(label_name, label);
24962575 }
24972576
2498 bool is_inline = (node->block_context->fn_entry == nullptr);
2577 bool is_inline = ir_should_inline(irb);
24992578 ir_build_br(irb, node, label_block, is_inline);
25002579 ir_set_cursor_at_end(irb, label_block);
25012580 return ir_build_const_void(irb, node);
......@@ -2535,56 +2614,58 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContex
25352614 node->block_context = block_context;
25362615
25372616 switch (node->type) {
2617 case NodeTypeStructValueField:
2618 zig_unreachable();
25382619 case NodeTypeBlock:
2539 return ir_gen_block(irb, node);
2620 return ir_lval_wrap(irb, ir_gen_block(irb, node), lval);
25402621 case NodeTypeBinOpExpr:
2541 return ir_gen_bin_op(irb, node);
2622 return ir_lval_wrap(irb, ir_gen_bin_op(irb, node), lval);
25422623 case NodeTypeNumberLiteral:
2543 return ir_gen_num_lit(irb, node);
2624 return ir_lval_wrap(irb, ir_gen_num_lit(irb, node), lval);
25442625 case NodeTypeSymbol:
25452626 return ir_gen_symbol(irb, node, lval);
25462627 case NodeTypeFnCallExpr:
25472628 return ir_lval_wrap(irb, ir_gen_fn_call(irb, node), lval);
25482629 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);
25502631 case NodeTypePrefixOpExpr:
25512632 return ir_gen_prefix_op_expr(irb, node, lval);
25522633 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);
25542635 case NodeTypeVariableDeclaration:
2555 return ir_gen_var_decl(irb, node);
2636 return ir_lval_wrap(irb, ir_gen_var_decl(irb, node), lval);
25562637 case NodeTypeWhileExpr:
2557 return ir_gen_while_expr(irb, node);
2638 return ir_lval_wrap(irb, ir_gen_while_expr(irb, node), lval);
25582639 case NodeTypeForExpr:
2559 return ir_gen_for_expr(irb, node);
2640 return ir_lval_wrap(irb, ir_gen_for_expr(irb, node), lval);
25602641 case NodeTypeArrayAccessExpr:
25612642 return ir_gen_array_access(irb, node, lval);
25622643 case NodeTypeReturnExpr:
2563 return ir_gen_return(irb, node);
2644 return ir_lval_wrap(irb, ir_gen_return(irb, node), lval);
25642645 case NodeTypeFieldAccessExpr:
25652646 return ir_gen_field_access(irb, node, lval);
25662647 case NodeTypeThisLiteral:
2567 return ir_gen_this_literal(irb, node);
2648 return ir_lval_wrap(irb, ir_gen_this_literal(irb, node), lval);
25682649 case NodeTypeBoolLiteral:
2569 return ir_gen_bool_literal(irb, node);
2650 return ir_lval_wrap(irb, ir_gen_bool_literal(irb, node), lval);
25702651 case NodeTypeArrayType:
2571 return ir_gen_array_type(irb, node);
2652 return ir_lval_wrap(irb, ir_gen_array_type(irb, node), lval);
25722653 case NodeTypeStringLiteral:
2573 return ir_gen_string_literal(irb, node);
2654 return ir_lval_wrap(irb, ir_gen_string_literal(irb, node), lval);
25742655 case NodeTypeUndefinedLiteral:
2575 return ir_gen_undefined_literal(irb, node);
2656 return ir_lval_wrap(irb, ir_gen_undefined_literal(irb, node), lval);
25762657 case NodeTypeAsmExpr:
2577 return ir_gen_asm_expr(irb, node);
2658 return ir_lval_wrap(irb, ir_gen_asm_expr(irb, node), lval);
25782659 case NodeTypeNullLiteral:
2579 return ir_gen_null_literal(irb, node);
2660 return ir_lval_wrap(irb, ir_gen_null_literal(irb, node), lval);
25802661 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);
25822663 case NodeTypeSwitchExpr:
2583 return ir_gen_switch_expr(irb, node);
2664 return ir_lval_wrap(irb, ir_gen_switch_expr(irb, node), lval);
25842665 case NodeTypeLabel:
2585 return ir_gen_label(irb, node);
2666 return ir_lval_wrap(irb, ir_gen_label(irb, node), lval);
25862667 case NodeTypeGoto:
2587 return ir_gen_goto(irb, node);
2668 return ir_lval_wrap(irb, ir_gen_goto(irb, node), lval);
25882669 case NodeTypeTypeLiteral:
25892670 return ir_lval_wrap(irb, ir_gen_type_literal(irb, node), lval);
25902671 case NodeTypeUnwrapErrorExpr:
......@@ -2604,7 +2685,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, BlockContex
26042685 case NodeTypeUse:
26052686 case NodeTypeContainerDecl:
26062687 case NodeTypeStructField:
2607 case NodeTypeStructValueField:
26082688 case NodeTypeSwitchProng:
26092689 case NodeTypeSwitchRange:
26102690 case NodeTypeErrorValueDecl:
......@@ -2642,7 +2722,7 @@ static bool ir_goto_pass2(IrBuilder *irb) {
26422722 }
26432723 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;
26462726 IrInstruction *new_instruction = ir_create_br(irb, goto_node, label->bb, is_inline);
26472727 new_instruction->ref_count = old_instruction->ref_count;
26482728 *slot = new_instruction;
......@@ -2703,6 +2783,21 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {
27032783 return ir_gen(codegn, body_node, scope, ir_executable);
27042784}
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
27062801static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type) {
27072802 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
29183013}
29193014
29203015static 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)
29223017{
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
29273018 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);
29293020 eval_const_expr_implicit_cast(cast_op, &value->static_value, value->type_entry,
29303021 &result->static_value, wanted_type);
29313022 return result;
29323023 } else {
2933 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->source_node,
2934 dest_type, value, cast_op);
3024 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->source_node, wanted_type, value, cast_op);
29353025 result->type_entry = wanted_type;
29363026 if (need_alloca && source_instr->source_node->block_context->fn_entry) {
29373027 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) {
31263216}
31273217
31283218static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
3129 IrInstruction *dest_type, IrInstruction *value)
3219 TypeTableEntry *wanted_type, IrInstruction *value)
31303220{
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;
31353221 TypeTableEntry *actual_type = value->type_entry;
31363222 TypeTableEntry *wanted_type_canon = get_underlying_type(wanted_type);
31373223 TypeTableEntry *actual_type_canon = get_underlying_type(actual_type);
......@@ -3147,21 +3233,21 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
31473233
31483234 // explicit match or non-const to const
31493235 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);
31513237 }
31523238
31533239 // explicit cast from bool to int
31543240 if (wanted_type_canon->id == TypeTableEntryIdInt &&
31553241 actual_type_canon->id == TypeTableEntryIdBool)
31563242 {
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);
31583244 }
31593245
31603246 // explicit cast from pointer to isize or usize
31613247 if ((wanted_type_canon == isize_type || wanted_type_canon == usize_type) &&
31623248 type_is_codegen_pointer(actual_type_canon))
31633249 {
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);
31653251 }
31663252
31673253
......@@ -3169,7 +3255,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
31693255 if (wanted_type_canon->id == TypeTableEntryIdPointer &&
31703256 (actual_type_canon == isize_type || actual_type_canon == usize_type))
31713257 {
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);
31733259 }
31743260
31753261 // explicit widening or shortening cast
......@@ -3178,21 +3264,21 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
31783264 (wanted_type_canon->id == TypeTableEntryIdFloat &&
31793265 actual_type_canon->id == TypeTableEntryIdFloat))
31803266 {
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);
31823268 }
31833269
31843270 // explicit cast from int to float
31853271 if (wanted_type_canon->id == TypeTableEntryIdFloat &&
31863272 actual_type_canon->id == TypeTableEntryIdInt)
31873273 {
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);
31893275 }
31903276
31913277 // explicit cast from float to int
31923278 if (wanted_type_canon->id == TypeTableEntryIdInt &&
31933279 actual_type_canon->id == TypeTableEntryIdFloat)
31943280 {
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);
31963282 }
31973283
31983284 // explicit cast from array to slice
......@@ -3202,7 +3288,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
32023288 wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type,
32033289 actual_type->data.array.child_type))
32043290 {
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);
32063292 }
32073293
32083294 // explicit cast from []T to []u8 or []u8 to []T
......@@ -3212,8 +3298,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
32123298 (wanted_type->data.structure.fields[0].type_entry->data.pointer.is_const ||
32133299 !actual_type->data.structure.fields[0].type_entry->data.pointer.is_const))
32143300 {
3215 mark_impure_fn(ira->codegen, source_instr->source_node->block_context, source_instr->source_node);
3216 return ir_resolve_cast(ira, source_instr, value, dest_type, CastOpResizeSlice, true);
3301 if (!ir_emit_global_runtime_side_effect(ira, source_instr))
3302 return ira->codegen->invalid_instruction;
3303 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpResizeSlice, true);
32173304 }
32183305
32193306 // explicit cast from [N]u8 to []T
......@@ -3221,11 +3308,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
32213308 actual_type->id == TypeTableEntryIdArray &&
32223309 is_u8(actual_type->data.array.child_type))
32233310 {
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;
32253313 uint64_t child_type_size = type_size(ira->codegen,
32263314 wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type);
32273315 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);
32293317 } else {
32303318 add_node_error(ira->codegen, source_instr->source_node,
32313319 buf_sprintf("unable to convert %s to %s: size mismatch",
......@@ -3238,7 +3326,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
32383326 if ((actual_type->id == TypeTableEntryIdPointer || actual_type->id == TypeTableEntryIdFn) &&
32393327 (wanted_type->id == TypeTableEntryIdPointer || wanted_type->id == TypeTableEntryIdFn))
32403328 {
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);
32423330 }
32433331
32443332 // explicit cast from maybe pointer to another maybe pointer
......@@ -3249,13 +3337,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
32493337 (wanted_type->data.maybe.child_type->id == TypeTableEntryIdPointer ||
32503338 wanted_type->data.maybe.child_type->id == TypeTableEntryIdFn))
32513339 {
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);
32533341 }
32543342
32553343 // explicit cast from child type of maybe type to maybe type
32563344 if (wanted_type->id == TypeTableEntryIdMaybe) {
32573345 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,
32593347 CastOpMaybeWrap, true);
32603348 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonNull;
32613349 return cast_instruction;
......@@ -3263,7 +3351,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
32633351 actual_type->id == TypeTableEntryIdNumLitFloat)
32643352 {
32653353 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,
32673355 CastOpMaybeWrap, true);
32683356 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonNull;
32693357 return cast_instruction;
......@@ -3277,7 +3365,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
32773365 if (wanted_type->id == TypeTableEntryIdMaybe &&
32783366 actual_type->id == TypeTableEntryIdNullLit)
32793367 {
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,
32813369 CastOpNullToMaybe, true);
32823370 cast_instruction->return_knowledge = ReturnKnowledgeKnownNull;
32833371 return cast_instruction;
......@@ -3286,7 +3374,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
32863374 // explicit cast from child type of error type to error type
32873375 if (wanted_type->id == TypeTableEntryIdErrorUnion) {
32883376 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,
32903378 CastOpErrorWrap, true);
32913379 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonError;
32923380 return cast_instruction;
......@@ -3294,7 +3382,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
32943382 actual_type->id == TypeTableEntryIdNumLitFloat)
32953383 {
32963384 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,
32983386 CastOpErrorWrap, true);
32993387 cast_instruction->return_knowledge = ReturnKnowledgeKnownNonError;
33003388 return cast_instruction;
......@@ -3308,7 +3396,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
33083396 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
33093397 actual_type->id == TypeTableEntryIdPureError)
33103398 {
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,
33123400 CastOpPureErrorWrap, false);
33133401 cast_instruction->return_knowledge = ReturnKnowledgeKnownError;
33143402 return cast_instruction;
......@@ -3333,7 +3421,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
33333421 } else {
33343422 zig_unreachable();
33353423 }
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);
33373425 } else {
33383426 return ira->codegen->invalid_instruction;
33393427 }
......@@ -3351,7 +3439,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
33513439 if (bignum_fits_in_bits(&bn, wanted_type->data.integral.bit_count,
33523440 wanted_type->data.integral.is_signed))
33533441 {
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);
33553443 } else {
33563444 add_node_error(ira->codegen, source_instr->source_node,
33573445 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
33643452 wanted_type->id == TypeTableEntryIdEnum &&
33653453 wanted_type->data.enumeration.gen_field_count == 0)
33663454 {
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);
33683456 }
33693457
33703458 // explicit cast from enum type with no payload to integer
......@@ -3372,12 +3460,12 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
33723460 actual_type->id == TypeTableEntryIdEnum &&
33733461 actual_type->data.enumeration.gen_field_count == 0)
33743462 {
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);
33763464 }
33773465
33783466 // explicit cast from undefined to anything
33793467 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);
33813469 }
33823470
33833471 add_node_error(ira->codegen, source_instr->source_node,
......@@ -3410,11 +3498,7 @@ static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value,
34103498 return ira->codegen->invalid_instruction;
34113499
34123500 case ImplicitCastMatchResultYes:
3413 {
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 }
3501 return ir_analyze_cast(ira, value, expected_type, value);
34183502 case ImplicitCastMatchResultReportedError:
34193503 return ira->codegen->invalid_instruction;
34203504 }
......@@ -3422,6 +3506,58 @@ static IrInstruction *ir_get_casted_value(IrAnalyze *ira, IrInstruction *value,
34223506 zig_unreachable();
34233507}
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
34253561static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) {
34263562 if (value->type_entry->id == TypeTableEntryIdInvalid)
34273563 return false;
......@@ -3580,6 +3716,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
35803716 case TypeTableEntryIdNamespace:
35813717 case TypeTableEntryIdBlock:
35823718 case TypeTableEntryIdGenericFn:
3719 case TypeTableEntryIdBoundFn:
35833720 if (!is_equality_cmp) {
35843721 add_node_error(ira->codegen, source_node,
35853722 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
39444081 case TypeTableEntryIdUnion:
39454082 case TypeTableEntryIdFn:
39464083 case TypeTableEntryIdGenericFn:
4084 case TypeTableEntryIdBoundFn:
39474085 // OK
39484086 break;
39494087 }
......@@ -3966,13 +4104,121 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
39664104 return ira->codegen->builtin_types.entry_void;
39674105}
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
39694209static 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;
39714211 if (fn_ref->type_entry->id == TypeTableEntryIdInvalid)
39724212 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) {
39754217 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
39764222 size_t actual_param_count = call_instruction->arg_count;
39774223
39784224 if (actual_param_count != 1) {
......@@ -3982,38 +4228,39 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
39824228 }
39834229
39844230 IrInstruction *arg = call_instruction->args[0]->other;
3985 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, fn_ref, arg);
3986 if (cast_instruction == ira->codegen->invalid_instruction)
4231
4232 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg);
4233 if (cast_instruction->type_entry->id == TypeTableEntryIdInvalid)
39874234 return ira->codegen->builtin_types.entry_invalid;
39884235
39894236 ir_link_new_instruction(cast_instruction, &call_instruction->base);
39904237 return ir_finish_anal(ira, cast_instruction->type_entry);
39914238 } else if (fn_ref->type_entry->id == TypeTableEntryIdFn) {
3992 // TODO fully port over the fn call analyze code to IR
3993 FnTableEntry *fn_table_entry = fn_ref->static_value.data.x_fn;
3994 TypeTableEntry *fn_type = fn_table_entry->type_entry;
3995
3996 IrInstruction **casted_args = allocate<IrInstruction *>(call_instruction->arg_count);
3997 for (size_t i = 0; i < call_instruction->arg_count; i += 1) {
3998 TypeTableEntry *param_type = fn_type->data.fn.fn_type_id.param_info[i].type;
3999 IrInstruction *old_arg = call_instruction->args[i]->other;
4000 if (old_arg->type_entry->id == TypeTableEntryIdInvalid)
4001 return ira->codegen->builtin_types.entry_invalid;
4002 casted_args[i] = ir_get_casted_value(ira, old_arg, param_type);
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);
4239 FnTableEntry *fn_table_entry = ir_resolve_fn(ira, fn_ref);
4240 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry,
4241 fn_ref, nullptr, is_inline);
4242 } else if (fn_ref->type_entry->id == TypeTableEntryIdBoundFn) {
4243 assert(fn_ref->static_value.special == ConstValSpecialStatic);
4244 FnTableEntry *fn_table_entry = fn_ref->static_value.data.x_bound_fn.fn;
4245 IrInstruction *first_arg_ptr = fn_ref->static_value.data.x_bound_fn.first_arg;
4246 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry,
4247 nullptr, first_arg_ptr, is_inline);
4248 } else if (fn_ref->type_entry->id == TypeTableEntryIdGenericFn) {
4249 zig_panic("TODO generic fn call");
40094250 } 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;
40114254 }
4012 } else {
4013 //ir_build_call_from(&ira->new_irb, &call_instruction->base,
4014 // call_instruction->fn, call_instruction->arg_count, call_instruction->args);
4255 }
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;
40174264 }
40184265}
40194266
......@@ -4071,6 +4318,7 @@ static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstruct
40714318 case TypeTableEntryIdUnion:
40724319 case TypeTableEntryIdFn:
40734320 case TypeTableEntryIdGenericFn:
4321 case TypeTableEntryIdBoundFn:
40744322 {
40754323 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base,
40764324 value->static_value.depends_on_compile_var);
......@@ -4119,6 +4367,7 @@ static TypeTableEntry *ir_analyze_unary_address_of(IrAnalyze *ira, IrInstruction
41194367 case TypeTableEntryIdUnreachable:
41204368 case TypeTableEntryIdVar:
41214369 case TypeTableEntryIdGenericFn:
4370 case TypeTableEntryIdBoundFn:
41224371 add_node_error(ira->codegen, un_op_instruction->base.source_node,
41234372 buf_sprintf("unable to get address of type '%s'", buf_ptr(&target_type->name)));
41244373 // 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
42174466 case TypeTableEntryIdNamespace:
42184467 case TypeTableEntryIdBlock:
42194468 case TypeTableEntryIdGenericFn:
4469 case TypeTableEntryIdBoundFn:
42204470 {
42214471 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base,
42224472 value->static_value.depends_on_compile_var);
......@@ -4626,7 +4876,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
46264876
46274877static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira,
46284878 TypeTableEntry *bare_struct_type, Buf *field_name, IrInstructionFieldPtr *field_ptr_instruction,
4629 TypeTableEntry *container_type)
4879 IrInstruction *container_ptr, TypeTableEntry *container_type)
46304880{
46314881 if (!is_slice(bare_struct_type)) {
46324882 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,
46344884 auto entry = container_block_context->decl_table.maybe_get(field_name);
46354885 AstNode *fn_decl_node = entry ? entry->value : nullptr;
46364886 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);
46384896 }
46394897 }
46404898 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,
46434901}
46444902
46454903
4646static TypeTableEntry *ir_analyze_container_member_access(IrAnalyze *ira, Buf *field_name,
4647 IrInstructionFieldPtr *field_ptr_instruction, TypeTableEntry *container_type)
4904static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,
4905 IrInstructionFieldPtr *field_ptr_instruction, IrInstruction *container_ptr, TypeTableEntry *container_type)
46484906{
4649 IrInstruction *container_ptr = field_ptr_instruction->container_ptr->other;
46504907 TypeTableEntry *bare_type = container_ref_type(container_type);
4651 if (!type_is_complete(bare_type)) {
4908 if (!type_is_complete(bare_type))
46524909 resolve_container_type(ira->codegen, bare_type);
4653 }
46544910
46554911 if (bare_type->id == TypeTableEntryIdStruct) {
46564912 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
46594915 return get_pointer_to_type(ira->codegen, field->type_entry, false);
46604916 } else {
46614917 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);
46634919 }
46644920 } 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 }
46664929 } else if (bare_type->id == TypeTableEntryIdUnion) {
46674930 zig_panic("TODO");
46684931 } else {
......@@ -4733,7 +4996,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
47334996 if (container_type->id == TypeTableEntryIdInvalid) {
47344997 return container_type;
47354998 } 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);
47375000 } else if (container_type->id == TypeTableEntryIdArray) {
47385001 if (buf_eql_str(field_name, "len")) {
47395002 ConstExprValue *len_val = allocate<ConstExprValue>(1);
......@@ -4749,24 +5012,38 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
47495012 return ira->codegen->builtin_types.entry_invalid;
47505013 }
47515014 } else if (container_type->id == TypeTableEntryIdMetaType) {
4752 zig_panic("TODO type field access");
4753 //TypeTableEntry *child_type = ir_resolve_type(ira, container_ptr);
4754
4755 //if (child_type->id == TypeTableEntryIdInvalid) {
4756 // return ira->codegen->builtin_types.entry_invalid;
4757 //} else if (child_type->id == TypeTableEntryIdEnum) {
4758 // zig_panic("TODO enum type field");
4759 //} else if (child_type->id == TypeTableEntryIdStruct) {
4760 // zig_panic("TODO struct type field");
4761 //} else if (child_type->id == TypeTableEntryIdPureError) {
4762 // zig_panic("TODO error type field");
4763 //} else if (child_type->id == TypeTableEntryIdInt) {
4764 // zig_panic("TODO integer type field");
4765 //} else {
4766 // add_node_error(ira->codegen, source_node,
4767 // buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
4768 // return ira->codegen->builtin_types.entry_invalid;
4769 //}
5015 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr);
5016 if (!container_ptr_val)
5017 return ira->codegen->builtin_types.entry_invalid;
5018 ConstExprValue *child_val = const_ptr_pointee(container_ptr_val);
5019 TypeTableEntry *child_type = child_val->data.x_type;
5020
5021 if (child_type->id == TypeTableEntryIdInvalid) {
5022 return ira->codegen->builtin_types.entry_invalid;
5023 } else if (child_type->id == TypeTableEntryIdEnum) {
5024 zig_panic("TODO enum type field");
5025 } else if (child_type->id == TypeTableEntryIdStruct) {
5026 BlockContext *container_block_context = get_container_block_context(child_type);
5027 auto entry = container_block_context->decl_table.maybe_get(field_name);
5028 AstNode *decl_node = entry ? entry->value : nullptr;
5029 if (decl_node) {
5030 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;
5031 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, decl_node, depends_on_compile_var);
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 }
47705047 } else if (container_type->id == TypeTableEntryIdNamespace) {
47715048 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr);
47725049 if (!container_ptr_val)
......@@ -4817,28 +5094,10 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
48175094
48185095static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *load_ptr_instruction) {
48195096 IrInstruction *ptr = load_ptr_instruction->ptr->other;
4820 TypeTableEntry *type_entry = ptr->type_entry;
4821 if (type_entry->id == TypeTableEntryIdInvalid) {
4822 return type_entry;
4823 } else if (type_entry->id == TypeTableEntryIdPointer) {
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 }
5097 IrInstruction *result = ir_get_deref(ira, &load_ptr_instruction->base, ptr);
5098 ir_link_new_instruction(result, &load_ptr_instruction->base);
5099 assert(result->type_entry);
5100 return result->type_entry;
48425101}
48435102
48445103static 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
49115170 case TypeTableEntryIdNamespace:
49125171 case TypeTableEntryIdBlock:
49135172 case TypeTableEntryIdGenericFn:
5173 case TypeTableEntryIdBoundFn:
49145174 case TypeTableEntryIdMetaType:
49155175 case TypeTableEntryIdVoid:
49165176 case TypeTableEntryIdBool:
......@@ -5148,6 +5408,7 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
51485408 case TypeTableEntryIdFn:
51495409 case TypeTableEntryIdNamespace:
51505410 case TypeTableEntryIdGenericFn:
5411 case TypeTableEntryIdBoundFn:
51515412 {
51525413 TypeTableEntry *result_type = get_slice_type(ira->codegen, resolved_child_type, is_const);
51535414 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,
51615422
51625423static TypeTableEntry *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAsm *asm_instruction) {
51635424 assert(asm_instruction->base.source_node->type == NodeTypeAsmExpr);
5164 mark_impure_fn(ira->codegen, asm_instruction->base.source_node->block_context,
5165 asm_instruction->base.source_node);
5425
5426 if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base))
5427 return ira->codegen->builtin_types.entry_invalid;
51665428
51675429 // TODO validate the output types and variable types
51685430
......@@ -5236,6 +5498,7 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,
52365498 case TypeTableEntryIdFn:
52375499 case TypeTableEntryIdNamespace:
52385500 case TypeTableEntryIdGenericFn:
5501 case TypeTableEntryIdBoundFn:
52395502 {
52405503 TypeTableEntry *result_type = get_array_type(ira->codegen, child_type, size);
52415504 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,
53065569 case TypeTableEntryIdNumLitFloat:
53075570 case TypeTableEntryIdNumLitInt:
53085571 case TypeTableEntryIdGenericFn:
5572 case TypeTableEntryIdBoundFn:
53095573 case TypeTableEntryIdMetaType:
53105574 case TypeTableEntryIdFn:
53115575 case TypeTableEntryIdNamespace:
......@@ -5469,7 +5733,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_br(IrAnalyze *ira,
54695733 return ir_unreach_error(ira);
54705734
54715735 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
54745738 if (is_inline || target_value->static_value.special != ConstValSpecialRuntime) {
54755739 ConstExprValue *target_val = ir_resolve_const(ira, target_value);
......@@ -5599,6 +5863,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
55995863 case TypeTableEntryIdUnion:
56005864 case TypeTableEntryIdBlock:
56015865 case TypeTableEntryIdGenericFn:
5866 case TypeTableEntryIdBoundFn:
56025867 add_node_error(ira->codegen, switch_target_instruction->base.source_node,
56035868 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));
56045869 // 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,
57416006
57426007static TypeTableEntry *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRef *ref_instruction) {
57436008 IrInstruction *value = ref_instruction->value->other;
5744 if (value->type_entry->id == TypeTableEntryIdInvalid)
5745 return ira->codegen->builtin_types.entry_invalid;
6009 return ir_analyze_ref(ira, &ref_instruction->base, value);
6010}
57466011
5747 FnTableEntry *fn_entry = ref_instruction->base.source_node->block_context->fn_entry;
5748 if (!fn_entry || value->static_value.special != ConstValSpecialRuntime) {
5749 ConstExprValue *val = ir_resolve_const(ira, value);
5750 if (!val)
6012static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction,
6013 TypeTableEntry *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields,
6014 bool depends_on_compile_var)
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)
57516047 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 }
57536074 }
57546075
5755 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, value->type_entry, true);
5756 if (handle_is_ptr(value->type_entry)) {
5757 // this instruction is a noop - codegen can pass the pointer we already have as the result
5758 ir_link_new_instruction(value, &ref_instruction->base);
5759 return ptr_type;
5760 } else {
5761 fn_entry->alloca_list.append(&ref_instruction->base);
5762 ir_build_ref_from(&ira->new_irb, &ref_instruction->base, value);
5763 return ptr_type;
6076 bool any_missing = false;
6077 for (size_t i = 0; i < actual_field_count; i += 1) {
6078 if (!field_assign_nodes[i]) {
6079 add_node_error(ira->codegen, instruction->source_node,
6080 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));
6081 any_missing = true;
6082 }
6083 }
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;
57646097 }
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;
57656103}
57666104
5767static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
5768 switch (instruction->id) {
5769 case IrInstructionIdInvalid:
5770 zig_unreachable();
5771 case IrInstructionIdReturn:
5772 return ir_analyze_instruction_return(ira, (IrInstructionReturn *)instruction);
5773 case IrInstructionIdConst:
5774 return ir_analyze_instruction_const(ira, (IrInstructionConst *)instruction);
5775 case IrInstructionIdUnOp:
5776 return ir_analyze_instruction_un_op(ira, (IrInstructionUnOp *)instruction);
5777 case IrInstructionIdBinOp:
5778 return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction);
5779 case IrInstructionIdDeclVar:
5780 return ir_analyze_instruction_decl_var(ira, (IrInstructionDeclVar *)instruction);
5781 case IrInstructionIdLoadPtr:
5782 return ir_analyze_instruction_load_ptr(ira, (IrInstructionLoadPtr *)instruction);
5783 case IrInstructionIdStorePtr:
5784 return ir_analyze_instruction_store_ptr(ira, (IrInstructionStorePtr *)instruction);
5785 case IrInstructionIdElemPtr:
5786 return ir_analyze_instruction_elem_ptr(ira, (IrInstructionElemPtr *)instruction);
5787 case IrInstructionIdVarPtr:
5788 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction);
6105static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira, IrInstructionContainerInitList *instruction) {
6106 IrInstruction *container_type_value = instruction->container_type->other;
6107 TypeTableEntry *container_type = ir_resolve_type(ira, container_type_value);
6108 if (!container_type)
6109 return ira->codegen->builtin_types.entry_invalid;
6110
6111 size_t elem_count = instruction->item_count;
6112 bool depends_on_compile_var = container_type_value->static_value.depends_on_compile_var;
6113
6114 if (container_type->id == TypeTableEntryIdStruct && !is_slice(container_type) && elem_count == 0) {
6115 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, depends_on_compile_var);
6116 } else if (is_slice(container_type)) {
6117 TypeTableEntry *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry;
6118 assert(pointer_type->id == TypeTableEntryIdPointer);
6119 TypeTableEntry *child_type = pointer_type->data.pointer.child_type;
6120
6121 ConstExprValue const_val = {};
6122 const_val.special = ConstValSpecialStatic;
6123 const_val.depends_on_compile_var = depends_on_compile_var;
6124 const_val.data.x_array.elements = allocate<ConstExprValue>(elem_count);
6125 const_val.data.x_array.size = elem_count;
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);
57896225 case IrInstructionIdFieldPtr:
57906226 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction);
57916227 case IrInstructionIdCall:
......@@ -5844,10 +6280,14 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
58446280 return ir_analyze_instruction_array_len(ira, (IrInstructionArrayLen *)instruction);
58456281 case IrInstructionIdRef:
58466282 return ir_analyze_instruction_ref(ira, (IrInstructionRef *)instruction);
5847 case IrInstructionIdCast:
58486283 case IrInstructionIdContainerInitList:
6284 return ir_analyze_instruction_container_init_list(ira, (IrInstructionContainerInitList *)instruction);
58496285 case IrInstructionIdContainerInitFields:
6286 return ir_analyze_instruction_container_init_fields(ira, (IrInstructionContainerInitFields *)instruction);
6287 case IrInstructionIdCast:
58506288 case IrInstructionIdStructFieldPtr:
6289 case IrInstructionIdEnumFieldPtr:
6290 case IrInstructionIdStructInit:
58516291 zig_panic("TODO analyze more instructions");
58526292 }
58536293 zig_unreachable();
......@@ -5947,6 +6387,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
59476387 case IrInstructionIdCast:
59486388 case IrInstructionIdContainerInitList:
59496389 case IrInstructionIdContainerInitFields:
6390 case IrInstructionIdStructInit:
59506391 case IrInstructionIdFieldPtr:
59516392 case IrInstructionIdElemPtr:
59526393 case IrInstructionIdVarPtr:
......@@ -5955,6 +6396,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
59556396 case IrInstructionIdPtrTypeChild:
59566397 case IrInstructionIdArrayLen:
59576398 case IrInstructionIdStructFieldPtr:
6399 case IrInstructionIdEnumFieldPtr:
59586400 case IrInstructionIdArrayType:
59596401 case IrInstructionIdSliceType:
59606402 case IrInstructionIdCompileVar:
......@@ -6393,46 +6835,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
63936835// return g->builtin_types.entry_void;
63946836//}
63956837//
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//
64366838//static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
64376839// TypeTableEntry *expected_type, AstNode *node)
64386840//{
......@@ -6634,713 +7036,10 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
66347036// return analyze_set_fn_test(g, import, context, node);
66357037// case BuiltinFnIdSetFnNoInline:
66367038// return analyze_set_fn_no_inline(g, import, context, node);
6637// case BuiltinFnIdSetFnStaticEval:
6638// return analyze_set_fn_static_eval(g, import, context, node);
66397039// }
66407040// zig_unreachable();
66417041//}
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//}
73447043//static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
73457044// TypeTableEntry *expected_type, AstNode *node)
73467045//{
......@@ -7476,68 +7175,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
74767175// return enum_type;
74777176//}
74787177//
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//}
75417178//
75427179//static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
75437180// AstNode *node)
......@@ -7887,19 +7524,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
78877524// return g->builtin_types.entry_invalid;
78887525//}
78897526//
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//
79037527//static void validate_voided_expr(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry) {
79047528// if (type_entry->id == TypeTableEntryIdMetaType) {
79057529// 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) {
82397863// }
82407864//}
82417865//
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//
83287866//static LLVMValueRef gen_array_base_ptr(CodeGen *g, AstNode *node) {
83297867// TypeTableEntry *type_entry = get_expr_type(node);
83307868//
......@@ -8356,46 +7894,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
83567894// return gen_array_elem_ptr(g, node, array_ptr, array_type, subscript_value);
83577895//}
83587896//
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//
83997897//static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {
84007898// assert(node->type == NodeTypeSliceExpr);
84017899//
......@@ -8771,87 +8269,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
87718269// zig_unreachable();
87728270//}
87738271//
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//
88558272//static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *implicit_return_type) {
88568273// assert(block_node->type == NodeTypeBlock);
88578274//
......@@ -8876,140 +8293,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
88768293// }
88778294//}
88788295//
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
90138296//static LLVMValueRef gen_break(CodeGen *g, AstNode *node) {
90148297// assert(node->type == NodeTypeBreak);
90158298// LLVMBasicBlockRef dest_block = g->break_block_stack.last();
......@@ -9164,44 +8447,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
91648447// }
91658448//}
91668449//
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//
92058450//static LLVMValueRef gen_return(CodeGen *g, AstNode *source_node, LLVMValueRef value, ReturnKnowledge rk) {
92068451// BlockContext *defer_inner_block = source_node->block_context;
92078452// 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 {
77 int indent_size;
88};
99
10static void ir_print_other_instruction(IrPrint *irp, IrInstruction *instruction);
11
1012static void ir_print_indent(IrPrint *irp) {
1113 for (int i = 0; i < irp->indent; i += 1) {
1214 fprintf(irp->f, " ");
......@@ -35,25 +37,30 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
3537 break;
3638 }
3739 switch (type_entry->id) {
40 case TypeTableEntryIdTypeDecl:
41 return ir_print_const_value(irp, type_entry->data.type_decl.canonical_type, const_val);
3842 case TypeTableEntryIdInvalid:
3943 fprintf(irp->f, "(invalid)");
40 break;
44 return;
45 case TypeTableEntryIdVar:
46 fprintf(irp->f, "(var)");
47 return;
4148 case TypeTableEntryIdVoid:
4249 fprintf(irp->f, "{}");
43 break;
50 return;
4451 case TypeTableEntryIdNumLitFloat:
4552 fprintf(irp->f, "%f", const_val->data.x_bignum.data.x_float);
46 break;
53 return;
4754 case TypeTableEntryIdNumLitInt:
4855 {
4956 BigNum *bignum = &const_val->data.x_bignum;
5057 const char *negative_str = bignum->is_negative ? "-" : "";
5158 fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint);
52 break;
59 return;
5360 }
5461 case TypeTableEntryIdMetaType:
5562 fprintf(irp->f, "%s", buf_ptr(&const_val->data.x_type->name));
56 break;
63 return;
5764 case TypeTableEntryIdInt:
5865 {
5966 BigNum *bignum = &const_val->data.x_bignum;
......@@ -61,31 +68,38 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
6168 const char *negative_str = bignum->is_negative ? "-" : "";
6269 fprintf(irp->f, "%s%llu", negative_str, bignum->data.x_uint);
6370 }
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;
6579 case TypeTableEntryIdUnreachable:
6680 fprintf(irp->f, "@unreachable()");
67 break;
81 return;
6882 case TypeTableEntryIdBool:
6983 {
7084 const char *value = const_val->data.x_bool ? "true" : "false";
7185 fprintf(irp->f, "%s", value);
72 break;
86 return;
7387 }
7488 case TypeTableEntryIdPointer:
7589 fprintf(irp->f, "&");
7690 ir_print_const_value(irp, type_entry->data.pointer.child_type, const_ptr_pointee(const_val));
77 break;
91 return;
7892 case TypeTableEntryIdFn:
7993 {
8094 FnTableEntry *fn_entry = const_val->data.x_fn;
8195 fprintf(irp->f, "%s", buf_ptr(&fn_entry->symbol_name));
82 break;
96 return;
8397 }
8498 case TypeTableEntryIdBlock:
8599 {
86100 AstNode *node = const_val->data.x_block->node;
87101 fprintf(irp->f, "(scope:%zu:%zu)", node->line + 1, node->column + 1);
88 break;
102 return;
89103 }
90104 case TypeTableEntryIdArray:
91105 {
......@@ -99,12 +113,17 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
99113 ir_print_const_value(irp, child_type, child_value);
100114 }
101115 fprintf(irp->f, "}");
102 break;
116 return;
103117 }
104118 case TypeTableEntryIdNullLit:
105119 {
106120 fprintf(irp->f, "null");
107 break;
121 return;
122 }
123 case TypeTableEntryIdUndefLit:
124 {
125 fprintf(irp->f, "undefined");
126 return;
108127 }
109128 case TypeTableEntryIdMaybe:
110129 {
......@@ -113,26 +132,56 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
113132 } else {
114133 fprintf(irp->f, "null");
115134 }
116 break;
135 return;
117136 }
118137 case TypeTableEntryIdNamespace:
119138 {
120139 ImportTableEntry *import = const_val->data.x_import;
121140 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;
123157 }
124 case TypeTableEntryIdVar:
125 case TypeTableEntryIdFloat:
126158 case TypeTableEntryIdStruct:
127 case TypeTableEntryIdUndefLit:
128 case TypeTableEntryIdErrorUnion:
129 case TypeTableEntryIdPureError:
159 {
160 fprintf(irp->f, "(struct %s constant)", buf_ptr(&type_entry->name));
161 return;
162 }
130163 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 }
131173 case TypeTableEntryIdUnion:
132 case TypeTableEntryIdTypeDecl:
133 case TypeTableEntryIdGenericFn:
134 zig_panic("TODO render more constant types in IR printer");
174 {
175 fprintf(irp->f, "(union %s constant)", buf_ptr(&type_entry->name));
176 return;
177 }
178 case TypeTableEntryIdPureError:
179 {
180 fprintf(irp->f, "(pure error constant)");
181 return;
182 }
135183 }
184 zig_unreachable();
136185}
137186
138187static 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
285334static void ir_print_cast(IrPrint *irp, IrInstructionCast *cast_instruction) {
286335 fprintf(irp->f, "cast ");
287336 ir_print_other_instruction(irp, cast_instruction->value);
288 fprintf(irp->f, " to ");
289 ir_print_other_instruction(irp, cast_instruction->dest_type);
337 fprintf(irp->f, " to %s", buf_ptr(&cast_instruction->dest_type->name));
290338}
291339
292340static 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 }
294347 fprintf(irp->f, "(");
295348 for (size_t i = 0; i < call_instruction->arg_count; i += 1) {
296349 IrInstruction *arg = call_instruction->args[i];
......@@ -347,13 +400,24 @@ static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerI
347400 ir_print_other_instruction(irp, instruction->container_type);
348401 fprintf(irp->f, "{");
349402 for (size_t i = 0; i < instruction->field_count; i += 1) {
350 Buf *name = instruction->field_names[i];
351 IrInstruction *field_value = instruction->field_values[i];
403 IrInstructionContainerInitFieldsField *field = &instruction->fields[i];
352404 const char *comma = (i == 0) ? "" : ", ";
353 fprintf(irp->f, "%s.%s = ", comma, buf_ptr(name));
354 ir_print_other_instruction(irp, field_value);
405 fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field->name));
406 ir_print_other_instruction(irp, field->value);
355407 }
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");
357421}
358422
359423static void ir_print_unreachable(IrPrint *irp, IrInstructionUnreachable *instruction) {
......@@ -406,10 +470,9 @@ static void ir_print_ptr_type_child(IrPrint *irp, IrInstructionPtrTypeChild *ins
406470}
407471
408472static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction) {
409 fprintf(irp->f, "@FieldPtr(&");
473 fprintf(irp->f, "fieldptr ");
410474 ir_print_other_instruction(irp, instruction->container_ptr);
411475 fprintf(irp->f, ".%s", buf_ptr(instruction->field_name));
412 fprintf(irp->f, ")");
413476}
414477
415478static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr *instruction) {
......@@ -419,6 +482,13 @@ static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr
419482 fprintf(irp->f, ")");
420483}
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
422492static void ir_print_set_fn_test(IrPrint *irp, IrInstructionSetFnTest *instruction) {
423493 fprintf(irp->f, "@setFnTest(");
424494 ir_print_other_instruction(irp, instruction->fn_value);
......@@ -632,6 +702,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
632702 case IrInstructionIdContainerInitFields:
633703 ir_print_container_init_fields(irp, (IrInstructionContainerInitFields *)instruction);
634704 break;
705 case IrInstructionIdStructInit:
706 ir_print_struct_init(irp, (IrInstructionStructInit *)instruction);
707 break;
635708 case IrInstructionIdUnreachable:
636709 ir_print_unreachable(irp, (IrInstructionUnreachable *)instruction);
637710 break;
......@@ -662,6 +735,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
662735 case IrInstructionIdStructFieldPtr:
663736 ir_print_struct_field_ptr(irp, (IrInstructionStructFieldPtr *)instruction);
664737 break;
738 case IrInstructionIdEnumFieldPtr:
739 ir_print_enum_field_ptr(irp, (IrInstructionEnumFieldPtr *)instruction);
740 break;
665741 case IrInstructionIdSetFnTest:
666742 ir_print_set_fn_test(irp, (IrInstructionSetFnTest *)instruction);
667743 break;
test/self_hosted2.zig+13
......@@ -84,6 +84,18 @@ end:
8484}
8585var 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
8799fn assert(ok: bool) {
88100 if (!ok)
89101 @unreachable();
......@@ -98,6 +110,7 @@ fn runAllTests() {
98110 testInlineSwitch();
99111 testNamespaceFnCall();
100112 gotoAndLabels();
113 testStructStatic();
101114}
102115
103116export nakedcc fn _start() -> unreachable {