authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-26 20:52:22-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-11-26 20:52:22-05:00
log84f7805029e6a272f51bfa106cc40081a8581823
tree74b0f0c1c3550fa3f9371986c3f7fa46e531ab68
parent4619b5de0609e98c0c98fe352f3bc32f036b6ad4

IR: support import builtin function


9 files changed, 417 insertions(+), 1080 deletions(-)

src/all_types.hpp+15-56
......@@ -117,12 +117,6 @@ enum ReturnKnowledge {
117117 ReturnKnowledgeSkipDefers,
118118};
119119
120struct Expr {
121 IrInstruction *instruction;
122 ReturnKnowledge return_knowledge;
123 VariableTableEntry *variable;
124};
125
126120struct StructValExprCodeGen {
127121 TypeTableEntry *type_entry;
128122 LLVMValueRef ptr;
......@@ -152,6 +146,7 @@ struct TopLevelDecl {
152146 bool dep_loop_flag;
153147 TldResolution resolution;
154148 AstNode *parent_decl;
149 IrInstruction *value;
155150};
156151
157152struct TypeEnumField {
......@@ -232,7 +227,6 @@ struct AstNodeFnProto {
232227 AstNode *fn_def_node;
233228 FnTableEntry *fn_table_entry;
234229 bool skip;
235 Expr resolved_expr;
236230 // computed from params field
237231 size_t inline_arg_count;
238232 size_t inline_or_var_type_arg_count;
......@@ -274,7 +268,6 @@ struct AstNodeBlock {
274268 // you can follow its parents up to child_block. it will equal
275269 // child_block if there are no defers or var decls in the block.
276270 BlockContext *nested_block;
277 Expr resolved_expr;
278271};
279272
280273enum ReturnKind {
......@@ -287,9 +280,6 @@ struct AstNodeReturnExpr {
287280 ReturnKind kind;
288281 // might be null in case of return void;
289282 AstNode *expr;
290
291 // populated by semantic analyzer:
292 Expr resolved_expr;
293283};
294284
295285struct AstNodeDefer {
......@@ -297,7 +287,6 @@ struct AstNodeDefer {
297287 AstNode *expr;
298288
299289 // populated by semantic analyzer:
300 Expr resolved_expr;
301290 size_t index_in_block;
302291 LLVMBasicBlockRef basic_block;
303292 BlockContext *child_block;
......@@ -314,7 +303,6 @@ struct AstNodeVariableDeclaration {
314303 AstNode *expr;
315304
316305 // populated by semantic analyzer
317 Expr resolved_expr;
318306 VariableTableEntry *variable;
319307};
320308
......@@ -392,7 +380,6 @@ struct AstNodeBinOpExpr {
392380 // populated by semantic analyzer:
393381 // for when op is BinOpTypeAssign
394382 VariableTableEntry *var_entry;
395 Expr resolved_expr;
396383};
397384
398385struct AstNodeUnwrapErrorExpr {
......@@ -401,7 +388,6 @@ struct AstNodeUnwrapErrorExpr {
401388 AstNode *op2;
402389
403390 // populated by semantic analyzer:
404 Expr resolved_expr;
405391 VariableTableEntry *var;
406392};
407393
......@@ -434,7 +420,6 @@ struct AstNodeFnCallExpr {
434420
435421 // populated by semantic analyzer:
436422 BuiltinFnEntry *builtin_fn;
437 Expr resolved_expr;
438423 FnTableEntry *fn_entry;
439424 CastOp cast_op;
440425 // if cast_op is CastOpArrayToString, this will be a pointer to
......@@ -447,7 +432,6 @@ struct AstNodeArrayAccessExpr {
447432 AstNode *subscript;
448433
449434 // populated by semantic analyzer:
450 Expr resolved_expr;
451435};
452436
453437struct AstNodeSliceExpr {
......@@ -457,7 +441,6 @@ struct AstNodeSliceExpr {
457441 bool is_const;
458442
459443 // populated by semantic analyzer:
460 Expr resolved_expr;
461444 StructValExprCodeGen resolved_struct_val_expr;
462445};
463446
......@@ -468,7 +451,6 @@ struct AstNodeFieldAccessExpr {
468451 // populated by semantic analyzer
469452 TypeStructField *type_struct_field;
470453 TypeEnumField *type_enum_field;
471 Expr resolved_expr;
472454 StructValExprCodeGen resolved_struct_val_expr; // for enum values
473455 TypeTableEntry *bare_container_type;
474456 bool is_member_fn;
......@@ -495,7 +477,6 @@ struct AstNodePrefixOpExpr {
495477 AstNode *primary_expr;
496478
497479 // populated by semantic analyzer
498 Expr resolved_expr;
499480};
500481
501482struct AstNodeUse {
......@@ -511,7 +492,6 @@ struct AstNodeIfBoolExpr {
511492 AstNode *else_node; // null, block node, or other if expr node
512493
513494 // populated by semantic analyzer
514 Expr resolved_expr;
515495};
516496
517497struct AstNodeIfVarExpr {
......@@ -522,7 +502,6 @@ struct AstNodeIfVarExpr {
522502
523503 // populated by semantic analyzer
524504 TypeTableEntry *type;
525 Expr resolved_expr;
526505};
527506
528507struct AstNodeWhileExpr {
......@@ -535,7 +514,6 @@ struct AstNodeWhileExpr {
535514 bool condition_always_true;
536515 bool contains_break;
537516 bool contains_continue;
538 Expr resolved_expr;
539517};
540518
541519struct AstNodeForExpr {
......@@ -549,7 +527,6 @@ struct AstNodeForExpr {
549527 // populated by semantic analyzer
550528 bool contains_break;
551529 bool contains_continue;
552 Expr resolved_expr;
553530 VariableTableEntry *elem_var;
554531 VariableTableEntry *index_var;
555532};
......@@ -560,7 +537,6 @@ struct AstNodeSwitchExpr {
560537 bool is_inline;
561538
562539 // populated by semantic analyzer
563 Expr resolved_expr;
564540};
565541
566542struct AstNodeSwitchProng {
......@@ -580,7 +556,6 @@ struct AstNodeLabel {
580556 Buf *name;
581557
582558 // populated by semantic analyzer
583 Expr resolved_expr;
584559 LabelTableEntry *label_entry;
585560};
586561
......@@ -588,7 +563,6 @@ struct AstNodeGoto {
588563 Buf *name;
589564
590565 // populated by semantic analyzer
591 Expr resolved_expr;
592566 LabelTableEntry *label_entry;
593567};
594568
......@@ -634,7 +608,6 @@ struct AstNodeAsmExpr {
634608 ZigList<Buf*> clobber_list;
635609
636610 // populated by semantic analyzer
637 Expr resolved_expr;
638611};
639612
640613enum ContainerKind {
......@@ -670,14 +643,12 @@ struct AstNodeStringLiteral {
670643 bool c;
671644
672645 // populated by semantic analyzer:
673 Expr resolved_expr;
674646};
675647
676648struct AstNodeCharLiteral {
677649 uint8_t value;
678650
679651 // populated by semantic analyzer:
680 Expr resolved_expr;
681652};
682653
683654struct AstNodeNumberLiteral {
......@@ -688,7 +659,6 @@ struct AstNodeNumberLiteral {
688659 bool overflow;
689660
690661 // populated by semantic analyzer
691 Expr resolved_expr;
692662};
693663
694664struct AstNodeStructValueField {
......@@ -711,35 +681,29 @@ struct AstNodeContainerInitExpr {
711681
712682 // populated by semantic analyzer
713683 StructValExprCodeGen resolved_struct_val_expr;
714 Expr resolved_expr;
715684 TypeTableEntry *enum_type;
716685};
717686
718687struct AstNodeNullLiteral {
719688 // populated by semantic analyzer
720 Expr resolved_expr;
721689};
722690
723691struct AstNodeUndefinedLiteral {
724692 // populated by semantic analyzer
725 Expr resolved_expr;
726693};
727694
728695struct AstNodeZeroesLiteral {
729696 // populated by semantic analyzer
730 Expr resolved_expr;
731697};
732698
733699struct AstNodeThisLiteral {
734700 // populated by semantic analyzer
735 Expr resolved_expr;
736701};
737702
738703struct AstNodeSymbolExpr {
739704 Buf *symbol;
740705
741706 // populated by semantic analyzer
742 Expr resolved_expr;
743707 TypeEnumField *enum_field;
744708 uint32_t err_value;
745709};
......@@ -748,17 +712,14 @@ struct AstNodeBoolLiteral {
748712 bool value;
749713
750714 // populated by semantic analyzer
751 Expr resolved_expr;
752715};
753716
754717struct AstNodeBreakExpr {
755718 // populated by semantic analyzer
756 Expr resolved_expr;
757719};
758720
759721struct AstNodeContinueExpr {
760722 // populated by semantic analyzer
761 Expr resolved_expr;
762723};
763724
764725struct AstNodeArrayType {
......@@ -767,22 +728,18 @@ struct AstNodeArrayType {
767728 bool is_const;
768729
769730 // populated by semantic analyzer
770 Expr resolved_expr;
771731};
772732
773733struct AstNodeErrorType {
774734 // populated by semantic analyzer
775 Expr resolved_expr;
776735};
777736
778737struct AstNodeTypeLiteral {
779738 // populated by semantic analyzer
780 Expr resolved_expr;
781739};
782740
783741struct AstNodeVarLiteral {
784742 // populated by semantic analyzer
785 Expr resolved_expr;
786743};
787744
788745struct AstNode {
......@@ -1329,7 +1286,6 @@ struct CodeGen {
13291286 LLVMValueRef err_name_table;
13301287
13311288 IrInstruction *invalid_instruction;
1332 Buf *len_buf;
13331289};
13341290
13351291struct VariableTableEntry {
......@@ -1389,9 +1345,6 @@ struct BlockContext {
13891345 ZigLLVMDIScope *di_scope;
13901346 Buf *c_import_buf;
13911347
1392 // if this is true, then this code will not be generated
1393 bool codegen_excluded;
1394
13951348 bool safety_off;
13961349 AstNode *safety_set_node;
13971350};
......@@ -1433,7 +1386,6 @@ enum IrInstructionId {
14331386 IrInstructionIdStorePtr,
14341387 IrInstructionIdFieldPtr,
14351388 IrInstructionIdStructFieldPtr,
1436 IrInstructionIdReadField,
14371389 IrInstructionIdElemPtr,
14381390 IrInstructionIdVarPtr,
14391391 IrInstructionIdCall,
......@@ -1460,6 +1412,8 @@ enum IrInstructionId {
14601412 IrInstructionIdClz,
14611413 IrInstructionIdCtz,
14621414 IrInstructionIdStaticEval,
1415 IrInstructionIdImport,
1416 IrInstructionIdArrayLen,
14631417};
14641418
14651419struct IrInstruction {
......@@ -1628,13 +1582,6 @@ struct IrInstructionStructFieldPtr {
16281582 bool is_const;
16291583};
16301584
1631struct IrInstructionReadField {
1632 IrInstruction base;
1633
1634 IrInstruction *container_ptr;
1635 Buf *field_name;
1636};
1637
16381585struct IrInstructionElemPtr {
16391586 IrInstruction base;
16401587
......@@ -1816,6 +1763,18 @@ struct IrInstructionStaticEval {
18161763 IrInstruction *value;
18171764};
18181765
1766struct IrInstructionImport {
1767 IrInstruction base;
1768
1769 IrInstruction *name;
1770};
1771
1772struct IrInstructionArrayLen {
1773 IrInstruction base;
1774
1775 IrInstruction *array_value;
1776};
1777
18191778enum LValPurpose {
18201779 LValPurposeNone,
18211780 LValPurposeAssign,
src/analyze.cpp+40-135
......@@ -19,7 +19,6 @@
1919
2020static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type);
2121static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type);
22static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node);
2322
2423AstNode *first_executing_node(AstNode *node) {
2524 switch (node->type) {
......@@ -1670,7 +1669,7 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {
16701669 node->data.error_value_decl.top_level_decl.resolution = TldResolutionOk;
16711670}
16721671
1673static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node) {
1672void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node) {
16741673 switch (node->type) {
16751674 case NodeTypeRoot:
16761675 for (size_t i = 0; i < import->root->data.root.top_level_decls.length; i += 1) {
......@@ -1947,9 +1946,8 @@ static void resolve_var_decl(CodeGen *g, ImportTableEntry *import, AstNode *node
19471946 implicit_type = g->builtin_types.entry_invalid;
19481947 }
19491948 if (implicit_type->id != TypeTableEntryIdInvalid) {
1950 Expr *expr = get_resolved_expr(var_decl->expr);
19511949 assert(result->static_value.special != ConstValSpecialRuntime);
1952 expr->instruction = result;
1950 var_decl->top_level_decl.value = result;
19531951 }
19541952 } else if (!is_extern) {
19551953 add_node_error(g, node, buf_sprintf("variables must be initialized"));
......@@ -2206,7 +2204,6 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
22062204 if (parent) {
22072205 context->parent_loop_node = parent->parent_loop_node;
22082206 context->c_import_buf = parent->c_import_buf;
2209 context->codegen_excluded = parent->codegen_excluded;
22102207 }
22112208
22122209 if (node && node->type == NodeTypeFnDef) {
......@@ -2455,17 +2452,16 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
24552452
24562453static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node) {
24572454 TopLevelDecl *tld = get_as_top_level_decl(dst_use_node);
2458 AstNode *use_target_node = src_use_node->data.use.expr;
2459 Expr *expr = get_resolved_expr(use_target_node);
24602455
2461 if (expr->instruction->type_entry->id == TypeTableEntryIdInvalid) {
2456 IrInstruction *use_target_value = tld->value;
2457 if (use_target_value->type_entry->id == TypeTableEntryIdInvalid) {
24622458 tld->import->any_imports_failed = true;
24632459 return;
24642460 }
24652461
24662462 tld->resolution = TldResolutionOk;
24672463
2468 ConstExprValue *const_val = &expr->instruction->static_value;
2464 ConstExprValue *const_val = &use_target_value->static_value;
24692465 assert(const_val->special != ConstValSpecialRuntime);
24702466
24712467 ImportTableEntry *target_import = const_val->data.x_import;
......@@ -2511,7 +2507,7 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
25112507
25122508}
25132509
2514static void resolve_use_decl(CodeGen *g, AstNode *node) {
2510void resolve_use_decl(CodeGen *g, AstNode *node) {
25152511 assert(node->type == NodeTypeUse);
25162512 if (get_as_top_level_decl(node)->resolution != TldResolutionUnresolved) {
25172513 return;
......@@ -2519,7 +2515,7 @@ static void resolve_use_decl(CodeGen *g, AstNode *node) {
25192515 add_symbols_from_import(g, node, node);
25202516}
25212517
2522static void preview_use_decl(CodeGen *g, AstNode *node) {
2518void preview_use_decl(CodeGen *g, AstNode *node) {
25232519 assert(node->type == NodeTypeUse);
25242520 TopLevelDecl *tld = get_as_top_level_decl(node);
25252521
......@@ -2637,97 +2633,6 @@ void semantic_analyze(CodeGen *g) {
26372633 }
26382634}
26392635
2640Expr *get_resolved_expr(AstNode *node) {
2641 switch (node->type) {
2642 case NodeTypeReturnExpr:
2643 return &node->data.return_expr.resolved_expr;
2644 case NodeTypeDefer:
2645 return &node->data.defer.resolved_expr;
2646 case NodeTypeBinOpExpr:
2647 return &node->data.bin_op_expr.resolved_expr;
2648 case NodeTypeUnwrapErrorExpr:
2649 return &node->data.unwrap_err_expr.resolved_expr;
2650 case NodeTypePrefixOpExpr:
2651 return &node->data.prefix_op_expr.resolved_expr;
2652 case NodeTypeFnCallExpr:
2653 return &node->data.fn_call_expr.resolved_expr;
2654 case NodeTypeArrayAccessExpr:
2655 return &node->data.array_access_expr.resolved_expr;
2656 case NodeTypeSliceExpr:
2657 return &node->data.slice_expr.resolved_expr;
2658 case NodeTypeFieldAccessExpr:
2659 return &node->data.field_access_expr.resolved_expr;
2660 case NodeTypeIfBoolExpr:
2661 return &node->data.if_bool_expr.resolved_expr;
2662 case NodeTypeIfVarExpr:
2663 return &node->data.if_var_expr.resolved_expr;
2664 case NodeTypeWhileExpr:
2665 return &node->data.while_expr.resolved_expr;
2666 case NodeTypeForExpr:
2667 return &node->data.for_expr.resolved_expr;
2668 case NodeTypeAsmExpr:
2669 return &node->data.asm_expr.resolved_expr;
2670 case NodeTypeContainerInitExpr:
2671 return &node->data.container_init_expr.resolved_expr;
2672 case NodeTypeNumberLiteral:
2673 return &node->data.number_literal.resolved_expr;
2674 case NodeTypeStringLiteral:
2675 return &node->data.string_literal.resolved_expr;
2676 case NodeTypeBlock:
2677 return &node->data.block.resolved_expr;
2678 case NodeTypeSymbol:
2679 return &node->data.symbol_expr.resolved_expr;
2680 case NodeTypeVariableDeclaration:
2681 return &node->data.variable_declaration.resolved_expr;
2682 case NodeTypeCharLiteral:
2683 return &node->data.char_literal.resolved_expr;
2684 case NodeTypeBoolLiteral:
2685 return &node->data.bool_literal.resolved_expr;
2686 case NodeTypeNullLiteral:
2687 return &node->data.null_literal.resolved_expr;
2688 case NodeTypeUndefinedLiteral:
2689 return &node->data.undefined_literal.resolved_expr;
2690 case NodeTypeZeroesLiteral:
2691 return &node->data.zeroes_literal.resolved_expr;
2692 case NodeTypeThisLiteral:
2693 return &node->data.this_literal.resolved_expr;
2694 case NodeTypeGoto:
2695 return &node->data.goto_expr.resolved_expr;
2696 case NodeTypeBreak:
2697 return &node->data.break_expr.resolved_expr;
2698 case NodeTypeContinue:
2699 return &node->data.continue_expr.resolved_expr;
2700 case NodeTypeLabel:
2701 return &node->data.label.resolved_expr;
2702 case NodeTypeArrayType:
2703 return &node->data.array_type.resolved_expr;
2704 case NodeTypeErrorType:
2705 return &node->data.error_type.resolved_expr;
2706 case NodeTypeTypeLiteral:
2707 return &node->data.type_literal.resolved_expr;
2708 case NodeTypeSwitchExpr:
2709 return &node->data.switch_expr.resolved_expr;
2710 case NodeTypeFnProto:
2711 return &node->data.fn_proto.resolved_expr;
2712 case NodeTypeVarLiteral:
2713 return &node->data.var_literal.resolved_expr;
2714 case NodeTypeSwitchProng:
2715 case NodeTypeSwitchRange:
2716 case NodeTypeRoot:
2717 case NodeTypeFnDef:
2718 case NodeTypeFnDecl:
2719 case NodeTypeParamDecl:
2720 case NodeTypeUse:
2721 case NodeTypeContainerDecl:
2722 case NodeTypeStructField:
2723 case NodeTypeStructValueField:
2724 case NodeTypeErrorValueDecl:
2725 case NodeTypeTypeDecl:
2726 zig_unreachable();
2727 }
2728 zig_unreachable();
2729}
2730
27312636TopLevelDecl *get_as_top_level_decl(AstNode *node) {
27322637 switch (node->type) {
27332638 case NodeTypeVariableDeclaration:
......@@ -2997,40 +2902,42 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)
29972902}
29982903
29992904uint32_t generic_fn_type_id_hash(GenericFnTypeId *id) {
3000 uint32_t result = 0;
3001 result += hash_ptr(id->decl_node);
3002 for (size_t i = 0; i < id->generic_param_count; i += 1) {
3003 GenericParamValue *generic_param = &id->generic_params[i];
3004 if (generic_param->node) {
3005 ConstExprValue *const_val = &get_resolved_expr(generic_param->node)->instruction->static_value;
3006 assert(const_val->special != ConstValSpecialRuntime);
3007 result += hash_const_val(generic_param->type, const_val);
3008 }
3009 result += hash_ptr(generic_param->type);
3010 }
3011 return result;
2905 zig_panic("TODO generic_fn_type_id_hash");
2906 //uint32_t result = 0;
2907 //result += hash_ptr(id->decl_node);
2908 //for (size_t i = 0; i < id->generic_param_count; i += 1) {
2909 // GenericParamValue *generic_param = &id->generic_params[i];
2910 // if (generic_param->node) {
2911 // ConstExprValue *const_val = &get_resolved_expr(generic_param->node)->instruction->static_value;
2912 // assert(const_val->special != ConstValSpecialRuntime);
2913 // result += hash_const_val(generic_param->type, const_val);
2914 // }
2915 // result += hash_ptr(generic_param->type);
2916 //}
2917 //return result;
30122918}
30132919
30142920bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) {
3015 if (a->decl_node != b->decl_node) return false;
3016 assert(a->generic_param_count == b->generic_param_count);
3017 for (size_t i = 0; i < a->generic_param_count; i += 1) {
3018 GenericParamValue *a_val = &a->generic_params[i];
3019 GenericParamValue *b_val = &b->generic_params[i];
3020 if (a_val->type != b_val->type) return false;
3021 if (a_val->node && b_val->node) {
3022 ConstExprValue *a_const_val = &get_resolved_expr(a_val->node)->instruction->static_value;
3023 ConstExprValue *b_const_val = &get_resolved_expr(b_val->node)->instruction->static_value;
3024 assert(a_const_val->special != ConstValSpecialRuntime);
3025 assert(b_const_val->special != ConstValSpecialRuntime);
3026 if (!const_values_equal(a_const_val, b_const_val, a_val->type)) {
3027 return false;
3028 }
3029 } else {
3030 assert(!a_val->node && !b_val->node);
3031 }
3032 }
3033 return true;
2921 zig_panic("TODO generic_fn_type_id_eql");
2922 //if (a->decl_node != b->decl_node) return false;
2923 //assert(a->generic_param_count == b->generic_param_count);
2924 //for (size_t i = 0; i < a->generic_param_count; i += 1) {
2925 // GenericParamValue *a_val = &a->generic_params[i];
2926 // GenericParamValue *b_val = &b->generic_params[i];
2927 // if (a_val->type != b_val->type) return false;
2928 // if (a_val->node && b_val->node) {
2929 // ConstExprValue *a_const_val = &get_resolved_expr(a_val->node)->instruction->static_value;
2930 // ConstExprValue *b_const_val = &get_resolved_expr(b_val->node)->instruction->static_value;
2931 // assert(a_const_val->special != ConstValSpecialRuntime);
2932 // assert(b_const_val->special != ConstValSpecialRuntime);
2933 // if (!const_values_equal(a_const_val, b_const_val, a_val->type)) {
2934 // return false;
2935 // }
2936 // } else {
2937 // assert(!a_val->node && !b_val->node);
2938 // }
2939 //}
2940 //return true;
30342941}
30352942
30362943bool type_has_bits(TypeTableEntry *type_entry) {
......@@ -3095,5 +3002,3 @@ uint64_t get_memcpy_align(CodeGen *g, TypeTableEntry *type_entry) {
30953002 TypeTableEntry *first_type_in_mem = type_of_first_thing_in_memory(type_entry);
30963003 return LLVMABISizeOfType(g->target_data_ref, first_type_in_mem->type_ref);
30973004}
3098
3099
src/analyze.hpp+3-1
......@@ -16,7 +16,6 @@ ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *m
1616TypeTableEntry *new_type_table_entry(TypeTableEntryId id);
1717TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
1818BlockContext *new_block_context(AstNode *node, BlockContext *parent);
19Expr *get_resolved_expr(AstNode *node);
2019bool is_node_void_expr(AstNode *node);
2120uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);
2221TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, size_t size_in_bits);
......@@ -63,5 +62,8 @@ TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name);
6362BlockContext *get_container_block_context(TypeTableEntry *type_entry);
6463TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name);
6564bool is_container_ref(TypeTableEntry *type_entry);
65void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node);
66void preview_use_decl(CodeGen *g, AstNode *node);
67void resolve_use_decl(CodeGen *g, AstNode *node);
6668
6769#endif
src/ast_render.cpp+15-16
......@@ -528,25 +528,24 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
528528 break;
529529 }
530530 case NodeTypeFnCallExpr:
531 if (node->data.fn_call_expr.is_builtin) {
532 fprintf(ar->f, "@");
533 } else {
531 {
532 if (node->data.fn_call_expr.is_builtin) {
533 fprintf(ar->f, "@");
534 }
535 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
536 bool grouped = (fn_ref_node->type != NodeTypeBinOpExpr);
537 render_node_extra(ar, fn_ref_node, grouped);
534538 fprintf(ar->f, "(");
535 }
536 render_node_ungrouped(ar, node->data.fn_call_expr.fn_ref_expr);
537 if (!node->data.fn_call_expr.is_builtin) {
538 fprintf(ar->f, ")");
539 }
540 fprintf(ar->f, "(");
541 for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
542 AstNode *param = node->data.fn_call_expr.params.at(i);
543 if (i != 0) {
544 fprintf(ar->f, ", ");
539 for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
540 AstNode *param = node->data.fn_call_expr.params.at(i);
541 if (i != 0) {
542 fprintf(ar->f, ", ");
543 }
544 render_node_grouped(ar, param);
545545 }
546 render_node_grouped(ar, param);
546 fprintf(ar->f, ")");
547 break;
547548 }
548 fprintf(ar->f, ")");
549 break;
550549 case NodeTypeArrayAccessExpr:
551550 render_node_ungrouped(ar, node->data.array_access_expr.array_ref_expr);
552551 fprintf(ar->f, "[");
src/codegen.cpp+5-7
......@@ -65,8 +65,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
6565 g->is_test_build = false;
6666 g->want_h_file = true;
6767
68 g->len_buf = buf_create_from_str("len");
69
7068 // the error.Ok value
7169 g->error_decls.append(nullptr);
7270
......@@ -1682,6 +1680,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
16821680 case IrInstructionIdSizeOf:
16831681 case IrInstructionIdSwitchTarget:
16841682 case IrInstructionIdStaticEval:
1683 case IrInstructionIdImport:
16851684 zig_unreachable();
16861685 case IrInstructionIdReturn:
16871686 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
......@@ -1728,8 +1727,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
17281727 case IrInstructionIdSwitchVar:
17291728 case IrInstructionIdContainerInitList:
17301729 case IrInstructionIdContainerInitFields:
1731 case IrInstructionIdReadField:
17321730 case IrInstructionIdEnumTag:
1731 case IrInstructionIdArrayLen:
17331732 zig_panic("TODO render more IR instructions to LLVM");
17341733 }
17351734 zig_unreachable();
......@@ -2114,7 +2113,7 @@ static void do_code_gen(CodeGen *g) {
21142113
21152114 if (var->type->id == TypeTableEntryIdNumLitFloat) {
21162115 // Generate debug info for it but that's it.
2117 ConstExprValue *const_val = &get_resolved_expr(var->val_node)->instruction->static_value;
2116 ConstExprValue *const_val = &var->decl_node->data.variable_declaration.top_level_decl.value->static_value;
21182117 assert(const_val->special != ConstValSpecialRuntime);
21192118 TypeTableEntry *var_type = g->builtin_types.entry_f64;
21202119 LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float);
......@@ -2124,7 +2123,7 @@ static void do_code_gen(CodeGen *g) {
21242123
21252124 if (var->type->id == TypeTableEntryIdNumLitInt) {
21262125 // Generate debug info for it but that's it.
2127 ConstExprValue *const_val = &get_resolved_expr(var->val_node)->instruction->static_value;
2126 ConstExprValue *const_val = &var->decl_node->data.variable_declaration.top_level_decl.value->static_value;
21282127 assert(const_val->special != ConstValSpecialRuntime);
21292128 TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?
21302129 g->builtin_types.entry_isize : g->builtin_types.entry_usize;
......@@ -2149,8 +2148,7 @@ static void do_code_gen(CodeGen *g) {
21492148
21502149 LLVMSetLinkage(global_value, LLVMExternalLinkage);
21512150 } else {
2152 AstNode *expr_node = var->decl_node->data.variable_declaration.expr;
2153 IrInstruction *instruction = get_resolved_expr(expr_node)->instruction;
2151 IrInstruction *instruction = var->decl_node->data.variable_declaration.top_level_decl.value;
21542152 render_const_val(g, instruction->type_entry, &instruction->static_value);
21552153 render_const_val_global(g, instruction->type_entry, &instruction->static_value);
21562154 global_value = instruction->static_value.llvm_global;
src/ir.cpp+308-856
......@@ -3,6 +3,7 @@
33#include "eval.hpp"
44#include "ir.hpp"
55#include "ir_print.hpp"
6#include "os.hpp"
67
78struct IrExecContext {
89 ConstExprValue *mem_slot_list;
......@@ -159,10 +160,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr *
159160 return IrInstructionIdStructFieldPtr;
160161}
161162
162static constexpr IrInstructionId ir_instruction_id(IrInstructionReadField *) {
163 return IrInstructionIdReadField;
164}
165
166163static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) {
167164 return IrInstructionIdElemPtr;
168165}
......@@ -267,6 +264,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStaticEval *) {
267264 return IrInstructionIdStaticEval;
268265}
269266
267static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) {
268 return IrInstructionIdImport;
269}
270
271static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayLen *) {
272 return IrInstructionIdArrayLen;
273}
274
270275template<typename T>
271276static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) {
272277 T *special_instruction = allocate<T>(1);
......@@ -565,18 +570,6 @@ static IrInstruction *ir_build_field_ptr(IrBuilder *irb, AstNode *source_node,
565570 return &instruction->base;
566571}
567572
568static IrInstruction *ir_build_read_field(IrBuilder *irb, AstNode *source_node,
569 IrInstruction *container_ptr, Buf *field_name)
570{
571 IrInstructionReadField *instruction = ir_build_instruction<IrInstructionReadField>(irb, source_node);
572 instruction->container_ptr = container_ptr;
573 instruction->field_name = field_name;
574
575 ir_ref_instruction(container_ptr);
576
577 return &instruction->base;
578}
579
580573static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, AstNode *source_node,
581574 IrInstruction *struct_ptr, TypeStructField *field)
582575{
......@@ -1087,6 +1080,32 @@ static IrInstruction *ir_build_static_eval(IrBuilder *irb, AstNode *source_node,
10871080 return &instruction->base;
10881081}
10891082
1083static IrInstruction *ir_build_import(IrBuilder *irb, AstNode *source_node, IrInstruction *name) {
1084 IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, source_node);
1085 instruction->name = name;
1086
1087 ir_ref_instruction(name);
1088
1089 return &instruction->base;
1090}
1091
1092static IrInstruction *ir_build_array_len(IrBuilder *irb, AstNode *source_node, IrInstruction *array_value) {
1093 IrInstructionArrayLen *instruction = ir_build_instruction<IrInstructionArrayLen>(irb, source_node);
1094 instruction->array_value = array_value;
1095
1096 ir_ref_instruction(array_value);
1097
1098 return &instruction->base;
1099}
1100
1101static IrInstruction *ir_build_array_len_from(IrBuilder *irb, IrInstruction *old_instruction,
1102 IrInstruction *array_value)
1103{
1104 IrInstruction *new_instruction = ir_build_array_len(irb, old_instruction->source_node, array_value);
1105 ir_link_new_instruction(new_instruction, old_instruction);
1106 return new_instruction;
1107}
1108
10901109static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block,
10911110 bool gen_error_defers, bool gen_maybe_defers)
10921111{
......@@ -1376,7 +1395,7 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, AstNode *node) {
13761395static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstNode *decl_node,
13771396 LValPurpose lval, BlockContext *scope)
13781397{
1379 resolve_top_level_decl(irb->codegen, decl_node, lval);
1398 resolve_top_level_decl(irb->codegen, decl_node, lval != LValPurposeNone);
13801399 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
13811400 if (tld->resolution == TldResolutionInvalid)
13821401 return irb->codegen->invalid_instruction;
......@@ -1492,15 +1511,16 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, AstNode *node, LValPur
14921511 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
14931512 Buf *field_name = node->data.field_access_expr.field_name;
14941513
1495 IrInstruction *container_ref_instruction = ir_gen_node(irb, container_ref_node, node->block_context);
1514 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, node->block_context,
1515 LValPurposeAddressOf);
14961516 if (container_ref_instruction == irb->codegen->invalid_instruction)
14971517 return container_ref_instruction;
14981518
1499 if (lval == LValPurposeNone) {
1500 return ir_build_read_field(irb, node, container_ref_instruction, field_name);
1501 } else {
1502 return ir_build_field_ptr(irb, node, container_ref_instruction, field_name);
1503 }
1519 IrInstruction *ptr_instruction = ir_build_field_ptr(irb, node, container_ref_instruction, field_name);
1520 if (lval != LValPurposeNone)
1521 return ptr_instruction;
1522
1523 return ir_build_load_ptr(irb, node, ptr_instruction);
15041524}
15051525
15061526static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
......@@ -1628,6 +1648,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
16281648
16291649 return ir_build_static_eval(irb, node, arg0_value);
16301650 }
1651 case BuiltinFnIdImport:
1652 {
1653 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
1654 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context);
1655 if (arg0_value == irb->codegen->invalid_instruction)
1656 return arg0_value;
1657
1658 if (node->block_context->fn_entry) {
1659 add_node_error(irb->codegen, node, buf_sprintf("import valid only at top level scope"));
1660 return irb->codegen->invalid_instruction;
1661 }
1662
1663 return ir_build_import(irb, node, arg0_value);
1664 }
16311665 case BuiltinFnIdMemcpy:
16321666 case BuiltinFnIdMemset:
16331667 case BuiltinFnIdAlignof:
......@@ -1642,7 +1676,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
16421676 case BuiltinFnIdCDefine:
16431677 case BuiltinFnIdCUndef:
16441678 case BuiltinFnIdCompileErr:
1645 case BuiltinFnIdImport:
16461679 case BuiltinFnIdCImport:
16471680 case BuiltinFnIdErrName:
16481681 case BuiltinFnIdBreakpoint:
......@@ -1978,7 +2011,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {
19782011 IrBasicBlock *end_block = ir_build_basic_block(irb, "ForEnd");
19792012 IrBasicBlock *continue_block = ir_build_basic_block(irb, "ForContinue");
19802013
1981 IrInstruction *len_val = ir_build_read_field(irb, node, array_val, irb->codegen->len_buf);
2014 IrInstruction *len_val = ir_build_array_len(irb, node, array_val);
19822015 ir_build_br(irb, node, cond_block, is_inline);
19832016
19842017 ir_set_cursor_at_end(irb, cond_block);
......@@ -2846,7 +2879,9 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in
28462879 var_ptr_instruction->var = old_var_ptr_instruction->var;
28472880 new_instruction = &var_ptr_instruction->base;
28482881 } else if (old_instruction->id == IrInstructionIdFieldPtr) {
2849 zig_panic("TODO");
2882 IrInstructionFieldPtr *field_ptr_instruction = ir_create_instruction<IrInstructionFieldPtr>(ira->new_irb.exec,
2883 old_instruction->source_node);
2884 new_instruction = &field_ptr_instruction->base;
28502885 } else if (old_instruction->id == IrInstructionIdElemPtr) {
28512886 IrInstructionElemPtr *elem_ptr_instruction = ir_create_instruction<IrInstructionElemPtr>(ira->new_irb.exec,
28522887 old_instruction->source_node);
......@@ -2868,6 +2903,17 @@ static TypeTableEntry *ir_analyze_void(IrAnalyze *ira, IrInstruction *instructio
28682903 return ira->codegen->builtin_types.entry_void;
28692904}
28702905
2906static TypeTableEntry *ir_analyze_const_ptr(IrAnalyze *ira, IrInstruction *instruction,
2907 ConstExprValue *pointee, TypeTableEntry *pointee_type, bool depends_on_compile_var)
2908{
2909 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, pointee_type, true);
2910 ConstExprValue *const_val = ir_build_const_from(ira, instruction,
2911 depends_on_compile_var || pointee->depends_on_compile_var);
2912 const_val->data.x_ptr.base_ptr = pointee;
2913 const_val->data.x_ptr.index = SIZE_MAX;
2914 return ptr_type;
2915}
2916
28712917static TypeTableEntry *ir_analyze_const_usize(IrAnalyze *ira, IrInstruction *instruction, uint64_t value,
28722918 bool depends_on_compile_var)
28732919{
......@@ -2889,9 +2935,6 @@ static TypeTableEntry *ir_resolve_type_lval(IrAnalyze *ira, IrInstruction *type_
28892935 if (lval != LValPurposeNone)
28902936 zig_panic("TODO");
28912937
2892 if (type_value == ira->codegen->invalid_instruction)
2893 return ira->codegen->builtin_types.entry_invalid;
2894
28952938 if (type_value->type_entry->id == TypeTableEntryIdInvalid)
28962939 return ira->codegen->builtin_types.entry_invalid;
28972940
......@@ -3810,7 +3853,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
38103853 }
38113854
38123855 ir_build_call_from(&ira->new_irb, &call_instruction->base,
3813 call_instruction->fn, call_instruction->arg_count, casted_args);
3856 fn_ref, call_instruction->arg_count, casted_args);
38143857
38153858 return ir_finish_anal(ira, fn_type->data.fn.fn_type_id.return_type);
38163859 } else {
......@@ -4286,14 +4329,11 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
42864329 return resolved_type;
42874330}
42884331
4289static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) {
4290 VariableTableEntry *var = var_ptr_instruction->var;
4332static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction, VariableTableEntry *var) {
42914333 assert(var->type);
42924334 if (var->type->id == TypeTableEntryIdInvalid)
42934335 return var->type;
42944336
4295 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, var->type, false);
4296
42974337 ConstExprValue *mem_slot = nullptr;
42984338 if (var->block_context->fn_entry) {
42994339 // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing.
......@@ -4302,23 +4342,23 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct
43024342 } else if (var->src_is_const) {
43034343 AstNode *var_decl_node = var->decl_node;
43044344 assert(var_decl_node->type == NodeTypeVariableDeclaration);
4305 mem_slot = &get_resolved_expr(var_decl_node->data.variable_declaration.expr)->instruction->static_value;
4345 mem_slot = &var_decl_node->data.variable_declaration.top_level_decl.value->static_value;
43064346 assert(mem_slot->special != ConstValSpecialRuntime);
43074347 }
43084348
43094349 if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {
4310 ConstExprValue *out_val = ir_build_const_from(ira, &var_ptr_instruction->base,
4311 mem_slot->depends_on_compile_var);
4312
4313 out_val->data.x_ptr.base_ptr = mem_slot;
4314 out_val->data.x_ptr.index = SIZE_MAX;
4315 return ptr_type;
4350 return ir_analyze_const_ptr(ira, instruction, mem_slot, var->type, false);
43164351 } else {
4317 ir_build_var_ptr_from(&ira->new_irb, &var_ptr_instruction->base, var);
4318 return ptr_type;
4352 ir_build_var_ptr_from(&ira->new_irb, instruction, var);
4353 return get_pointer_to_type(ira->codegen, var->type, false);
43194354 }
43204355}
43214356
4357static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) {
4358 VariableTableEntry *var = var_ptr_instruction->var;
4359 return ir_analyze_var_ptr(ira, &var_ptr_instruction->base, var);
4360}
4361
43224362static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) {
43234363 IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other;
43244364 if (array_ptr->type_entry->id == TypeTableEntryIdInvalid)
......@@ -4483,108 +4523,146 @@ static TypeTableEntry *ir_analyze_container_member_access(IrAnalyze *ira, Buf *f
44834523 }
44844524}
44854525
4486static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) {
4487 IrInstruction *container_ptr = field_ptr_instruction->container_ptr->other;
4488 Buf *field_name = field_ptr_instruction->field_name;
4526static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, AstNode *decl_node,
4527 bool depends_on_compile_var)
4528{
4529 bool pointer_only = false;
4530 resolve_top_level_decl(ira->codegen, decl_node, pointer_only);
4531 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
4532 if (tld->resolution == TldResolutionInvalid)
4533 return ira->codegen->builtin_types.entry_invalid;
44894534
4490 TypeTableEntry *container_type = container_ptr->type_entry;
4491 if (container_type->id == TypeTableEntryIdInvalid) {
4492 return container_type;
4493 } else if (is_container_ref(container_type)) {
4494 return ir_analyze_container_member_access(ira, field_name, field_ptr_instruction, container_type);
4495 } else if (container_type->id == TypeTableEntryIdArray) {
4496 if (buf_eql_str(field_name, "len")) {
4497 add_node_error(ira->codegen, field_ptr_instruction->base.source_node,
4498 buf_sprintf("pointer to array length not available"));
4499 return ira->codegen->builtin_types.entry_invalid;
4500 } else {
4501 add_node_error(ira->codegen, field_ptr_instruction->base.source_node,
4502 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name),
4503 buf_ptr(&container_type->name)));
4504 return ira->codegen->builtin_types.entry_invalid;
4505 }
4506 } else if (container_type->id == TypeTableEntryIdMetaType) {
4507 TypeTableEntry *child_type = ir_resolve_type(ira, container_ptr);
4535 if (decl_node->type == NodeTypeVariableDeclaration) {
4536 VariableTableEntry *var = decl_node->data.variable_declaration.variable;
4537 return ir_analyze_var_ptr(ira, source_instruction, var);
4538 } else if (decl_node->type == NodeTypeFnProto) {
4539 FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry;
4540 assert(fn_entry->type_entry);
45084541
4509 if (child_type->id == TypeTableEntryIdInvalid) {
4510 return ira->codegen->builtin_types.entry_invalid;
4511 } else if (child_type->id == TypeTableEntryIdEnum) {
4512 zig_panic("TODO enum type field");
4513 } else if (child_type->id == TypeTableEntryIdStruct) {
4514 zig_panic("TODO struct type field");
4515 } else if (child_type->id == TypeTableEntryIdPureError) {
4516 zig_panic("TODO error type field");
4517 } else if (child_type->id == TypeTableEntryIdInt) {
4518 zig_panic("TODO integer type field");
4542 // TODO instead of allocating this every time, put it in the tld value and we can reference
4543 // the same one every time
4544 ConstExprValue *const_val = allocate<ConstExprValue>(1);
4545 const_val->special = ConstValSpecialStatic;
4546 if (fn_entry->type_entry->id == TypeTableEntryIdGenericFn) {
4547 const_val->data.x_type = fn_entry->type_entry;
45194548 } else {
4520 add_node_error(ira->codegen, field_ptr_instruction->base.source_node,
4521 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
4522 return ira->codegen->builtin_types.entry_invalid;
4549 const_val->data.x_fn = fn_entry;
45234550 }
4524 } else if (container_type->id == TypeTableEntryIdNamespace) {
4525 zig_panic("TODO namespace field access");
4551
4552 return ir_analyze_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, depends_on_compile_var);
4553 } else if (decl_node->type == NodeTypeContainerDecl) {
4554 zig_panic("TODO");
4555 //ConstExprValue *out_val = ir_build_const_from(ira, source_instruction, depends_on_compile_var);
4556 //if (decl_node->data.struct_decl.generic_params.length > 0) {
4557 // TypeTableEntry *type_entry = decl_node->data.struct_decl.generic_fn_type;
4558 // assert(type_entry);
4559 // out_val->data.x_type = type_entry;
4560 // return type_entry;
4561 //} else {
4562 // out_val->data.x_type = decl_node->data.struct_decl.type_entry;
4563 // return ira->codegen->builtin_types.entry_type;
4564 //}
4565 } else if (decl_node->type == NodeTypeTypeDecl) {
4566 zig_panic("TODO");
4567 //ConstExprValue *out_val = ir_build_const_from(ira, source_instruction, depends_on_compile_var);
4568 //out_val->data.x_type = decl_node->data.type_decl.child_type_entry;
4569 //return ira->codegen->builtin_types.entry_type;
45264570 } else {
4527 add_node_error(ira->codegen, field_ptr_instruction->base.source_node,
4528 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
4529 return ira->codegen->builtin_types.entry_invalid;
4571 zig_unreachable();
45304572 }
45314573}
45324574
4533static TypeTableEntry *ir_analyze_read_field_as_ptr_load(IrAnalyze *ira,
4534 IrInstructionReadField *read_field_instruction)
4535{
4536 IrInstruction *old_field_ptr_inst = ir_build_field_ptr(&ira->old_irb, read_field_instruction->base.source_node,
4537 read_field_instruction->container_ptr, read_field_instruction->field_name);
4538 IrInstruction *old_load_ptr_inst = ir_build_load_ptr(&ira->old_irb, read_field_instruction->base.source_node,
4539 old_field_ptr_inst);
4540 ir_analyze_instruction(ira, old_field_ptr_inst);
4541 TypeTableEntry *result_type = ir_analyze_instruction(ira, old_load_ptr_inst);
4542 read_field_instruction->base.other = old_load_ptr_inst->other;
4543 return result_type;
4544}
4575static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) {
4576 IrInstruction *container_ptr = field_ptr_instruction->container_ptr->other;
4577 if (container_ptr->type_entry->id == TypeTableEntryIdInvalid)
4578 return ira->codegen->builtin_types.entry_invalid;
45454579
4546static TypeTableEntry *ir_analyze_instruction_read_field(IrAnalyze *ira,
4547 IrInstructionReadField *read_field_instruction)
4548{
4549 IrInstruction *container_ptr = read_field_instruction->container_ptr->other;
4550 Buf *field_name = read_field_instruction->field_name;
4580 assert(container_ptr->type_entry->id == TypeTableEntryIdPointer);
4581 TypeTableEntry *container_type = container_ptr->type_entry->data.pointer.child_type;
4582
4583 Buf *field_name = field_ptr_instruction->field_name;
4584 AstNode *source_node = field_ptr_instruction->base.source_node;
45514585
4552 TypeTableEntry *container_type = container_ptr->type_entry;
45534586 if (container_type->id == TypeTableEntryIdInvalid) {
45544587 return container_type;
45554588 } else if (is_container_ref(container_type)) {
4556 return ir_analyze_read_field_as_ptr_load(ira, read_field_instruction);
4589 return ir_analyze_container_member_access(ira, field_name, field_ptr_instruction, container_type);
45574590 } else if (container_type->id == TypeTableEntryIdArray) {
45584591 if (buf_eql_str(field_name, "len")) {
4559 return ir_analyze_const_usize(ira, &read_field_instruction->base, container_type->data.array.len, false);
4592 ConstExprValue *len_val = allocate<ConstExprValue>(1);
4593 len_val->special = ConstValSpecialStatic;
4594 bignum_init_unsigned(&len_val->data.x_bignum, container_type->data.array.len);
4595
4596 TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
4597 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, len_val, usize, false);
45604598 } else {
4561 add_node_error(ira->codegen, read_field_instruction->base.source_node,
4599 add_node_error(ira->codegen, source_node,
45624600 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name),
45634601 buf_ptr(&container_type->name)));
45644602 return ira->codegen->builtin_types.entry_invalid;
45654603 }
45664604 } else if (container_type->id == TypeTableEntryIdMetaType) {
4567 TypeTableEntry *child_type = ir_resolve_type(ira, container_ptr);
4568
4569 if (child_type->id == TypeTableEntryIdInvalid) {
4605 zig_panic("TODO type field access");
4606 //TypeTableEntry *child_type = ir_resolve_type(ira, container_ptr);
4607
4608 //if (child_type->id == TypeTableEntryIdInvalid) {
4609 // return ira->codegen->builtin_types.entry_invalid;
4610 //} else if (child_type->id == TypeTableEntryIdEnum) {
4611 // zig_panic("TODO enum type field");
4612 //} else if (child_type->id == TypeTableEntryIdStruct) {
4613 // zig_panic("TODO struct type field");
4614 //} else if (child_type->id == TypeTableEntryIdPureError) {
4615 // zig_panic("TODO error type field");
4616 //} else if (child_type->id == TypeTableEntryIdInt) {
4617 // zig_panic("TODO integer type field");
4618 //} else {
4619 // add_node_error(ira->codegen, source_node,
4620 // buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
4621 // return ira->codegen->builtin_types.entry_invalid;
4622 //}
4623 } else if (container_type->id == TypeTableEntryIdNamespace) {
4624 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr);
4625 if (!container_ptr_val)
45704626 return ira->codegen->builtin_types.entry_invalid;
4571 } else if (child_type->id == TypeTableEntryIdEnum) {
4572 zig_panic("TODO enum type field");
4573 } else if (child_type->id == TypeTableEntryIdStruct) {
4574 zig_panic("TODO struct type field");
4575 } else if (child_type->id == TypeTableEntryIdPureError) {
4576 zig_panic("TODO error type field");
4577 } else if (child_type->id == TypeTableEntryIdInt) {
4578 zig_panic("TODO integer type field");
4627
4628 ConstExprValue *namespace_val = const_ptr_pointee(container_ptr_val);
4629 assert(namespace_val->special == ConstValSpecialStatic);
4630
4631 ImportTableEntry *namespace_import = namespace_val->data.x_import;
4632
4633 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;
4634 AstNode *decl_node = find_decl(namespace_import->block_context, field_name);
4635 if (!decl_node) {
4636 // we must now resolve all the use decls
4637 for (size_t i = 0; i < namespace_import->use_decls.length; i += 1) {
4638 AstNode *use_decl_node = namespace_import->use_decls.at(i);
4639 TopLevelDecl *tld = get_as_top_level_decl(use_decl_node);
4640 if (tld->resolution == TldResolutionUnresolved) {
4641 preview_use_decl(ira->codegen, use_decl_node);
4642 }
4643 resolve_use_decl(ira->codegen, use_decl_node);
4644 }
4645 decl_node = find_decl(namespace_import->block_context, field_name);
4646 }
4647 if (decl_node) {
4648 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
4649 if (tld->visib_mod == VisibModPrivate &&
4650 decl_node->owner != source_node->owner)
4651 {
4652 ErrorMsg *msg = add_node_error(ira->codegen, source_node,
4653 buf_sprintf("'%s' is private", buf_ptr(field_name)));
4654 add_error_note(ira->codegen, msg, decl_node, buf_sprintf("declared here"));
4655 return ira->codegen->builtin_types.entry_invalid;
4656 }
4657 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, decl_node, depends_on_compile_var);
45794658 } else {
4580 add_node_error(ira->codegen, read_field_instruction->base.source_node,
4581 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
4659 const char *import_name = namespace_import->path ? buf_ptr(namespace_import->path) : "(C import)";
4660 add_node_error(ira->codegen, source_node,
4661 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), import_name));
45824662 return ira->codegen->builtin_types.entry_invalid;
45834663 }
4584 } else if (container_type->id == TypeTableEntryIdNamespace) {
4585 zig_panic("TODO namespace field access");
45864664 } else {
4587 add_node_error(ira->codegen, read_field_instruction->base.source_node,
4665 add_node_error(ira->codegen, field_ptr_instruction->base.source_node,
45884666 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
45894667 return ira->codegen->builtin_types.entry_invalid;
45904668 }
......@@ -4610,7 +4688,7 @@ static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruc
46104688 return child_type;
46114689 } else {
46124690 add_node_error(ira->codegen, load_ptr_instruction->base.source_node,
4613 buf_sprintf("indirection requires pointer operand ('%s' invalid)",
4691 buf_sprintf("attempt to dereference non pointer type '%s'",
46144692 buf_ptr(&type_entry->name)));
46154693 return ira->codegen->builtin_types.entry_invalid;
46164694 }
......@@ -5413,6 +5491,110 @@ static TypeTableEntry *ir_analyze_instruction_static_eval(IrAnalyze *ira,
54135491 return value->type_entry;
54145492}
54155493
5494static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) {
5495 IrInstruction *name_value = import_instruction->name->other;
5496 Buf *import_target_str = ir_resolve_str(ira, name_value);
5497 if (!import_target_str)
5498 return ira->codegen->builtin_types.entry_invalid;
5499 bool depends_on_compile_var = name_value->static_value.depends_on_compile_var;
5500
5501 AstNode *source_node = import_instruction->base.source_node;
5502 ImportTableEntry *import = source_node->owner;
5503
5504 Buf *import_target_path;
5505 Buf *search_dir;
5506 assert(import->package);
5507 PackageTableEntry *target_package;
5508 auto package_entry = import->package->package_table.maybe_get(import_target_str);
5509 if (package_entry) {
5510 target_package = package_entry->value;
5511 import_target_path = &target_package->root_src_path;
5512 search_dir = &target_package->root_src_dir;
5513 } else {
5514 // try it as a filename
5515 target_package = import->package;
5516 import_target_path = import_target_str;
5517 search_dir = &import->package->root_src_dir;
5518 }
5519
5520 Buf full_path = BUF_INIT;
5521 os_path_join(search_dir, import_target_path, &full_path);
5522
5523 Buf *import_code = buf_alloc();
5524 Buf *abs_full_path = buf_alloc();
5525 int err;
5526 if ((err = os_path_real(&full_path, abs_full_path))) {
5527 if (err == ErrorFileNotFound) {
5528 add_node_error(ira->codegen, source_node,
5529 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path)));
5530 return ira->codegen->builtin_types.entry_invalid;
5531 } else {
5532 ira->codegen->error_during_imports = true;
5533 add_node_error(ira->codegen, source_node,
5534 buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err)));
5535 return ira->codegen->builtin_types.entry_invalid;
5536 }
5537 }
5538
5539 auto import_entry = ira->codegen->import_table.maybe_get(abs_full_path);
5540 if (import_entry) {
5541 ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base, depends_on_compile_var);
5542 out_val->data.x_import = import_entry->value;
5543 return ira->codegen->builtin_types.entry_namespace;
5544 }
5545
5546 if ((err = os_fetch_file_path(abs_full_path, import_code))) {
5547 if (err == ErrorFileNotFound) {
5548 add_node_error(ira->codegen, source_node,
5549 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path)));
5550 return ira->codegen->builtin_types.entry_invalid;
5551 } else {
5552 add_node_error(ira->codegen, source_node,
5553 buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err)));
5554 return ira->codegen->builtin_types.entry_invalid;
5555 }
5556 }
5557 ImportTableEntry *target_import = add_source_file(ira->codegen, target_package,
5558 abs_full_path, search_dir, import_target_path, import_code);
5559
5560 scan_decls(ira->codegen, target_import, target_import->block_context, target_import->root);
5561
5562 ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base, depends_on_compile_var);
5563 out_val->data.x_import = target_import;
5564 return ira->codegen->builtin_types.entry_namespace;
5565
5566}
5567
5568static TypeTableEntry *ir_analyze_instruction_array_len(IrAnalyze *ira,
5569 IrInstructionArrayLen *array_len_instruction)
5570{
5571 IrInstruction *array_value = array_len_instruction->array_value->other;
5572 TypeTableEntry *canon_type = get_underlying_type(array_value->type_entry);
5573 if (canon_type->id == TypeTableEntryIdInvalid) {
5574 return ira->codegen->builtin_types.entry_invalid;
5575 } else if (canon_type->id == TypeTableEntryIdArray) {
5576 bool depends_on_compile_var = array_value->static_value.depends_on_compile_var;
5577 return ir_analyze_const_usize(ira, &array_len_instruction->base,
5578 canon_type->data.array.len, depends_on_compile_var);
5579 } else if (is_slice(canon_type)) {
5580 if (array_value->static_value.special != ConstValSpecialRuntime) {
5581 ConstExprValue *len_val = &array_value->static_value.data.x_struct.fields[slice_len_index];
5582 if (len_val->special != ConstValSpecialRuntime) {
5583 bool depends_on_compile_var = len_val->depends_on_compile_var;
5584 return ir_analyze_const_usize(ira, &array_len_instruction->base,
5585 len_val->data.x_bignum.data.x_uint, depends_on_compile_var);
5586 }
5587 }
5588 ir_build_array_len_from(&ira->new_irb, &array_len_instruction->base, array_value);
5589 return ira->codegen->builtin_types.entry_usize;
5590 } else {
5591 add_node_error(ira->codegen, array_len_instruction->base.source_node,
5592 buf_sprintf("type '%s' has no field 'len'", buf_ptr(&array_value->type_entry->name)));
5593 // TODO if this is a typedecl, add error note showing the declaration of the type decl
5594 return ira->codegen->builtin_types.entry_invalid;
5595 }
5596}
5597
54165598static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
54175599 switch (instruction->id) {
54185600 case IrInstructionIdInvalid:
......@@ -5437,8 +5619,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
54375619 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction);
54385620 case IrInstructionIdFieldPtr:
54395621 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction);
5440 case IrInstructionIdReadField:
5441 return ir_analyze_instruction_read_field(ira, (IrInstructionReadField *)instruction);
54425622 case IrInstructionIdCall:
54435623 return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction);
54445624 case IrInstructionIdBr:
......@@ -5489,6 +5669,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
54895669 return ir_analyze_instruction_enum_tag(ira, (IrInstructionEnumTag *)instruction);
54905670 case IrInstructionIdStaticEval:
54915671 return ir_analyze_instruction_static_eval(ira, (IrInstructionStaticEval *)instruction);
5672 case IrInstructionIdImport:
5673 return ir_analyze_instruction_import(ira, (IrInstructionImport *)instruction);
5674 case IrInstructionIdArrayLen:
5675 return ir_analyze_instruction_array_len(ira, (IrInstructionArrayLen *)instruction);
54925676 case IrInstructionIdCast:
54935677 case IrInstructionIdContainerInitList:
54945678 case IrInstructionIdContainerInitFields:
......@@ -5580,6 +5764,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
55805764 case IrInstructionIdSetFnTest:
55815765 case IrInstructionIdSetFnVisible:
55825766 case IrInstructionIdSetDebugSafety:
5767 case IrInstructionIdImport:
55835768 return true;
55845769 case IrInstructionIdPhi:
55855770 case IrInstructionIdUnOp:
......@@ -5595,7 +5780,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
55955780 case IrInstructionIdTypeOf:
55965781 case IrInstructionIdToPtrType:
55975782 case IrInstructionIdPtrTypeChild:
5598 case IrInstructionIdReadField:
5783 case IrInstructionIdArrayLen:
55995784 case IrInstructionIdStructFieldPtr:
56005785 case IrInstructionIdArrayType:
56015786 case IrInstructionIdSliceType:
......@@ -5666,81 +5851,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
56665851// }
56675852//}
56685853
5669//static TypeTableEntry *analyze_import(CodeGen *g, ImportTableEntry *import, BlockContext *context,
5670// AstNode *node)
5671//{
5672// assert(node->type == NodeTypeFnCallExpr);
5673//
5674// if (context->fn_entry) {
5675// add_node_error(g, node, buf_sprintf("@import invalid inside function bodies"));
5676// return g->builtin_types.entry_invalid;
5677// }
5678//
5679// AstNode *first_param_node = node->data.fn_call_expr.params.at(0);
5680// Buf *import_target_str = resolve_const_expr_str(g, import, context, first_param_node->parent_field);
5681// if (!import_target_str) {
5682// return g->builtin_types.entry_invalid;
5683// }
5684//
5685// Buf *import_target_path;
5686// Buf *search_dir;
5687// assert(import->package);
5688// PackageTableEntry *target_package;
5689// auto package_entry = import->package->package_table.maybe_get(import_target_str);
5690// if (package_entry) {
5691// target_package = package_entry->value;
5692// import_target_path = &target_package->root_src_path;
5693// search_dir = &target_package->root_src_dir;
5694// } else {
5695// // try it as a filename
5696// target_package = import->package;
5697// import_target_path = import_target_str;
5698// search_dir = &import->package->root_src_dir;
5699// }
5700//
5701// Buf full_path = BUF_INIT;
5702// os_path_join(search_dir, import_target_path, &full_path);
5703//
5704// Buf *import_code = buf_alloc();
5705// Buf *abs_full_path = buf_alloc();
5706// int err;
5707// if ((err = os_path_real(&full_path, abs_full_path))) {
5708// if (err == ErrorFileNotFound) {
5709// add_node_error(g, node,
5710// buf_sprintf("unable to find '%s'", buf_ptr(import_target_path)));
5711// return g->builtin_types.entry_invalid;
5712// } else {
5713// g->error_during_imports = true;
5714// add_node_error(g, node,
5715// buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err)));
5716// return g->builtin_types.entry_invalid;
5717// }
5718// }
5719//
5720// auto import_entry = g->import_table.maybe_get(abs_full_path);
5721// if (import_entry) {
5722// return resolve_expr_const_val_as_import(g, node, import_entry->value);
5723// }
5724//
5725// if ((err = os_fetch_file_path(abs_full_path, import_code))) {
5726// if (err == ErrorFileNotFound) {
5727// add_node_error(g, node,
5728// buf_sprintf("unable to find '%s'", buf_ptr(import_target_path)));
5729// return g->builtin_types.entry_invalid;
5730// } else {
5731// add_node_error(g, node,
5732// buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err)));
5733// return g->builtin_types.entry_invalid;
5734// }
5735// }
5736// ImportTableEntry *target_import = add_source_file(g, target_package,
5737// abs_full_path, search_dir, import_target_path, import_code);
5738//
5739// scan_decls(g, target_import, target_import->block_context, target_import->root);
5740//
5741// return resolve_expr_const_val_as_import(g, node, target_import);
5742//}
5743//
57445854//static TypeTableEntry *analyze_c_import(CodeGen *g, ImportTableEntry *parent_import,
57455855// BlockContext *parent_context, AstNode *node)
57465856//{
......@@ -6615,38 +6725,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
66156725// buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));
66166726// return g->builtin_types.entry_invalid;
66176727// }
6618// } else if (struct_type->id == TypeTableEntryIdNamespace) {
6619// ConstExprValue *const_val = &get_resolved_expr(*struct_expr_node)->const_val;
6620// assert(const_val->ok);
6621// ImportTableEntry *namespace_import = const_val->data.x_import;
6622// AstNode *decl_node = find_decl(namespace_import->block_context, field_name);
6623// if (!decl_node) {
6624// // we must now resolve all the use decls
6625// for (size_t i = 0; i < namespace_import->use_decls.length; i += 1) {
6626// AstNode *use_decl_node = namespace_import->use_decls.at(i);
6627// if (!get_resolved_expr(use_decl_node->data.use.expr)->type_entry) {
6628// preview_use_decl(g, use_decl_node);
6629// }
6630// resolve_use_decl(g, use_decl_node);
6631// }
6632// decl_node = find_decl(namespace_import->block_context, field_name);
6633// }
6634// if (decl_node) {
6635// TopLevelDecl *tld = get_as_top_level_decl(decl_node);
6636// if (tld->visib_mod == VisibModPrivate && decl_node->owner != import) {
6637// ErrorMsg *msg = add_node_error(g, node,
6638// buf_sprintf("'%s' is private", buf_ptr(field_name)));
6639// add_error_note(g, msg, decl_node, buf_sprintf("declared here"));
6640// }
6641// bool pointer_only = false;
6642// return analyze_decl_ref(g, node, decl_node, pointer_only, context,
6643// const_val->depends_on_compile_var);
6644// } else {
6645// const char *import_name = namespace_import->path ? buf_ptr(namespace_import->path) : "(C import)";
6646// add_node_error(g, node,
6647// buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), import_name));
6648// return g->builtin_types.entry_invalid;
6649// }
66506728// } else {
66516729// add_node_error(g, node,
66526730// buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));
......@@ -6654,490 +6732,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
66546732// }
66556733//}
66566734//
6657
6658//static TypeTableEntry *analyze_lvalue(CodeGen *g, ImportTableEntry *import, BlockContext *block_context,
6659// AstNode *lhs_node, LValPurpose purpose, bool is_ptr_const)
6660//{
6661// TypeTableEntry *expected_rhs_type = nullptr;
6662// lhs_node->block_context = block_context;
6663// if (lhs_node->type == NodeTypeSymbol) {
6664// bool pointer_only = purpose == LValPurposeAddressOf;
6665// expected_rhs_type = analyze_symbol_expr(g, import, block_context, nullptr, lhs_node, pointer_only);
6666// if (expected_rhs_type->id == TypeTableEntryIdInvalid) {
6667// return g->builtin_types.entry_invalid;
6668// }
6669// if (purpose != LValPurposeAddressOf) {
6670// Buf *name = lhs_node->data.symbol_expr.symbol;
6671// VariableTableEntry *var = find_variable(g, block_context, name);
6672// if (var) {
6673// if (var->src_is_const) {
6674// add_node_error(g, lhs_node, buf_sprintf("cannot assign to constant"));
6675// expected_rhs_type = g->builtin_types.entry_invalid;
6676// } else {
6677// expected_rhs_type = var->type;
6678// get_resolved_expr(lhs_node)->variable = var;
6679// }
6680// } else {
6681// add_node_error(g, lhs_node,
6682// buf_sprintf("use of undeclared identifier '%s'", buf_ptr(name)));
6683// expected_rhs_type = g->builtin_types.entry_invalid;
6684// }
6685// }
6686// } else if (lhs_node->type == NodeTypeArrayAccessExpr) {
6687// expected_rhs_type = analyze_array_access_expr(g, import, block_context, lhs_node, purpose);
6688// } else if (lhs_node->type == NodeTypeFieldAccessExpr) {
6689// expected_rhs_type = analyze_field_access_expr(g, import, block_context, nullptr, lhs_node);
6690// } else if (lhs_node->type == NodeTypePrefixOpExpr &&
6691// lhs_node->data.prefix_op_expr.prefix_op == PrefixOpDereference)
6692// {
6693// assert(purpose == LValPurposeAssign);
6694// AstNode *target_node = lhs_node->data.prefix_op_expr.primary_expr;
6695// TypeTableEntry *type_entry = analyze_expression(g, import, block_context, nullptr, target_node);
6696// if (type_entry->id == TypeTableEntryIdInvalid) {
6697// expected_rhs_type = type_entry;
6698// } else if (type_entry->id == TypeTableEntryIdPointer) {
6699// expected_rhs_type = type_entry->data.pointer.child_type;
6700// } else {
6701// add_node_error(g, target_node,
6702// buf_sprintf("indirection requires pointer operand ('%s' invalid)",
6703// buf_ptr(&type_entry->name)));
6704// expected_rhs_type = g->builtin_types.entry_invalid;
6705// }
6706// } else {
6707// if (purpose == LValPurposeAssign) {
6708// add_node_error(g, lhs_node, buf_sprintf("invalid assignment target"));
6709// expected_rhs_type = g->builtin_types.entry_invalid;
6710// } else if (purpose == LValPurposeAddressOf) {
6711// TypeTableEntry *type_entry = analyze_expression(g, import, block_context, nullptr, lhs_node);
6712// if (type_entry->id == TypeTableEntryIdInvalid) {
6713// expected_rhs_type = g->builtin_types.entry_invalid;
6714// } else if (type_entry->id == TypeTableEntryIdMetaType) {
6715// expected_rhs_type = type_entry;
6716// } else {
6717// add_node_error(g, lhs_node, buf_sprintf("invalid addressof target"));
6718// expected_rhs_type = g->builtin_types.entry_invalid;
6719// }
6720// }
6721// }
6722// assert(expected_rhs_type);
6723// return expected_rhs_type;
6724//}
6725
6726
6727
6728//static TypeTableEntry *analyze_bin_op_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
6729// TypeTableEntry *expected_type, AstNode *node)
6730//{
6731// assert(node->type == NodeTypeBinOpExpr);
6732// BinOpType bin_op_type = node->data.bin_op_expr.bin_op;
6733// switch (bin_op_type) {
6734// case BinOpTypeAssign:
6735// case BinOpTypeAssignTimes:
6736// case BinOpTypeAssignTimesWrap:
6737// case BinOpTypeAssignDiv:
6738// case BinOpTypeAssignMod:
6739// case BinOpTypeAssignPlus:
6740// case BinOpTypeAssignPlusWrap:
6741// case BinOpTypeAssignMinus:
6742// case BinOpTypeAssignMinusWrap:
6743// case BinOpTypeAssignBitShiftLeft:
6744// case BinOpTypeAssignBitShiftLeftWrap:
6745// case BinOpTypeAssignBitShiftRight:
6746// case BinOpTypeAssignBitAnd:
6747// case BinOpTypeAssignBitXor:
6748// case BinOpTypeAssignBitOr:
6749// case BinOpTypeAssignBoolAnd:
6750// case BinOpTypeAssignBoolOr:
6751// {
6752// AstNode *lhs_node = node->data.bin_op_expr.op1;
6753//
6754// TypeTableEntry *expected_rhs_type = analyze_lvalue(g, import, context, lhs_node,
6755// LValPurposeAssign, false);
6756// if (expected_rhs_type->id == TypeTableEntryIdInvalid) {
6757// return g->builtin_types.entry_invalid;
6758// } else if (!is_op_allowed(expected_rhs_type, node->data.bin_op_expr.bin_op)) {
6759// if (expected_rhs_type->id != TypeTableEntryIdInvalid) {
6760// add_node_error(g, lhs_node,
6761// buf_sprintf("operator not allowed for type '%s'",
6762// buf_ptr(&expected_rhs_type->name)));
6763// }
6764// }
6765//
6766// analyze_expression(g, import, context, expected_rhs_type, node->data.bin_op_expr.op2);
6767// // not const ok because expression has side effects
6768// return g->builtin_types.entry_void;
6769// }
6770// case BinOpTypeBoolOr:
6771// case BinOpTypeBoolAnd:
6772// return analyze_logic_bin_op_expr(g, import, context, node);
6773// case BinOpTypeCmpEq:
6774// case BinOpTypeCmpNotEq:
6775// case BinOpTypeCmpLessThan:
6776// case BinOpTypeCmpGreaterThan:
6777// case BinOpTypeCmpLessOrEq:
6778// case BinOpTypeCmpGreaterOrEq:
6779// return analyze_bool_bin_op_expr(g, import, context, node);
6780// case BinOpTypeBinOr:
6781// case BinOpTypeBinXor:
6782// case BinOpTypeBinAnd:
6783// case BinOpTypeBitShiftLeft:
6784// case BinOpTypeBitShiftLeftWrap:
6785// case BinOpTypeBitShiftRight:
6786// case BinOpTypeAdd:
6787// case BinOpTypeAddWrap:
6788// case BinOpTypeSub:
6789// case BinOpTypeSubWrap:
6790// case BinOpTypeMult:
6791// case BinOpTypeMultWrap:
6792// case BinOpTypeDiv:
6793// case BinOpTypeMod:
6794// {
6795// AstNode **op1 = node->data.bin_op_expr.op1->parent_field;
6796// AstNode **op2 = node->data.bin_op_expr.op2->parent_field;
6797// TypeTableEntry *lhs_type = analyze_expression(g, import, context, nullptr, *op1);
6798// TypeTableEntry *rhs_type = analyze_expression(g, import, context, nullptr, *op2);
6799//
6800// AstNode *op_nodes[] = {*op1, *op2};
6801// TypeTableEntry *op_types[] = {lhs_type, rhs_type};
6802//
6803// TypeTableEntry *resolved_type = resolve_peer_type_compatibility(g, import, context, node,
6804// op_nodes, op_types, 2);
6805//
6806// if (resolved_type->id == TypeTableEntryIdInvalid) {
6807// return resolved_type;
6808// }
6809//
6810// if (resolved_type->id == TypeTableEntryIdInt ||
6811// resolved_type->id == TypeTableEntryIdNumLitInt)
6812// {
6813// // int
6814// } else if ((resolved_type->id == TypeTableEntryIdFloat ||
6815// resolved_type->id == TypeTableEntryIdNumLitFloat) &&
6816// (bin_op_type == BinOpTypeAdd ||
6817// bin_op_type == BinOpTypeSub ||
6818// bin_op_type == BinOpTypeMult ||
6819// bin_op_type == BinOpTypeDiv ||
6820// bin_op_type == BinOpTypeMod))
6821// {
6822// // float
6823// } else {
6824// add_node_error(g, node, buf_sprintf("invalid operands to binary expression: '%s' and '%s'",
6825// buf_ptr(&lhs_type->name), buf_ptr(&rhs_type->name)));
6826// return g->builtin_types.entry_invalid;
6827// }
6828//
6829// ConstExprValue *op1_val = &get_resolved_expr(*op1)->const_val;
6830// ConstExprValue *op2_val = &get_resolved_expr(*op2)->const_val;
6831// if (!op1_val->ok || !op2_val->ok) {
6832// return resolved_type;
6833// }
6834//
6835// ConstExprValue *out_val = &get_resolved_expr(node)->const_val;
6836// int err;
6837// if ((err = eval_const_expr_bin_op(op1_val, resolved_type, bin_op_type,
6838// op2_val, resolved_type, out_val)))
6839// {
6840// if (err == ErrorDivByZero) {
6841// add_node_error(g, node, buf_sprintf("division by zero is undefined"));
6842// return g->builtin_types.entry_invalid;
6843// } else if (err == ErrorOverflow) {
6844// add_node_error(g, node, buf_sprintf("value cannot be represented in any integer type"));
6845// return g->builtin_types.entry_invalid;
6846// }
6847// return g->builtin_types.entry_invalid;
6848// }
6849//
6850// num_lit_fits_in_other_type(g, node, resolved_type);
6851// return resolved_type;
6852// }
6853// case BinOpTypeUnwrapMaybe:
6854// {
6855// AstNode *op1 = node->data.bin_op_expr.op1;
6856// AstNode *op2 = node->data.bin_op_expr.op2;
6857// TypeTableEntry *lhs_type = analyze_expression(g, import, context, nullptr, op1);
6858//
6859// if (lhs_type->id == TypeTableEntryIdInvalid) {
6860// return lhs_type;
6861// } else if (lhs_type->id == TypeTableEntryIdMaybe) {
6862// TypeTableEntry *child_type = lhs_type->data.maybe.child_type;
6863// analyze_expression(g, import, context, child_type, op2);
6864// return child_type;
6865// } else {
6866// add_node_error(g, op1,
6867// buf_sprintf("expected maybe type, found '%s'",
6868// buf_ptr(&lhs_type->name)));
6869// return g->builtin_types.entry_invalid;
6870// }
6871// }
6872// case BinOpTypeArrayCat:
6873// {
6874// AstNode **op1 = node->data.bin_op_expr.op1->parent_field;
6875// AstNode **op2 = node->data.bin_op_expr.op2->parent_field;
6876//
6877// TypeTableEntry *op1_type = analyze_expression(g, import, context, nullptr, *op1);
6878// TypeTableEntry *child_type;
6879// if (op1_type->id == TypeTableEntryIdInvalid) {
6880// return g->builtin_types.entry_invalid;
6881// } else if (op1_type->id == TypeTableEntryIdArray) {
6882// child_type = op1_type->data.array.child_type;
6883// } else if (op1_type->id == TypeTableEntryIdPointer &&
6884// op1_type->data.pointer.child_type == g->builtin_types.entry_u8) {
6885// child_type = op1_type->data.pointer.child_type;
6886// } else {
6887// add_node_error(g, *op1, buf_sprintf("expected array or C string literal, found '%s'",
6888// buf_ptr(&op1_type->name)));
6889// return g->builtin_types.entry_invalid;
6890// }
6891//
6892// TypeTableEntry *op2_type = analyze_expression(g, import, context, nullptr, *op2);
6893//
6894// if (op2_type->id == TypeTableEntryIdInvalid) {
6895// return g->builtin_types.entry_invalid;
6896// } else if (op2_type->id == TypeTableEntryIdArray) {
6897// if (op2_type->data.array.child_type != child_type) {
6898// add_node_error(g, *op2, buf_sprintf("expected array of type '%s', found '%s'",
6899// buf_ptr(&child_type->name),
6900// buf_ptr(&op2_type->name)));
6901// return g->builtin_types.entry_invalid;
6902// }
6903// } else if (op2_type->id == TypeTableEntryIdPointer &&
6904// op2_type->data.pointer.child_type == g->builtin_types.entry_u8) {
6905// } else {
6906// add_node_error(g, *op2, buf_sprintf("expected array or C string literal, found '%s'",
6907// buf_ptr(&op2_type->name)));
6908// return g->builtin_types.entry_invalid;
6909// }
6910//
6911// ConstExprValue *op1_val = &get_resolved_expr(*op1)->const_val;
6912// ConstExprValue *op2_val = &get_resolved_expr(*op2)->const_val;
6913//
6914// AstNode *bad_node;
6915// if (!op1_val->ok) {
6916// bad_node = *op1;
6917// } else if (!op2_val->ok) {
6918// bad_node = *op2;
6919// } else {
6920// bad_node = nullptr;
6921// }
6922// if (bad_node) {
6923// add_node_error(g, bad_node, buf_sprintf("array concatenation requires constant expression"));
6924// return g->builtin_types.entry_invalid;
6925// }
6926//
6927// ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
6928// const_val->ok = true;
6929// const_val->depends_on_compile_var = op1_val->depends_on_compile_var ||
6930// op2_val->depends_on_compile_var;
6931//
6932// if (op1_type->id == TypeTableEntryIdArray) {
6933// uint64_t new_len = op1_type->data.array.len + op2_type->data.array.len;
6934// const_val->data.x_array.fields = allocate<ConstExprValue*>(new_len);
6935// uint64_t next_index = 0;
6936// for (uint64_t i = 0; i < op1_type->data.array.len; i += 1, next_index += 1) {
6937// const_val->data.x_array.fields[next_index] = op1_val->data.x_array.fields[i];
6938// }
6939// for (uint64_t i = 0; i < op2_type->data.array.len; i += 1, next_index += 1) {
6940// const_val->data.x_array.fields[next_index] = op2_val->data.x_array.fields[i];
6941// }
6942// return get_array_type(g, child_type, new_len);
6943// } else if (op1_type->id == TypeTableEntryIdPointer) {
6944// if (!op1_val->data.x_ptr.is_c_str) {
6945// add_node_error(g, *op1,
6946// buf_sprintf("expected array or C string literal, found '%s'",
6947// buf_ptr(&op1_type->name)));
6948// return g->builtin_types.entry_invalid;
6949// } else if (!op2_val->data.x_ptr.is_c_str) {
6950// add_node_error(g, *op2,
6951// buf_sprintf("expected array or C string literal, found '%s'",
6952// buf_ptr(&op2_type->name)));
6953// return g->builtin_types.entry_invalid;
6954// }
6955// const_val->data.x_ptr.is_c_str = true;
6956// const_val->data.x_ptr.len = op1_val->data.x_ptr.len + op2_val->data.x_ptr.len - 1;
6957// const_val->data.x_ptr.ptr = allocate<ConstExprValue*>(const_val->data.x_ptr.len);
6958// uint64_t next_index = 0;
6959// for (uint64_t i = 0; i < op1_val->data.x_ptr.len - 1; i += 1, next_index += 1) {
6960// const_val->data.x_ptr.ptr[next_index] = op1_val->data.x_ptr.ptr[i];
6961// }
6962// for (uint64_t i = 0; i < op2_val->data.x_ptr.len; i += 1, next_index += 1) {
6963// const_val->data.x_ptr.ptr[next_index] = op2_val->data.x_ptr.ptr[i];
6964// }
6965// return op1_type;
6966// } else {
6967// zig_unreachable();
6968// }
6969// }
6970// case BinOpTypeArrayMult:
6971// return analyze_array_mult(g, import, context, expected_type, node);
6972// case BinOpTypeInvalid:
6973// zig_unreachable();
6974// }
6975// zig_unreachable();
6976//}
6977
6978
6979//static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
6980// AstNode *node)
6981//{
6982// assert(node->type == NodeTypeBinOpExpr);
6983// BinOpType bin_op_type = node->data.bin_op_expr.bin_op;
6984//
6985// AstNode **op1 = &node->data.bin_op_expr.op1;
6986// AstNode **op2 = &node->data.bin_op_expr.op2;
6987// TypeTableEntry *op1_type = analyze_expression(g, import, context, nullptr, *op1);
6988// TypeTableEntry *op2_type = analyze_expression(g, import, context, nullptr, *op2);
6989//
6990// AstNode *op_nodes[] = {*op1, *op2};
6991// TypeTableEntry *op_types[] = {op1_type, op2_type};
6992//
6993// TypeTableEntry *resolved_type = resolve_peer_type_compatibility(g, import, context, node,
6994// op_nodes, op_types, 2);
6995//
6996// bool is_equality_cmp = (bin_op_type == BinOpTypeCmpEq || bin_op_type == BinOpTypeCmpNotEq);
6997//
6998// switch (resolved_type->id) {
6999// case TypeTableEntryIdInvalid:
7000// return g->builtin_types.entry_invalid;
7001//
7002// case TypeTableEntryIdNumLitFloat:
7003// case TypeTableEntryIdNumLitInt:
7004// case TypeTableEntryIdInt:
7005// case TypeTableEntryIdFloat:
7006// break;
7007//
7008// case TypeTableEntryIdBool:
7009// case TypeTableEntryIdMetaType:
7010// case TypeTableEntryIdVoid:
7011// case TypeTableEntryIdPointer:
7012// case TypeTableEntryIdPureError:
7013// case TypeTableEntryIdFn:
7014// case TypeTableEntryIdTypeDecl:
7015// case TypeTableEntryIdNamespace:
7016// case TypeTableEntryIdBlock:
7017// case TypeTableEntryIdGenericFn:
7018// if (!is_equality_cmp) {
7019// add_node_error(g, node,
7020// buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));
7021// return g->builtin_types.entry_invalid;
7022// }
7023// break;
7024//
7025// case TypeTableEntryIdEnum:
7026// if (!is_equality_cmp || resolved_type->data.enumeration.gen_field_count != 0) {
7027// add_node_error(g, node,
7028// buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));
7029// return g->builtin_types.entry_invalid;
7030// }
7031// break;
7032//
7033// case TypeTableEntryIdUnreachable:
7034// case TypeTableEntryIdArray:
7035// case TypeTableEntryIdStruct:
7036// case TypeTableEntryIdUndefLit:
7037// case TypeTableEntryIdNullLit:
7038// case TypeTableEntryIdMaybe:
7039// case TypeTableEntryIdErrorUnion:
7040// case TypeTableEntryIdUnion:
7041// add_node_error(g, node,
7042// buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name)));
7043// return g->builtin_types.entry_invalid;
7044//
7045// case TypeTableEntryIdVar:
7046// zig_unreachable();
7047// }
7048//
7049// ConstExprValue *op1_val = &get_resolved_expr(*op1)->const_val;
7050// ConstExprValue *op2_val = &get_resolved_expr(*op2)->const_val;
7051// if (!op1_val->ok || !op2_val->ok) {
7052// return g->builtin_types.entry_bool;
7053// }
7054//
7055//
7056// ConstExprValue *out_val = &get_resolved_expr(node)->const_val;
7057// eval_const_expr_bin_op(op1_val, op1_type, bin_op_type, op2_val, op2_type, out_val);
7058// return g->builtin_types.entry_bool;
7059//
7060//}
7061//
7062////
7063//static TypeTableEntry *analyze_if(CodeGen *g, ImportTableEntry *import, BlockContext *parent_context,
7064// TypeTableEntry *expected_type, AstNode *node,
7065// AstNode **then_node, AstNode **else_node, bool cond_is_const, bool cond_bool_val)
7066//{
7067// if (!*else_node) {
7068// *else_node = create_ast_void_node(g, import, node);
7069// normalize_parent_ptrs(node);
7070// }
7071//
7072// BlockContext *then_context;
7073// BlockContext *else_context;
7074// if (cond_is_const) {
7075// if (cond_bool_val) {
7076// then_context = parent_context;
7077// else_context = new_block_context(node, parent_context);
7078//
7079// else_context->codegen_excluded = true;
7080// } else {
7081// then_context = new_block_context(node, parent_context);
7082// else_context = parent_context;
7083//
7084// then_context->codegen_excluded = true;
7085// }
7086// } else {
7087// then_context = parent_context;
7088// else_context = parent_context;
7089// }
7090//
7091// TypeTableEntry *then_type = nullptr;
7092// TypeTableEntry *else_type = nullptr;
7093//
7094// if (!then_context->codegen_excluded) {
7095// then_type = analyze_expression(g, import, then_context, expected_type, *then_node);
7096// if (then_type->id == TypeTableEntryIdInvalid) {
7097// return g->builtin_types.entry_invalid;
7098// }
7099// }
7100// if (!else_context->codegen_excluded) {
7101// else_type = analyze_expression(g, import, else_context, expected_type, *else_node);
7102// if (else_type->id == TypeTableEntryIdInvalid) {
7103// return g->builtin_types.entry_invalid;
7104// }
7105// }
7106//
7107// TypeTableEntry *result_type;
7108// if (then_context->codegen_excluded) {
7109// result_type = else_type;
7110// } else if (else_context->codegen_excluded) {
7111// result_type = then_type;
7112// } else if (expected_type) {
7113// result_type = (then_type->id == TypeTableEntryIdUnreachable) ? else_type : then_type;
7114// } else {
7115// AstNode *op_nodes[] = {*then_node, *else_node};
7116// TypeTableEntry *op_types[] = {then_type, else_type};
7117// result_type = resolve_peer_type_compatibility(g, import, parent_context, node, op_nodes, op_types, 2);
7118// }
7119//
7120// if (!cond_is_const) {
7121// return add_error_if_type_is_num_lit(g, result_type, node);
7122// }
7123//
7124// ConstExprValue *other_const_val;
7125// if (cond_bool_val) {
7126// other_const_val = &get_resolved_expr(*then_node)->const_val;
7127// } else {
7128// other_const_val = &get_resolved_expr(*else_node)->const_val;
7129// }
7130// if (!other_const_val->ok) {
7131// return add_error_if_type_is_num_lit(g, result_type, node);
7132// }
7133//
7134// ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
7135// *const_val = *other_const_val;
7136// // the condition depends on a compile var, so the entire if statement does too
7137// const_val->depends_on_compile_var = true;
7138// return result_type;
7139//}
7140//
71416735//static TypeTableEntry *bad_method_call(CodeGen *g, AstNode *node, TypeTableEntry *container_type,
71426736// TypeTableEntry *expected_param_type, FnTableEntry *fn_table_entry)
71436737//{
......@@ -8195,92 +7789,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
81957789// return g->builtin_types.entry_invalid;
81967790//}
81977791//
8198//static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
8199// TypeTableEntry *expected_type, AstNode *node, bool pointer_only)
8200//{
8201// Buf *variable_name = node->data.symbol_expr.symbol;
8202//
8203// auto primitive_table_entry = g->primitive_type_table.maybe_get(variable_name);
8204// if (primitive_table_entry) {
8205// return resolve_expr_const_val_as_type(g, node, primitive_table_entry->value, false);
8206// }
8207//
8208// VariableTableEntry *var = find_variable(g, context, variable_name);
8209// if (var) {
8210// TypeTableEntry *var_type = analyze_var_ref(g, node, var, context, false);
8211// return var_type;
8212// }
8213//
8214// AstNode *decl_node = find_decl(context, variable_name);
8215// if (decl_node) {
8216// return analyze_decl_ref(g, node, decl_node, pointer_only, context, false);
8217// }
8218//
8219// if (import->any_imports_failed) {
8220// // skip the error message since we had a failing import in this file
8221// // if an import breaks we don't need 9999 undeclared identifier errors
8222// return g->builtin_types.entry_invalid;
8223// }
8224//
8225// mark_impure_fn(g, context, node);
8226// add_node_error(g, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
8227// return g->builtin_types.entry_invalid;
8228//}
8229//
8230//static TypeTableEntry *analyze_decl_ref(CodeGen *g, AstNode *source_node, AstNode *decl_node,
8231// bool pointer_only, BlockContext *block_context, bool depends_on_compile_var)
8232//{
8233// resolve_top_level_decl(g, decl_node, pointer_only);
8234// TopLevelDecl *tld = get_as_top_level_decl(decl_node);
8235// if (tld->resolution == TldResolutionInvalid) {
8236// return g->builtin_types.entry_invalid;
8237// }
8238//
8239// if (decl_node->type == NodeTypeVariableDeclaration) {
8240// VariableTableEntry *var = decl_node->data.variable_declaration.variable;
8241// return analyze_var_ref(g, source_node, var, block_context, depends_on_compile_var);
8242// } else if (decl_node->type == NodeTypeFnProto) {
8243// FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry;
8244// assert(fn_entry->type_entry);
8245// if (fn_entry->type_entry->id == TypeTableEntryIdGenericFn) {
8246// return resolve_expr_const_val_as_generic_fn(g, source_node, fn_entry->type_entry, depends_on_compile_var);
8247// } else {
8248// return resolve_expr_const_val_as_fn(g, source_node, fn_entry, depends_on_compile_var);
8249// }
8250// } else if (decl_node->type == NodeTypeContainerDecl) {
8251// if (decl_node->data.struct_decl.generic_params.length > 0) {
8252// TypeTableEntry *type_entry = decl_node->data.struct_decl.generic_fn_type;
8253// assert(type_entry);
8254// return resolve_expr_const_val_as_generic_fn(g, source_node, type_entry, depends_on_compile_var);
8255// } else {
8256// return resolve_expr_const_val_as_type(g, source_node, decl_node->data.struct_decl.type_entry,
8257// depends_on_compile_var);
8258// }
8259// } else if (decl_node->type == NodeTypeTypeDecl) {
8260// return resolve_expr_const_val_as_type(g, source_node, decl_node->data.type_decl.child_type_entry,
8261// depends_on_compile_var);
8262// } else {
8263// zig_unreachable();
8264// }
8265//}
8266//
8267//static TypeTableEntry *analyze_var_ref(CodeGen *g, AstNode *source_node, VariableTableEntry *var,
8268// BlockContext *context, bool depends_on_compile_var)
8269//{
8270// get_resolved_expr(source_node)->variable = var;
8271// if (!var_is_pure(var, context)) {
8272// mark_impure_fn(g, context, source_node);
8273// }
8274// if (var->src_is_const && var->val_node) {
8275// ConstExprValue *other_const_val = &get_resolved_expr(var->val_node)->const_val;
8276// if (other_const_val->ok) {
8277// return resolve_expr_const_val_as_other_expr(g, source_node, var->val_node,
8278// depends_on_compile_var || var->force_depends_on_compile_var);
8279// }
8280// }
8281// return var->type;
8282//}
8283//
82847792//static TypeTableEntry *analyze_fn_proto_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
82857793// TypeTableEntry *expected_type, AstNode *node)
82867794//{
......@@ -8294,14 +7802,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
82947802// return resolve_expr_const_val_as_type(g, node, type_entry, false);
82957803//}
82967804//
8297//static bool var_is_pure(VariableTableEntry *var, BlockContext *context) {
8298// if (var->block_context->fn_entry == context->fn_entry) {
8299// // variable was declared in the current function, so it's OK.
8300// return true;
8301// }
8302// return var->src_is_const && var->type->deep_const;
8303//}
8304//
83057805//static void validate_voided_expr(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry) {
83067806// if (type_entry->id == TypeTableEntryIdMetaType) {
83077807// add_node_error(g, first_executing_node(source_node), buf_sprintf("expected expression, found type"));
......@@ -8949,54 +8449,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no
89498449//}
89508450//
89518451//
8952//static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node,
8953// TypeTableEntry **out_type_entry)
8954//{
8955// LLVMValueRef target_ref;
8956//
8957// if (node->type == NodeTypeSymbol) {
8958// VariableTableEntry *var = get_resolved_expr(node)->variable;
8959// assert(var);
8960//
8961// *out_type_entry = var->type;
8962// target_ref = var->value_ref;
8963// } else if (node->type == NodeTypeArrayAccessExpr) {
8964// TypeTableEntry *array_type = get_expr_type(node->data.array_access_expr.array_ref_expr);
8965// if (array_type->id == TypeTableEntryIdArray) {
8966// *out_type_entry = array_type->data.array.child_type;
8967// target_ref = gen_array_ptr(g, node);
8968// } else if (array_type->id == TypeTableEntryIdPointer) {
8969// *out_type_entry = array_type->data.pointer.child_type;
8970// target_ref = gen_array_ptr(g, node);
8971// } else if (array_type->id == TypeTableEntryIdStruct) {
8972// assert(array_type->data.structure.is_slice);
8973// *out_type_entry = array_type->data.structure.fields[0].type_entry->data.pointer.child_type;
8974// target_ref = gen_array_ptr(g, node);
8975// } else {
8976// zig_unreachable();
8977// }
8978// } else if (node->type == NodeTypeFieldAccessExpr) {
8979// AstNode *struct_expr_node = node->data.field_access_expr.struct_expr;
8980// TypeTableEntry *struct_type = get_expr_type(struct_expr_node);
8981// if (struct_type->id == TypeTableEntryIdNamespace) {
8982// target_ref = gen_field_access_expr(g, node, true);
8983// *out_type_entry = get_expr_type(node);
8984// } else {
8985// target_ref = gen_field_ptr(g, node, out_type_entry);
8986// }
8987// } else if (node->type == NodeTypePrefixOpExpr) {
8988// assert(node->data.prefix_op_expr.prefix_op == PrefixOpDereference);
8989// AstNode *target_expr = node->data.prefix_op_expr.primary_expr;
8990// TypeTableEntry *type_entry = get_expr_type(target_expr);
8991// assert(type_entry->id == TypeTableEntryIdPointer);
8992// *out_type_entry = type_entry->data.pointer.child_type;
8993// return gen_expr(g, target_expr);
8994// } else {
8995// zig_panic("bad assign target");
8996// }
8997//
8998// return target_ref;
8999//}
90008452//
90018453//static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) {
90028454// assert(node->type == NodeTypeBinOpExpr);
src/ir_print.cpp+23-9
......@@ -115,6 +115,12 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
115115 }
116116 break;
117117 }
118 case TypeTableEntryIdNamespace:
119 {
120 ImportTableEntry *import = const_val->data.x_import;
121 fprintf(irp->f, "(namespace: %s)", buf_ptr(import->path));
122 break;
123 }
118124 case TypeTableEntryIdVar:
119125 case TypeTableEntryIdFloat:
120126 case TypeTableEntryIdStruct:
......@@ -124,7 +130,6 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
124130 case TypeTableEntryIdEnum:
125131 case TypeTableEntryIdUnion:
126132 case TypeTableEntryIdTypeDecl:
127 case TypeTableEntryIdNamespace:
128133 case TypeTableEntryIdGenericFn:
129134 zig_panic("TODO render more constant types in IR printer");
130135 }
......@@ -407,11 +412,6 @@ static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction)
407412 fprintf(irp->f, ")");
408413}
409414
410static void ir_print_read_field(IrPrint *irp, IrInstructionReadField *instruction) {
411 ir_print_other_instruction(irp, instruction->container_ptr);
412 fprintf(irp->f, ".%s", buf_ptr(instruction->field_name));
413}
414
415415static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr *instruction) {
416416 fprintf(irp->f, "@StructFieldPtr(&");
417417 ir_print_other_instruction(irp, instruction->struct_ptr);
......@@ -575,6 +575,17 @@ static void ir_print_static_eval(IrPrint *irp, IrInstructionStaticEval *instruct
575575 fprintf(irp->f, ")");
576576}
577577
578static void ir_print_import(IrPrint *irp, IrInstructionImport *instruction) {
579 fprintf(irp->f, "@import(");
580 ir_print_other_instruction(irp, instruction->name);
581 fprintf(irp->f, ")");
582}
583
584static void ir_print_array_len(IrPrint *irp, IrInstructionArrayLen *instruction) {
585 ir_print_other_instruction(irp, instruction->array_value);
586 fprintf(irp->f, ".len");
587}
588
578589static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
579590 ir_print_prefix(irp, instruction);
580591 switch (instruction->id) {
......@@ -643,9 +654,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
643654 case IrInstructionIdFieldPtr:
644655 ir_print_field_ptr(irp, (IrInstructionFieldPtr *)instruction);
645656 break;
646 case IrInstructionIdReadField:
647 ir_print_read_field(irp, (IrInstructionReadField *)instruction);
648 break;
649657 case IrInstructionIdStructFieldPtr:
650658 ir_print_struct_field_ptr(irp, (IrInstructionStructFieldPtr *)instruction);
651659 break;
......@@ -700,6 +708,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
700708 case IrInstructionIdStaticEval:
701709 ir_print_static_eval(irp, (IrInstructionStaticEval *)instruction);
702710 break;
711 case IrInstructionIdImport:
712 ir_print_import(irp, (IrInstructionImport *)instruction);
713 break;
714 case IrInstructionIdArrayLen:
715 ir_print_array_len(irp, (IrInstructionArrayLen *)instruction);
716 break;
703717 }
704718 fprintf(irp->f, "\n");
705719}
test/cases/namespace_fn_call.zig created+1
......@@ -0,0 +1 @@
1pub fn foo() -> i32 { 1234 }
test/self_hosted2.zig+7
......@@ -1,3 +1,5 @@
1const case_namespace_fn_call = @import("cases/namespace_fn_call.zig");
2
13pub const SYS_write = 1;
24pub const SYS_exit = 60;
35pub const stdout_fileno = 1;
......@@ -61,6 +63,10 @@ fn testInlineSwitch() {
6163 assert(result + 1 == 14);
6264}
6365
66fn testNamespaceFnCall() {
67 assert(case_namespace_fn_call.foo() == 1234);
68}
69
6470fn assert(ok: bool) {
6571 if (!ok)
6672 @unreachable();
......@@ -73,6 +79,7 @@ fn runAllTests() {
7379 switchWithNumbers();
7480 switchWithAllRanges();
7581 testInlineSwitch();
82 testNamespaceFnCall();
7683}
7784
7885export nakedcc fn _start() -> unreachable {