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 {...@@ -117,12 +117,6 @@ enum ReturnKnowledge {
117 ReturnKnowledgeSkipDefers,117 ReturnKnowledgeSkipDefers,
118};118};
119119
120struct Expr {
121 IrInstruction *instruction;
122 ReturnKnowledge return_knowledge;
123 VariableTableEntry *variable;
124};
125
126struct StructValExprCodeGen {120struct StructValExprCodeGen {
127 TypeTableEntry *type_entry;121 TypeTableEntry *type_entry;
128 LLVMValueRef ptr;122 LLVMValueRef ptr;
...@@ -152,6 +146,7 @@ struct TopLevelDecl {...@@ -152,6 +146,7 @@ struct TopLevelDecl {
152 bool dep_loop_flag;146 bool dep_loop_flag;
153 TldResolution resolution;147 TldResolution resolution;
154 AstNode *parent_decl;148 AstNode *parent_decl;
149 IrInstruction *value;
155};150};
156151
157struct TypeEnumField {152struct TypeEnumField {
...@@ -232,7 +227,6 @@ struct AstNodeFnProto {...@@ -232,7 +227,6 @@ struct AstNodeFnProto {
232 AstNode *fn_def_node;227 AstNode *fn_def_node;
233 FnTableEntry *fn_table_entry;228 FnTableEntry *fn_table_entry;
234 bool skip;229 bool skip;
235 Expr resolved_expr;
236 // computed from params field230 // computed from params field
237 size_t inline_arg_count;231 size_t inline_arg_count;
238 size_t inline_or_var_type_arg_count;232 size_t inline_or_var_type_arg_count;
...@@ -274,7 +268,6 @@ struct AstNodeBlock {...@@ -274,7 +268,6 @@ struct AstNodeBlock {
274 // you can follow its parents up to child_block. it will equal268 // you can follow its parents up to child_block. it will equal
275 // child_block if there are no defers or var decls in the block.269 // child_block if there are no defers or var decls in the block.
276 BlockContext *nested_block;270 BlockContext *nested_block;
277 Expr resolved_expr;
278};271};
279272
280enum ReturnKind {273enum ReturnKind {
...@@ -287,9 +280,6 @@ struct AstNodeReturnExpr {...@@ -287,9 +280,6 @@ struct AstNodeReturnExpr {
287 ReturnKind kind;280 ReturnKind kind;
288 // might be null in case of return void;281 // might be null in case of return void;
289 AstNode *expr;282 AstNode *expr;
290
291 // populated by semantic analyzer:
292 Expr resolved_expr;
293};283};
294284
295struct AstNodeDefer {285struct AstNodeDefer {
...@@ -297,7 +287,6 @@ struct AstNodeDefer {...@@ -297,7 +287,6 @@ struct AstNodeDefer {
297 AstNode *expr;287 AstNode *expr;
298288
299 // populated by semantic analyzer:289 // populated by semantic analyzer:
300 Expr resolved_expr;
301 size_t index_in_block;290 size_t index_in_block;
302 LLVMBasicBlockRef basic_block;291 LLVMBasicBlockRef basic_block;
303 BlockContext *child_block;292 BlockContext *child_block;
...@@ -314,7 +303,6 @@ struct AstNodeVariableDeclaration {...@@ -314,7 +303,6 @@ struct AstNodeVariableDeclaration {
314 AstNode *expr;303 AstNode *expr;
315304
316 // populated by semantic analyzer305 // populated by semantic analyzer
317 Expr resolved_expr;
318 VariableTableEntry *variable;306 VariableTableEntry *variable;
319};307};
320308
...@@ -392,7 +380,6 @@ struct AstNodeBinOpExpr {...@@ -392,7 +380,6 @@ struct AstNodeBinOpExpr {
392 // populated by semantic analyzer:380 // populated by semantic analyzer:
393 // for when op is BinOpTypeAssign381 // for when op is BinOpTypeAssign
394 VariableTableEntry *var_entry;382 VariableTableEntry *var_entry;
395 Expr resolved_expr;
396};383};
397384
398struct AstNodeUnwrapErrorExpr {385struct AstNodeUnwrapErrorExpr {
...@@ -401,7 +388,6 @@ struct AstNodeUnwrapErrorExpr {...@@ -401,7 +388,6 @@ struct AstNodeUnwrapErrorExpr {
401 AstNode *op2;388 AstNode *op2;
402389
403 // populated by semantic analyzer:390 // populated by semantic analyzer:
404 Expr resolved_expr;
405 VariableTableEntry *var;391 VariableTableEntry *var;
406};392};
407393
...@@ -434,7 +420,6 @@ struct AstNodeFnCallExpr {...@@ -434,7 +420,6 @@ struct AstNodeFnCallExpr {
434420
435 // populated by semantic analyzer:421 // populated by semantic analyzer:
436 BuiltinFnEntry *builtin_fn;422 BuiltinFnEntry *builtin_fn;
437 Expr resolved_expr;
438 FnTableEntry *fn_entry;423 FnTableEntry *fn_entry;
439 CastOp cast_op;424 CastOp cast_op;
440 // if cast_op is CastOpArrayToString, this will be a pointer to425 // if cast_op is CastOpArrayToString, this will be a pointer to
...@@ -447,7 +432,6 @@ struct AstNodeArrayAccessExpr {...@@ -447,7 +432,6 @@ struct AstNodeArrayAccessExpr {
447 AstNode *subscript;432 AstNode *subscript;
448433
449 // populated by semantic analyzer:434 // populated by semantic analyzer:
450 Expr resolved_expr;
451};435};
452436
453struct AstNodeSliceExpr {437struct AstNodeSliceExpr {
...@@ -457,7 +441,6 @@ struct AstNodeSliceExpr {...@@ -457,7 +441,6 @@ struct AstNodeSliceExpr {
457 bool is_const;441 bool is_const;
458442
459 // populated by semantic analyzer:443 // populated by semantic analyzer:
460 Expr resolved_expr;
461 StructValExprCodeGen resolved_struct_val_expr;444 StructValExprCodeGen resolved_struct_val_expr;
462};445};
463446
...@@ -468,7 +451,6 @@ struct AstNodeFieldAccessExpr {...@@ -468,7 +451,6 @@ struct AstNodeFieldAccessExpr {
468 // populated by semantic analyzer451 // populated by semantic analyzer
469 TypeStructField *type_struct_field;452 TypeStructField *type_struct_field;
470 TypeEnumField *type_enum_field;453 TypeEnumField *type_enum_field;
471 Expr resolved_expr;
472 StructValExprCodeGen resolved_struct_val_expr; // for enum values454 StructValExprCodeGen resolved_struct_val_expr; // for enum values
473 TypeTableEntry *bare_container_type;455 TypeTableEntry *bare_container_type;
474 bool is_member_fn;456 bool is_member_fn;
...@@ -495,7 +477,6 @@ struct AstNodePrefixOpExpr {...@@ -495,7 +477,6 @@ struct AstNodePrefixOpExpr {
495 AstNode *primary_expr;477 AstNode *primary_expr;
496478
497 // populated by semantic analyzer479 // populated by semantic analyzer
498 Expr resolved_expr;
499};480};
500481
501struct AstNodeUse {482struct AstNodeUse {
...@@ -511,7 +492,6 @@ struct AstNodeIfBoolExpr {...@@ -511,7 +492,6 @@ struct AstNodeIfBoolExpr {
511 AstNode *else_node; // null, block node, or other if expr node492 AstNode *else_node; // null, block node, or other if expr node
512493
513 // populated by semantic analyzer494 // populated by semantic analyzer
514 Expr resolved_expr;
515};495};
516496
517struct AstNodeIfVarExpr {497struct AstNodeIfVarExpr {
...@@ -522,7 +502,6 @@ struct AstNodeIfVarExpr {...@@ -522,7 +502,6 @@ struct AstNodeIfVarExpr {
522502
523 // populated by semantic analyzer503 // populated by semantic analyzer
524 TypeTableEntry *type;504 TypeTableEntry *type;
525 Expr resolved_expr;
526};505};
527506
528struct AstNodeWhileExpr {507struct AstNodeWhileExpr {
...@@ -535,7 +514,6 @@ struct AstNodeWhileExpr {...@@ -535,7 +514,6 @@ struct AstNodeWhileExpr {
535 bool condition_always_true;514 bool condition_always_true;
536 bool contains_break;515 bool contains_break;
537 bool contains_continue;516 bool contains_continue;
538 Expr resolved_expr;
539};517};
540518
541struct AstNodeForExpr {519struct AstNodeForExpr {
...@@ -549,7 +527,6 @@ struct AstNodeForExpr {...@@ -549,7 +527,6 @@ struct AstNodeForExpr {
549 // populated by semantic analyzer527 // populated by semantic analyzer
550 bool contains_break;528 bool contains_break;
551 bool contains_continue;529 bool contains_continue;
552 Expr resolved_expr;
553 VariableTableEntry *elem_var;530 VariableTableEntry *elem_var;
554 VariableTableEntry *index_var;531 VariableTableEntry *index_var;
555};532};
...@@ -560,7 +537,6 @@ struct AstNodeSwitchExpr {...@@ -560,7 +537,6 @@ struct AstNodeSwitchExpr {
560 bool is_inline;537 bool is_inline;
561538
562 // populated by semantic analyzer539 // populated by semantic analyzer
563 Expr resolved_expr;
564};540};
565541
566struct AstNodeSwitchProng {542struct AstNodeSwitchProng {
...@@ -580,7 +556,6 @@ struct AstNodeLabel {...@@ -580,7 +556,6 @@ struct AstNodeLabel {
580 Buf *name;556 Buf *name;
581557
582 // populated by semantic analyzer558 // populated by semantic analyzer
583 Expr resolved_expr;
584 LabelTableEntry *label_entry;559 LabelTableEntry *label_entry;
585};560};
586561
...@@ -588,7 +563,6 @@ struct AstNodeGoto {...@@ -588,7 +563,6 @@ struct AstNodeGoto {
588 Buf *name;563 Buf *name;
589564
590 // populated by semantic analyzer565 // populated by semantic analyzer
591 Expr resolved_expr;
592 LabelTableEntry *label_entry;566 LabelTableEntry *label_entry;
593};567};
594568
...@@ -634,7 +608,6 @@ struct AstNodeAsmExpr {...@@ -634,7 +608,6 @@ struct AstNodeAsmExpr {
634 ZigList<Buf*> clobber_list;608 ZigList<Buf*> clobber_list;
635609
636 // populated by semantic analyzer610 // populated by semantic analyzer
637 Expr resolved_expr;
638};611};
639612
640enum ContainerKind {613enum ContainerKind {
...@@ -670,14 +643,12 @@ struct AstNodeStringLiteral {...@@ -670,14 +643,12 @@ struct AstNodeStringLiteral {
670 bool c;643 bool c;
671644
672 // populated by semantic analyzer:645 // populated by semantic analyzer:
673 Expr resolved_expr;
674};646};
675647
676struct AstNodeCharLiteral {648struct AstNodeCharLiteral {
677 uint8_t value;649 uint8_t value;
678650
679 // populated by semantic analyzer:651 // populated by semantic analyzer:
680 Expr resolved_expr;
681};652};
682653
683struct AstNodeNumberLiteral {654struct AstNodeNumberLiteral {
...@@ -688,7 +659,6 @@ struct AstNodeNumberLiteral {...@@ -688,7 +659,6 @@ struct AstNodeNumberLiteral {
688 bool overflow;659 bool overflow;
689660
690 // populated by semantic analyzer661 // populated by semantic analyzer
691 Expr resolved_expr;
692};662};
693663
694struct AstNodeStructValueField {664struct AstNodeStructValueField {
...@@ -711,35 +681,29 @@ struct AstNodeContainerInitExpr {...@@ -711,35 +681,29 @@ struct AstNodeContainerInitExpr {
711681
712 // populated by semantic analyzer682 // populated by semantic analyzer
713 StructValExprCodeGen resolved_struct_val_expr;683 StructValExprCodeGen resolved_struct_val_expr;
714 Expr resolved_expr;
715 TypeTableEntry *enum_type;684 TypeTableEntry *enum_type;
716};685};
717686
718struct AstNodeNullLiteral {687struct AstNodeNullLiteral {
719 // populated by semantic analyzer688 // populated by semantic analyzer
720 Expr resolved_expr;
721};689};
722690
723struct AstNodeUndefinedLiteral {691struct AstNodeUndefinedLiteral {
724 // populated by semantic analyzer692 // populated by semantic analyzer
725 Expr resolved_expr;
726};693};
727694
728struct AstNodeZeroesLiteral {695struct AstNodeZeroesLiteral {
729 // populated by semantic analyzer696 // populated by semantic analyzer
730 Expr resolved_expr;
731};697};
732698
733struct AstNodeThisLiteral {699struct AstNodeThisLiteral {
734 // populated by semantic analyzer700 // populated by semantic analyzer
735 Expr resolved_expr;
736};701};
737702
738struct AstNodeSymbolExpr {703struct AstNodeSymbolExpr {
739 Buf *symbol;704 Buf *symbol;
740705
741 // populated by semantic analyzer706 // populated by semantic analyzer
742 Expr resolved_expr;
743 TypeEnumField *enum_field;707 TypeEnumField *enum_field;
744 uint32_t err_value;708 uint32_t err_value;
745};709};
...@@ -748,17 +712,14 @@ struct AstNodeBoolLiteral {...@@ -748,17 +712,14 @@ struct AstNodeBoolLiteral {
748 bool value;712 bool value;
749713
750 // populated by semantic analyzer714 // populated by semantic analyzer
751 Expr resolved_expr;
752};715};
753716
754struct AstNodeBreakExpr {717struct AstNodeBreakExpr {
755 // populated by semantic analyzer718 // populated by semantic analyzer
756 Expr resolved_expr;
757};719};
758720
759struct AstNodeContinueExpr {721struct AstNodeContinueExpr {
760 // populated by semantic analyzer722 // populated by semantic analyzer
761 Expr resolved_expr;
762};723};
763724
764struct AstNodeArrayType {725struct AstNodeArrayType {
...@@ -767,22 +728,18 @@ struct AstNodeArrayType {...@@ -767,22 +728,18 @@ struct AstNodeArrayType {
767 bool is_const;728 bool is_const;
768729
769 // populated by semantic analyzer730 // populated by semantic analyzer
770 Expr resolved_expr;
771};731};
772732
773struct AstNodeErrorType {733struct AstNodeErrorType {
774 // populated by semantic analyzer734 // populated by semantic analyzer
775 Expr resolved_expr;
776};735};
777736
778struct AstNodeTypeLiteral {737struct AstNodeTypeLiteral {
779 // populated by semantic analyzer738 // populated by semantic analyzer
780 Expr resolved_expr;
781};739};
782740
783struct AstNodeVarLiteral {741struct AstNodeVarLiteral {
784 // populated by semantic analyzer742 // populated by semantic analyzer
785 Expr resolved_expr;
786};743};
787744
788struct AstNode {745struct AstNode {
...@@ -1329,7 +1286,6 @@ struct CodeGen {...@@ -1329,7 +1286,6 @@ struct CodeGen {
1329 LLVMValueRef err_name_table;1286 LLVMValueRef err_name_table;
13301287
1331 IrInstruction *invalid_instruction;1288 IrInstruction *invalid_instruction;
1332 Buf *len_buf;
1333};1289};
13341290
1335struct VariableTableEntry {1291struct VariableTableEntry {
...@@ -1389,9 +1345,6 @@ struct BlockContext {...@@ -1389,9 +1345,6 @@ struct BlockContext {
1389 ZigLLVMDIScope *di_scope;1345 ZigLLVMDIScope *di_scope;
1390 Buf *c_import_buf;1346 Buf *c_import_buf;
13911347
1392 // if this is true, then this code will not be generated
1393 bool codegen_excluded;
1394
1395 bool safety_off;1348 bool safety_off;
1396 AstNode *safety_set_node;1349 AstNode *safety_set_node;
1397};1350};
...@@ -1433,7 +1386,6 @@ enum IrInstructionId {...@@ -1433,7 +1386,6 @@ enum IrInstructionId {
1433 IrInstructionIdStorePtr,1386 IrInstructionIdStorePtr,
1434 IrInstructionIdFieldPtr,1387 IrInstructionIdFieldPtr,
1435 IrInstructionIdStructFieldPtr,1388 IrInstructionIdStructFieldPtr,
1436 IrInstructionIdReadField,
1437 IrInstructionIdElemPtr,1389 IrInstructionIdElemPtr,
1438 IrInstructionIdVarPtr,1390 IrInstructionIdVarPtr,
1439 IrInstructionIdCall,1391 IrInstructionIdCall,
...@@ -1460,6 +1412,8 @@ enum IrInstructionId {...@@ -1460,6 +1412,8 @@ enum IrInstructionId {
1460 IrInstructionIdClz,1412 IrInstructionIdClz,
1461 IrInstructionIdCtz,1413 IrInstructionIdCtz,
1462 IrInstructionIdStaticEval,1414 IrInstructionIdStaticEval,
1415 IrInstructionIdImport,
1416 IrInstructionIdArrayLen,
1463};1417};
14641418
1465struct IrInstruction {1419struct IrInstruction {
...@@ -1628,13 +1582,6 @@ struct IrInstructionStructFieldPtr {...@@ -1628,13 +1582,6 @@ struct IrInstructionStructFieldPtr {
1628 bool is_const;1582 bool is_const;
1629};1583};
16301584
1631struct IrInstructionReadField {
1632 IrInstruction base;
1633
1634 IrInstruction *container_ptr;
1635 Buf *field_name;
1636};
1637
1638struct IrInstructionElemPtr {1585struct IrInstructionElemPtr {
1639 IrInstruction base;1586 IrInstruction base;
16401587
...@@ -1816,6 +1763,18 @@ struct IrInstructionStaticEval {...@@ -1816,6 +1763,18 @@ struct IrInstructionStaticEval {
1816 IrInstruction *value;1763 IrInstruction *value;
1817};1764};
18181765
1766struct IrInstructionImport {
1767 IrInstruction base;
1768
1769 IrInstruction *name;
1770};
1771
1772struct IrInstructionArrayLen {
1773 IrInstruction base;
1774
1775 IrInstruction *array_value;
1776};
1777
1819enum LValPurpose {1778enum LValPurpose {
1820 LValPurposeNone,1779 LValPurposeNone,
1821 LValPurposeAssign,1780 LValPurposeAssign,
src/analyze.cpp+40-135
...@@ -19,7 +19,6 @@...@@ -19,7 +19,6 @@
1919
20static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type);20static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type);
21static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type);21static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type);
22static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node);
2322
24AstNode *first_executing_node(AstNode *node) {23AstNode *first_executing_node(AstNode *node) {
25 switch (node->type) {24 switch (node->type) {
...@@ -1670,7 +1669,7 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {...@@ -1670,7 +1669,7 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {
1670 node->data.error_value_decl.top_level_decl.resolution = TldResolutionOk;1669 node->data.error_value_decl.top_level_decl.resolution = TldResolutionOk;
1671}1670}
16721671
1673static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node) {1672void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *context, AstNode *node) {
1674 switch (node->type) {1673 switch (node->type) {
1675 case NodeTypeRoot:1674 case NodeTypeRoot:
1676 for (size_t i = 0; i < import->root->data.root.top_level_decls.length; i += 1) {1675 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...@@ -1947,9 +1946,8 @@ static void resolve_var_decl(CodeGen *g, ImportTableEntry *import, AstNode *node
1947 implicit_type = g->builtin_types.entry_invalid;1946 implicit_type = g->builtin_types.entry_invalid;
1948 }1947 }
1949 if (implicit_type->id != TypeTableEntryIdInvalid) {1948 if (implicit_type->id != TypeTableEntryIdInvalid) {
1950 Expr *expr = get_resolved_expr(var_decl->expr);
1951 assert(result->static_value.special != ConstValSpecialRuntime);1949 assert(result->static_value.special != ConstValSpecialRuntime);
1952 expr->instruction = result;1950 var_decl->top_level_decl.value = result;
1953 }1951 }
1954 } else if (!is_extern) {1952 } else if (!is_extern) {
1955 add_node_error(g, node, buf_sprintf("variables must be initialized"));1953 add_node_error(g, node, buf_sprintf("variables must be initialized"));
...@@ -2206,7 +2204,6 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {...@@ -2206,7 +2204,6 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
2206 if (parent) {2204 if (parent) {
2207 context->parent_loop_node = parent->parent_loop_node;2205 context->parent_loop_node = parent->parent_loop_node;
2208 context->c_import_buf = parent->c_import_buf;2206 context->c_import_buf = parent->c_import_buf;
2209 context->codegen_excluded = parent->codegen_excluded;
2210 }2207 }
22112208
2212 if (node && node->type == NodeTypeFnDef) {2209 if (node && node->type == NodeTypeFnDef) {
...@@ -2455,17 +2452,16 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -2455,17 +2452,16 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
24552452
2456static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node) {2453static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node) {
2457 TopLevelDecl *tld = get_as_top_level_decl(dst_use_node);2454 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) {
2462 tld->import->any_imports_failed = true;2458 tld->import->any_imports_failed = true;
2463 return;2459 return;
2464 }2460 }
24652461
2466 tld->resolution = TldResolutionOk;2462 tld->resolution = TldResolutionOk;
24672463
2468 ConstExprValue *const_val = &expr->instruction->static_value;2464 ConstExprValue *const_val = &use_target_value->static_value;
2469 assert(const_val->special != ConstValSpecialRuntime);2465 assert(const_val->special != ConstValSpecialRuntime);
24702466
2471 ImportTableEntry *target_import = const_val->data.x_import;2467 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 *...@@ -2511,7 +2507,7 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
25112507
2512}2508}
25132509
2514static void resolve_use_decl(CodeGen *g, AstNode *node) {2510void resolve_use_decl(CodeGen *g, AstNode *node) {
2515 assert(node->type == NodeTypeUse);2511 assert(node->type == NodeTypeUse);
2516 if (get_as_top_level_decl(node)->resolution != TldResolutionUnresolved) {2512 if (get_as_top_level_decl(node)->resolution != TldResolutionUnresolved) {
2517 return;2513 return;
...@@ -2519,7 +2515,7 @@ static void resolve_use_decl(CodeGen *g, AstNode *node) {...@@ -2519,7 +2515,7 @@ static void resolve_use_decl(CodeGen *g, AstNode *node) {
2519 add_symbols_from_import(g, node, node);2515 add_symbols_from_import(g, node, node);
2520}2516}
25212517
2522static void preview_use_decl(CodeGen *g, AstNode *node) {2518void preview_use_decl(CodeGen *g, AstNode *node) {
2523 assert(node->type == NodeTypeUse);2519 assert(node->type == NodeTypeUse);
2524 TopLevelDecl *tld = get_as_top_level_decl(node);2520 TopLevelDecl *tld = get_as_top_level_decl(node);
25252521
...@@ -2637,97 +2633,6 @@ void semantic_analyze(CodeGen *g) {...@@ -2637,97 +2633,6 @@ void semantic_analyze(CodeGen *g) {
2637 }2633 }
2638}2634}
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
2731TopLevelDecl *get_as_top_level_decl(AstNode *node) {2636TopLevelDecl *get_as_top_level_decl(AstNode *node) {
2732 switch (node->type) {2637 switch (node->type) {
2733 case NodeTypeVariableDeclaration:2638 case NodeTypeVariableDeclaration:
...@@ -2997,40 +2902,42 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)...@@ -2997,40 +2902,42 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)
2997}2902}
29982903
2999uint32_t generic_fn_type_id_hash(GenericFnTypeId *id) {2904uint32_t generic_fn_type_id_hash(GenericFnTypeId *id) {
3000 uint32_t result = 0;2905 zig_panic("TODO generic_fn_type_id_hash");
3001 result += hash_ptr(id->decl_node);2906 //uint32_t result = 0;
3002 for (size_t i = 0; i < id->generic_param_count; i += 1) {2907 //result += hash_ptr(id->decl_node);
3003 GenericParamValue *generic_param = &id->generic_params[i];2908 //for (size_t i = 0; i < id->generic_param_count; i += 1) {
3004 if (generic_param->node) {2909 // GenericParamValue *generic_param = &id->generic_params[i];
3005 ConstExprValue *const_val = &get_resolved_expr(generic_param->node)->instruction->static_value;2910 // if (generic_param->node) {
3006 assert(const_val->special != ConstValSpecialRuntime);2911 // ConstExprValue *const_val = &get_resolved_expr(generic_param->node)->instruction->static_value;
3007 result += hash_const_val(generic_param->type, const_val);2912 // assert(const_val->special != ConstValSpecialRuntime);
3008 }2913 // result += hash_const_val(generic_param->type, const_val);
3009 result += hash_ptr(generic_param->type);2914 // }
3010 }2915 // result += hash_ptr(generic_param->type);
3011 return result;2916 //}
2917 //return result;
3012}2918}
30132919
3014bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) {2920bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) {
3015 if (a->decl_node != b->decl_node) return false;2921 zig_panic("TODO generic_fn_type_id_eql");
3016 assert(a->generic_param_count == b->generic_param_count);2922 //if (a->decl_node != b->decl_node) return false;
3017 for (size_t i = 0; i < a->generic_param_count; i += 1) {2923 //assert(a->generic_param_count == b->generic_param_count);
3018 GenericParamValue *a_val = &a->generic_params[i];2924 //for (size_t i = 0; i < a->generic_param_count; i += 1) {
3019 GenericParamValue *b_val = &b->generic_params[i];2925 // GenericParamValue *a_val = &a->generic_params[i];
3020 if (a_val->type != b_val->type) return false;2926 // GenericParamValue *b_val = &b->generic_params[i];
3021 if (a_val->node && b_val->node) {2927 // if (a_val->type != b_val->type) return false;
3022 ConstExprValue *a_const_val = &get_resolved_expr(a_val->node)->instruction->static_value;2928 // if (a_val->node && b_val->node) {
3023 ConstExprValue *b_const_val = &get_resolved_expr(b_val->node)->instruction->static_value;2929 // ConstExprValue *a_const_val = &get_resolved_expr(a_val->node)->instruction->static_value;
3024 assert(a_const_val->special != ConstValSpecialRuntime);2930 // ConstExprValue *b_const_val = &get_resolved_expr(b_val->node)->instruction->static_value;
3025 assert(b_const_val->special != ConstValSpecialRuntime);2931 // assert(a_const_val->special != ConstValSpecialRuntime);
3026 if (!const_values_equal(a_const_val, b_const_val, a_val->type)) {2932 // assert(b_const_val->special != ConstValSpecialRuntime);
3027 return false;2933 // if (!const_values_equal(a_const_val, b_const_val, a_val->type)) {
3028 }2934 // return false;
3029 } else {2935 // }
3030 assert(!a_val->node && !b_val->node);2936 // } else {
3031 }2937 // assert(!a_val->node && !b_val->node);
3032 }2938 // }
3033 return true;2939 //}
2940 //return true;
3034}2941}
30352942
3036bool type_has_bits(TypeTableEntry *type_entry) {2943bool type_has_bits(TypeTableEntry *type_entry) {
...@@ -3095,5 +3002,3 @@ uint64_t get_memcpy_align(CodeGen *g, TypeTableEntry *type_entry) {...@@ -3095,5 +3002,3 @@ uint64_t get_memcpy_align(CodeGen *g, TypeTableEntry *type_entry) {
3095 TypeTableEntry *first_type_in_mem = type_of_first_thing_in_memory(type_entry);3002 TypeTableEntry *first_type_in_mem = type_of_first_thing_in_memory(type_entry);
3096 return LLVMABISizeOfType(g->target_data_ref, first_type_in_mem->type_ref);3003 return LLVMABISizeOfType(g->target_data_ref, first_type_in_mem->type_ref);
3097}3004}
3098
3099
src/analyze.hpp+3-1
...@@ -16,7 +16,6 @@ ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *m...@@ -16,7 +16,6 @@ ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *m
16TypeTableEntry *new_type_table_entry(TypeTableEntryId id);16TypeTableEntry *new_type_table_entry(TypeTableEntryId id);
17TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);17TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
18BlockContext *new_block_context(AstNode *node, BlockContext *parent);18BlockContext *new_block_context(AstNode *node, BlockContext *parent);
19Expr *get_resolved_expr(AstNode *node);
20bool is_node_void_expr(AstNode *node);19bool is_node_void_expr(AstNode *node);
21uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);20uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry);
22TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, size_t size_in_bits);21TypeTableEntry **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);...@@ -63,5 +62,8 @@ TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name);
63BlockContext *get_container_block_context(TypeTableEntry *type_entry);62BlockContext *get_container_block_context(TypeTableEntry *type_entry);
64TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name);63TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name);
65bool is_container_ref(TypeTableEntry *type_entry);64bool 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
67#endif69#endif
src/ast_render.cpp+15-16
...@@ -528,25 +528,24 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -528,25 +528,24 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
528 break;528 break;
529 }529 }
530 case NodeTypeFnCallExpr:530 case NodeTypeFnCallExpr:
531 if (node->data.fn_call_expr.is_builtin) {531 {
532 fprintf(ar->f, "@");532 if (node->data.fn_call_expr.is_builtin) {
533 } else {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);
534 fprintf(ar->f, "(");538 fprintf(ar->f, "(");
535 }539 for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
536 render_node_ungrouped(ar, node->data.fn_call_expr.fn_ref_expr);540 AstNode *param = node->data.fn_call_expr.params.at(i);
537 if (!node->data.fn_call_expr.is_builtin) {541 if (i != 0) {
538 fprintf(ar->f, ")");542 fprintf(ar->f, ", ");
539 }543 }
540 fprintf(ar->f, "(");544 render_node_grouped(ar, param);
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, ", ");
545 }545 }
546 render_node_grouped(ar, param);546 fprintf(ar->f, ")");
547 break;
547 }548 }
548 fprintf(ar->f, ")");
549 break;
550 case NodeTypeArrayAccessExpr:549 case NodeTypeArrayAccessExpr:
551 render_node_ungrouped(ar, node->data.array_access_expr.array_ref_expr);550 render_node_ungrouped(ar, node->data.array_access_expr.array_ref_expr);
552 fprintf(ar->f, "[");551 fprintf(ar->f, "[");
src/codegen.cpp+5-7
...@@ -65,8 +65,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {...@@ -65,8 +65,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
65 g->is_test_build = false;65 g->is_test_build = false;
66 g->want_h_file = true;66 g->want_h_file = true;
6767
68 g->len_buf = buf_create_from_str("len");
69
70 // the error.Ok value68 // the error.Ok value
71 g->error_decls.append(nullptr);69 g->error_decls.append(nullptr);
7270
...@@ -1682,6 +1680,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -1682,6 +1680,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
1682 case IrInstructionIdSizeOf:1680 case IrInstructionIdSizeOf:
1683 case IrInstructionIdSwitchTarget:1681 case IrInstructionIdSwitchTarget:
1684 case IrInstructionIdStaticEval:1682 case IrInstructionIdStaticEval:
1683 case IrInstructionIdImport:
1685 zig_unreachable();1684 zig_unreachable();
1686 case IrInstructionIdReturn:1685 case IrInstructionIdReturn:
1687 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);1686 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
...@@ -1728,8 +1727,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -1728,8 +1727,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
1728 case IrInstructionIdSwitchVar:1727 case IrInstructionIdSwitchVar:
1729 case IrInstructionIdContainerInitList:1728 case IrInstructionIdContainerInitList:
1730 case IrInstructionIdContainerInitFields:1729 case IrInstructionIdContainerInitFields:
1731 case IrInstructionIdReadField:
1732 case IrInstructionIdEnumTag:1730 case IrInstructionIdEnumTag:
1731 case IrInstructionIdArrayLen:
1733 zig_panic("TODO render more IR instructions to LLVM");1732 zig_panic("TODO render more IR instructions to LLVM");
1734 }1733 }
1735 zig_unreachable();1734 zig_unreachable();
...@@ -2114,7 +2113,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2114,7 +2113,7 @@ static void do_code_gen(CodeGen *g) {
21142113
2115 if (var->type->id == TypeTableEntryIdNumLitFloat) {2114 if (var->type->id == TypeTableEntryIdNumLitFloat) {
2116 // Generate debug info for it but that's it.2115 // 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;
2118 assert(const_val->special != ConstValSpecialRuntime);2117 assert(const_val->special != ConstValSpecialRuntime);
2119 TypeTableEntry *var_type = g->builtin_types.entry_f64;2118 TypeTableEntry *var_type = g->builtin_types.entry_f64;
2120 LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float);2119 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) {...@@ -2124,7 +2123,7 @@ static void do_code_gen(CodeGen *g) {
21242123
2125 if (var->type->id == TypeTableEntryIdNumLitInt) {2124 if (var->type->id == TypeTableEntryIdNumLitInt) {
2126 // Generate debug info for it but that's it.2125 // 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;
2128 assert(const_val->special != ConstValSpecialRuntime);2127 assert(const_val->special != ConstValSpecialRuntime);
2129 TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?2128 TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?
2130 g->builtin_types.entry_isize : g->builtin_types.entry_usize;2129 g->builtin_types.entry_isize : g->builtin_types.entry_usize;
...@@ -2149,8 +2148,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2149,8 +2148,7 @@ static void do_code_gen(CodeGen *g) {
21492148
2150 LLVMSetLinkage(global_value, LLVMExternalLinkage);2149 LLVMSetLinkage(global_value, LLVMExternalLinkage);
2151 } else {2150 } else {
2152 AstNode *expr_node = var->decl_node->data.variable_declaration.expr;2151 IrInstruction *instruction = var->decl_node->data.variable_declaration.top_level_decl.value;
2153 IrInstruction *instruction = get_resolved_expr(expr_node)->instruction;
2154 render_const_val(g, instruction->type_entry, &instruction->static_value);2152 render_const_val(g, instruction->type_entry, &instruction->static_value);
2155 render_const_val_global(g, instruction->type_entry, &instruction->static_value);2153 render_const_val_global(g, instruction->type_entry, &instruction->static_value);
2156 global_value = instruction->static_value.llvm_global;2154 global_value = instruction->static_value.llvm_global;
src/ir.cpp+308-856
...@@ -3,6 +3,7 @@...@@ -3,6 +3,7 @@
3#include "eval.hpp"3#include "eval.hpp"
4#include "ir.hpp"4#include "ir.hpp"
5#include "ir_print.hpp"5#include "ir_print.hpp"
6#include "os.hpp"
67
7struct IrExecContext {8struct IrExecContext {
8 ConstExprValue *mem_slot_list;9 ConstExprValue *mem_slot_list;
...@@ -159,10 +160,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr *...@@ -159,10 +160,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr *
159 return IrInstructionIdStructFieldPtr;160 return IrInstructionIdStructFieldPtr;
160}161}
161162
162static constexpr IrInstructionId ir_instruction_id(IrInstructionReadField *) {
163 return IrInstructionIdReadField;
164}
165
166static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) {163static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) {
167 return IrInstructionIdElemPtr;164 return IrInstructionIdElemPtr;
168}165}
...@@ -267,6 +264,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStaticEval *) {...@@ -267,6 +264,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStaticEval *) {
267 return IrInstructionIdStaticEval;264 return IrInstructionIdStaticEval;
268}265}
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
270template<typename T>275template<typename T>
271static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) {276static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) {
272 T *special_instruction = allocate<T>(1);277 T *special_instruction = allocate<T>(1);
...@@ -565,18 +570,6 @@ static IrInstruction *ir_build_field_ptr(IrBuilder *irb, AstNode *source_node,...@@ -565,18 +570,6 @@ static IrInstruction *ir_build_field_ptr(IrBuilder *irb, AstNode *source_node,
565 return &instruction->base;570 return &instruction->base;
566}571}
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
580static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, AstNode *source_node,573static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, AstNode *source_node,
581 IrInstruction *struct_ptr, TypeStructField *field)574 IrInstruction *struct_ptr, TypeStructField *field)
582{575{
...@@ -1087,6 +1080,32 @@ static IrInstruction *ir_build_static_eval(IrBuilder *irb, AstNode *source_node,...@@ -1087,6 +1080,32 @@ static IrInstruction *ir_build_static_eval(IrBuilder *irb, AstNode *source_node,
1087 return &instruction->base;1080 return &instruction->base;
1088}1081}
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
1090static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block,1109static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block,
1091 bool gen_error_defers, bool gen_maybe_defers)1110 bool gen_error_defers, bool gen_maybe_defers)
1092{1111{
...@@ -1376,7 +1395,7 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, AstNode *node) {...@@ -1376,7 +1395,7 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, AstNode *node) {
1376static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstNode *decl_node,1395static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstNode *decl_node,
1377 LValPurpose lval, BlockContext *scope)1396 LValPurpose lval, BlockContext *scope)
1378{1397{
1379 resolve_top_level_decl(irb->codegen, decl_node, lval);1398 resolve_top_level_decl(irb->codegen, decl_node, lval != LValPurposeNone);
1380 TopLevelDecl *tld = get_as_top_level_decl(decl_node);1399 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
1381 if (tld->resolution == TldResolutionInvalid)1400 if (tld->resolution == TldResolutionInvalid)
1382 return irb->codegen->invalid_instruction;1401 return irb->codegen->invalid_instruction;
...@@ -1492,15 +1511,16 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, AstNode *node, LValPur...@@ -1492,15 +1511,16 @@ static IrInstruction *ir_gen_field_access(IrBuilder *irb, AstNode *node, LValPur
1492 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;1511 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
1493 Buf *field_name = node->data.field_access_expr.field_name;1512 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);
1496 if (container_ref_instruction == irb->codegen->invalid_instruction)1516 if (container_ref_instruction == irb->codegen->invalid_instruction)
1497 return container_ref_instruction;1517 return container_ref_instruction;
14981518
1499 if (lval == LValPurposeNone) {1519 IrInstruction *ptr_instruction = ir_build_field_ptr(irb, node, container_ref_instruction, field_name);
1500 return ir_build_read_field(irb, node, container_ref_instruction, field_name);1520 if (lval != LValPurposeNone)
1501 } else {1521 return ptr_instruction;
1502 return ir_build_field_ptr(irb, node, container_ref_instruction, field_name);1522
1503 }1523 return ir_build_load_ptr(irb, node, ptr_instruction);
1504}1524}
15051525
1506static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {1526static 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) {...@@ -1628,6 +1648,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
16281648
1629 return ir_build_static_eval(irb, node, arg0_value);1649 return ir_build_static_eval(irb, node, arg0_value);
1630 }1650 }
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 }
1631 case BuiltinFnIdMemcpy:1665 case BuiltinFnIdMemcpy:
1632 case BuiltinFnIdMemset:1666 case BuiltinFnIdMemset:
1633 case BuiltinFnIdAlignof:1667 case BuiltinFnIdAlignof:
...@@ -1642,7 +1676,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {...@@ -1642,7 +1676,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
1642 case BuiltinFnIdCDefine:1676 case BuiltinFnIdCDefine:
1643 case BuiltinFnIdCUndef:1677 case BuiltinFnIdCUndef:
1644 case BuiltinFnIdCompileErr:1678 case BuiltinFnIdCompileErr:
1645 case BuiltinFnIdImport:
1646 case BuiltinFnIdCImport:1679 case BuiltinFnIdCImport:
1647 case BuiltinFnIdErrName:1680 case BuiltinFnIdErrName:
1648 case BuiltinFnIdBreakpoint:1681 case BuiltinFnIdBreakpoint:
...@@ -1978,7 +2011,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {...@@ -1978,7 +2011,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {
1978 IrBasicBlock *end_block = ir_build_basic_block(irb, "ForEnd");2011 IrBasicBlock *end_block = ir_build_basic_block(irb, "ForEnd");
1979 IrBasicBlock *continue_block = ir_build_basic_block(irb, "ForContinue");2012 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);
1982 ir_build_br(irb, node, cond_block, is_inline);2015 ir_build_br(irb, node, cond_block, is_inline);
19832016
1984 ir_set_cursor_at_end(irb, cond_block);2017 ir_set_cursor_at_end(irb, cond_block);
...@@ -2846,7 +2879,9 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in...@@ -2846,7 +2879,9 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in
2846 var_ptr_instruction->var = old_var_ptr_instruction->var;2879 var_ptr_instruction->var = old_var_ptr_instruction->var;
2847 new_instruction = &var_ptr_instruction->base;2880 new_instruction = &var_ptr_instruction->base;
2848 } else if (old_instruction->id == IrInstructionIdFieldPtr) {2881 } 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;
2850 } else if (old_instruction->id == IrInstructionIdElemPtr) {2885 } else if (old_instruction->id == IrInstructionIdElemPtr) {
2851 IrInstructionElemPtr *elem_ptr_instruction = ir_create_instruction<IrInstructionElemPtr>(ira->new_irb.exec,2886 IrInstructionElemPtr *elem_ptr_instruction = ir_create_instruction<IrInstructionElemPtr>(ira->new_irb.exec,
2852 old_instruction->source_node);2887 old_instruction->source_node);
...@@ -2868,6 +2903,17 @@ static TypeTableEntry *ir_analyze_void(IrAnalyze *ira, IrInstruction *instructio...@@ -2868,6 +2903,17 @@ static TypeTableEntry *ir_analyze_void(IrAnalyze *ira, IrInstruction *instructio
2868 return ira->codegen->builtin_types.entry_void;2903 return ira->codegen->builtin_types.entry_void;
2869}2904}
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
2871static TypeTableEntry *ir_analyze_const_usize(IrAnalyze *ira, IrInstruction *instruction, uint64_t value,2917static TypeTableEntry *ir_analyze_const_usize(IrAnalyze *ira, IrInstruction *instruction, uint64_t value,
2872 bool depends_on_compile_var)2918 bool depends_on_compile_var)
2873{2919{
...@@ -2889,9 +2935,6 @@ static TypeTableEntry *ir_resolve_type_lval(IrAnalyze *ira, IrInstruction *type_...@@ -2889,9 +2935,6 @@ static TypeTableEntry *ir_resolve_type_lval(IrAnalyze *ira, IrInstruction *type_
2889 if (lval != LValPurposeNone)2935 if (lval != LValPurposeNone)
2890 zig_panic("TODO");2936 zig_panic("TODO");
28912937
2892 if (type_value == ira->codegen->invalid_instruction)
2893 return ira->codegen->builtin_types.entry_invalid;
2894
2895 if (type_value->type_entry->id == TypeTableEntryIdInvalid)2938 if (type_value->type_entry->id == TypeTableEntryIdInvalid)
2896 return ira->codegen->builtin_types.entry_invalid;2939 return ira->codegen->builtin_types.entry_invalid;
28972940
...@@ -3810,7 +3853,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction...@@ -3810,7 +3853,7 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
3810 }3853 }
38113854
3812 ir_build_call_from(&ira->new_irb, &call_instruction->base,3855 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
3815 return ir_finish_anal(ira, fn_type->data.fn.fn_type_id.return_type);3858 return ir_finish_anal(ira, fn_type->data.fn.fn_type_id.return_type);
3816 } else {3859 } else {
...@@ -4286,14 +4329,11 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP...@@ -4286,14 +4329,11 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
4286 return resolved_type;4329 return resolved_type;
4287}4330}
42884331
4289static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) {4332static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction, VariableTableEntry *var) {
4290 VariableTableEntry *var = var_ptr_instruction->var;
4291 assert(var->type);4333 assert(var->type);
4292 if (var->type->id == TypeTableEntryIdInvalid)4334 if (var->type->id == TypeTableEntryIdInvalid)
4293 return var->type;4335 return var->type;
42944336
4295 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, var->type, false);
4296
4297 ConstExprValue *mem_slot = nullptr;4337 ConstExprValue *mem_slot = nullptr;
4298 if (var->block_context->fn_entry) {4338 if (var->block_context->fn_entry) {
4299 // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing.4339 // 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...@@ -4302,23 +4342,23 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct
4302 } else if (var->src_is_const) {4342 } else if (var->src_is_const) {
4303 AstNode *var_decl_node = var->decl_node;4343 AstNode *var_decl_node = var->decl_node;
4304 assert(var_decl_node->type == NodeTypeVariableDeclaration);4344 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;
4306 assert(mem_slot->special != ConstValSpecialRuntime);4346 assert(mem_slot->special != ConstValSpecialRuntime);
4307 }4347 }
43084348
4309 if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {4349 if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {
4310 ConstExprValue *out_val = ir_build_const_from(ira, &var_ptr_instruction->base,4350 return ir_analyze_const_ptr(ira, instruction, mem_slot, var->type, false);
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;
4316 } else {4351 } else {
4317 ir_build_var_ptr_from(&ira->new_irb, &var_ptr_instruction->base, var);4352 ir_build_var_ptr_from(&ira->new_irb, instruction, var);
4318 return ptr_type;4353 return get_pointer_to_type(ira->codegen, var->type, false);
4319 }4354 }
4320}4355}
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
4322static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) {4362static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) {
4323 IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other;4363 IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other;
4324 if (array_ptr->type_entry->id == TypeTableEntryIdInvalid)4364 if (array_ptr->type_entry->id == TypeTableEntryIdInvalid)
...@@ -4483,108 +4523,146 @@ static TypeTableEntry *ir_analyze_container_member_access(IrAnalyze *ira, Buf *f...@@ -4483,108 +4523,146 @@ static TypeTableEntry *ir_analyze_container_member_access(IrAnalyze *ira, Buf *f
4483 }4523 }
4484}4524}
44854525
4486static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) {4526static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, AstNode *decl_node,
4487 IrInstruction *container_ptr = field_ptr_instruction->container_ptr->other;4527 bool depends_on_compile_var)
4488 Buf *field_name = field_ptr_instruction->field_name;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;4535 if (decl_node->type == NodeTypeVariableDeclaration) {
4491 if (container_type->id == TypeTableEntryIdInvalid) {4536 VariableTableEntry *var = decl_node->data.variable_declaration.variable;
4492 return container_type;4537 return ir_analyze_var_ptr(ira, source_instruction, var);
4493 } else if (is_container_ref(container_type)) {4538 } else if (decl_node->type == NodeTypeFnProto) {
4494 return ir_analyze_container_member_access(ira, field_name, field_ptr_instruction, container_type);4539 FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry;
4495 } else if (container_type->id == TypeTableEntryIdArray) {4540 assert(fn_entry->type_entry);
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);
45084541
4509 if (child_type->id == TypeTableEntryIdInvalid) {4542 // TODO instead of allocating this every time, put it in the tld value and we can reference
4510 return ira->codegen->builtin_types.entry_invalid;4543 // the same one every time
4511 } else if (child_type->id == TypeTableEntryIdEnum) {4544 ConstExprValue *const_val = allocate<ConstExprValue>(1);
4512 zig_panic("TODO enum type field");4545 const_val->special = ConstValSpecialStatic;
4513 } else if (child_type->id == TypeTableEntryIdStruct) {4546 if (fn_entry->type_entry->id == TypeTableEntryIdGenericFn) {
4514 zig_panic("TODO struct type field");4547 const_val->data.x_type = fn_entry->type_entry;
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");
4519 } else {4548 } else {
4520 add_node_error(ira->codegen, field_ptr_instruction->base.source_node,4549 const_val->data.x_fn = fn_entry;
4521 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
4522 return ira->codegen->builtin_types.entry_invalid;
4523 }4550 }
4524 } else if (container_type->id == TypeTableEntryIdNamespace) {4551
4525 zig_panic("TODO namespace field access");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;
4526 } else {4570 } else {
4527 add_node_error(ira->codegen, field_ptr_instruction->base.source_node,4571 zig_unreachable();
4528 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
4529 return ira->codegen->builtin_types.entry_invalid;
4530 }4572 }
4531}4573}
45324574
4533static TypeTableEntry *ir_analyze_read_field_as_ptr_load(IrAnalyze *ira,4575static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) {
4534 IrInstructionReadField *read_field_instruction)4576 IrInstruction *container_ptr = field_ptr_instruction->container_ptr->other;
4535{4577 if (container_ptr->type_entry->id == TypeTableEntryIdInvalid)
4536 IrInstruction *old_field_ptr_inst = ir_build_field_ptr(&ira->old_irb, read_field_instruction->base.source_node,4578 return ira->codegen->builtin_types.entry_invalid;
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}
45454579
4546static TypeTableEntry *ir_analyze_instruction_read_field(IrAnalyze *ira,4580 assert(container_ptr->type_entry->id == TypeTableEntryIdPointer);
4547 IrInstructionReadField *read_field_instruction)4581 TypeTableEntry *container_type = container_ptr->type_entry->data.pointer.child_type;
4548{4582
4549 IrInstruction *container_ptr = read_field_instruction->container_ptr->other;4583 Buf *field_name = field_ptr_instruction->field_name;
4550 Buf *field_name = read_field_instruction->field_name;4584 AstNode *source_node = field_ptr_instruction->base.source_node;
45514585
4552 TypeTableEntry *container_type = container_ptr->type_entry;
4553 if (container_type->id == TypeTableEntryIdInvalid) {4586 if (container_type->id == TypeTableEntryIdInvalid) {
4554 return container_type;4587 return container_type;
4555 } else if (is_container_ref(container_type)) {4588 } 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);
4557 } else if (container_type->id == TypeTableEntryIdArray) {4590 } else if (container_type->id == TypeTableEntryIdArray) {
4558 if (buf_eql_str(field_name, "len")) {4591 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);
4560 } else {4598 } else {
4561 add_node_error(ira->codegen, read_field_instruction->base.source_node,4599 add_node_error(ira->codegen, source_node,
4562 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name),4600 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name),
4563 buf_ptr(&container_type->name)));4601 buf_ptr(&container_type->name)));
4564 return ira->codegen->builtin_types.entry_invalid;4602 return ira->codegen->builtin_types.entry_invalid;
4565 }4603 }
4566 } else if (container_type->id == TypeTableEntryIdMetaType) {4604 } else if (container_type->id == TypeTableEntryIdMetaType) {
4567 TypeTableEntry *child_type = ir_resolve_type(ira, container_ptr);4605 zig_panic("TODO type field access");
45684606 //TypeTableEntry *child_type = ir_resolve_type(ira, container_ptr);
4569 if (child_type->id == TypeTableEntryIdInvalid) {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)
4570 return ira->codegen->builtin_types.entry_invalid;4626 return ira->codegen->builtin_types.entry_invalid;
4571 } else if (child_type->id == TypeTableEntryIdEnum) {4627
4572 zig_panic("TODO enum type field");4628 ConstExprValue *namespace_val = const_ptr_pointee(container_ptr_val);
4573 } else if (child_type->id == TypeTableEntryIdStruct) {4629 assert(namespace_val->special == ConstValSpecialStatic);
4574 zig_panic("TODO struct type field");4630
4575 } else if (child_type->id == TypeTableEntryIdPureError) {4631 ImportTableEntry *namespace_import = namespace_val->data.x_import;
4576 zig_panic("TODO error type field");4632
4577 } else if (child_type->id == TypeTableEntryIdInt) {4633 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;
4578 zig_panic("TODO integer type field");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);
4579 } else {4658 } else {
4580 add_node_error(ira->codegen, read_field_instruction->base.source_node,4659 const char *import_name = namespace_import->path ? buf_ptr(namespace_import->path) : "(C import)";
4581 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));4660 add_node_error(ira->codegen, source_node,
4661 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), import_name));
4582 return ira->codegen->builtin_types.entry_invalid;4662 return ira->codegen->builtin_types.entry_invalid;
4583 }4663 }
4584 } else if (container_type->id == TypeTableEntryIdNamespace) {
4585 zig_panic("TODO namespace field access");
4586 } else {4664 } 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,
4588 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));4666 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name)));
4589 return ira->codegen->builtin_types.entry_invalid;4667 return ira->codegen->builtin_types.entry_invalid;
4590 }4668 }
...@@ -4610,7 +4688,7 @@ static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruc...@@ -4610,7 +4688,7 @@ static TypeTableEntry *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstruc
4610 return child_type;4688 return child_type;
4611 } else {4689 } else {
4612 add_node_error(ira->codegen, load_ptr_instruction->base.source_node,4690 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'",
4614 buf_ptr(&type_entry->name)));4692 buf_ptr(&type_entry->name)));
4615 return ira->codegen->builtin_types.entry_invalid;4693 return ira->codegen->builtin_types.entry_invalid;
4616 }4694 }
...@@ -5413,6 +5491,110 @@ static TypeTableEntry *ir_analyze_instruction_static_eval(IrAnalyze *ira,...@@ -5413,6 +5491,110 @@ static TypeTableEntry *ir_analyze_instruction_static_eval(IrAnalyze *ira,
5413 return value->type_entry;5491 return value->type_entry;
5414}5492}
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
5416static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {5598static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
5417 switch (instruction->id) {5599 switch (instruction->id) {
5418 case IrInstructionIdInvalid:5600 case IrInstructionIdInvalid:
...@@ -5437,8 +5619,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -5437,8 +5619,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
5437 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction);5619 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction);
5438 case IrInstructionIdFieldPtr:5620 case IrInstructionIdFieldPtr:
5439 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction);5621 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction);
5440 case IrInstructionIdReadField:
5441 return ir_analyze_instruction_read_field(ira, (IrInstructionReadField *)instruction);
5442 case IrInstructionIdCall:5622 case IrInstructionIdCall:
5443 return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction);5623 return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction);
5444 case IrInstructionIdBr:5624 case IrInstructionIdBr:
...@@ -5489,6 +5669,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -5489,6 +5669,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
5489 return ir_analyze_instruction_enum_tag(ira, (IrInstructionEnumTag *)instruction);5669 return ir_analyze_instruction_enum_tag(ira, (IrInstructionEnumTag *)instruction);
5490 case IrInstructionIdStaticEval:5670 case IrInstructionIdStaticEval:
5491 return ir_analyze_instruction_static_eval(ira, (IrInstructionStaticEval *)instruction);5671 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);
5492 case IrInstructionIdCast:5676 case IrInstructionIdCast:
5493 case IrInstructionIdContainerInitList:5677 case IrInstructionIdContainerInitList:
5494 case IrInstructionIdContainerInitFields:5678 case IrInstructionIdContainerInitFields:
...@@ -5580,6 +5764,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -5580,6 +5764,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
5580 case IrInstructionIdSetFnTest:5764 case IrInstructionIdSetFnTest:
5581 case IrInstructionIdSetFnVisible:5765 case IrInstructionIdSetFnVisible:
5582 case IrInstructionIdSetDebugSafety:5766 case IrInstructionIdSetDebugSafety:
5767 case IrInstructionIdImport:
5583 return true;5768 return true;
5584 case IrInstructionIdPhi:5769 case IrInstructionIdPhi:
5585 case IrInstructionIdUnOp:5770 case IrInstructionIdUnOp:
...@@ -5595,7 +5780,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -5595,7 +5780,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
5595 case IrInstructionIdTypeOf:5780 case IrInstructionIdTypeOf:
5596 case IrInstructionIdToPtrType:5781 case IrInstructionIdToPtrType:
5597 case IrInstructionIdPtrTypeChild:5782 case IrInstructionIdPtrTypeChild:
5598 case IrInstructionIdReadField:5783 case IrInstructionIdArrayLen:
5599 case IrInstructionIdStructFieldPtr:5784 case IrInstructionIdStructFieldPtr:
5600 case IrInstructionIdArrayType:5785 case IrInstructionIdArrayType:
5601 case IrInstructionIdSliceType:5786 case IrInstructionIdSliceType:
...@@ -5666,81 +5851,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -5666,81 +5851,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
5666// }5851// }
5667//}5852//}
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//
5744//static TypeTableEntry *analyze_c_import(CodeGen *g, ImportTableEntry *parent_import,5854//static TypeTableEntry *analyze_c_import(CodeGen *g, ImportTableEntry *parent_import,
5745// BlockContext *parent_context, AstNode *node)5855// BlockContext *parent_context, AstNode *node)
5746//{5856//{
...@@ -6615,38 +6725,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -6615,38 +6725,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
6615// buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));6725// buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));
6616// return g->builtin_types.entry_invalid;6726// return g->builtin_types.entry_invalid;
6617// }6727// }
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// }
6650// } else {6728// } else {
6651// add_node_error(g, node,6729// add_node_error(g, node,
6652// buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name)));6730// 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) {...@@ -6654,490 +6732,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
6654// }6732// }
6655//}6733//}
6656//6734//
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//
7141//static TypeTableEntry *bad_method_call(CodeGen *g, AstNode *node, TypeTableEntry *container_type,6735//static TypeTableEntry *bad_method_call(CodeGen *g, AstNode *node, TypeTableEntry *container_type,
7142// TypeTableEntry *expected_param_type, FnTableEntry *fn_table_entry)6736// TypeTableEntry *expected_param_type, FnTableEntry *fn_table_entry)
7143//{6737//{
...@@ -8195,92 +7789,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -8195,92 +7789,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
8195// return g->builtin_types.entry_invalid;7789// return g->builtin_types.entry_invalid;
8196//}7790//}
8197//7791//
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//
8284//static TypeTableEntry *analyze_fn_proto_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,7792//static TypeTableEntry *analyze_fn_proto_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
8285// TypeTableEntry *expected_type, AstNode *node)7793// TypeTableEntry *expected_type, AstNode *node)
8286//{7794//{
...@@ -8294,14 +7802,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {...@@ -8294,14 +7802,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
8294// return resolve_expr_const_val_as_type(g, node, type_entry, false);7802// return resolve_expr_const_val_as_type(g, node, type_entry, false);
8295//}7803//}
8296//7804//
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//
8305//static void validate_voided_expr(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry) {7805//static void validate_voided_expr(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry) {
8306// if (type_entry->id == TypeTableEntryIdMetaType) {7806// if (type_entry->id == TypeTableEntryIdMetaType) {
8307// add_node_error(g, first_executing_node(source_node), buf_sprintf("expected expression, found type"));7807// 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...@@ -8949,54 +8449,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no
8949//}8449//}
8950//8450//
8951//8451//
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//}
9000//8452//
9001//static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) {8453//static LLVMValueRef gen_bool_and_expr(CodeGen *g, AstNode *node) {
9002// assert(node->type == NodeTypeBinOpExpr);8454// 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...@@ -115,6 +115,12 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
115 }115 }
116 break;116 break;
117 }117 }
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 }
118 case TypeTableEntryIdVar:124 case TypeTableEntryIdVar:
119 case TypeTableEntryIdFloat:125 case TypeTableEntryIdFloat:
120 case TypeTableEntryIdStruct:126 case TypeTableEntryIdStruct:
...@@ -124,7 +130,6 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const...@@ -124,7 +130,6 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
124 case TypeTableEntryIdEnum:130 case TypeTableEntryIdEnum:
125 case TypeTableEntryIdUnion:131 case TypeTableEntryIdUnion:
126 case TypeTableEntryIdTypeDecl:132 case TypeTableEntryIdTypeDecl:
127 case TypeTableEntryIdNamespace:
128 case TypeTableEntryIdGenericFn:133 case TypeTableEntryIdGenericFn:
129 zig_panic("TODO render more constant types in IR printer");134 zig_panic("TODO render more constant types in IR printer");
130 }135 }
...@@ -407,11 +412,6 @@ static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction)...@@ -407,11 +412,6 @@ static void ir_print_field_ptr(IrPrint *irp, IrInstructionFieldPtr *instruction)
407 fprintf(irp->f, ")");412 fprintf(irp->f, ")");
408}413}
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
415static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr *instruction) {415static void ir_print_struct_field_ptr(IrPrint *irp, IrInstructionStructFieldPtr *instruction) {
416 fprintf(irp->f, "@StructFieldPtr(&");416 fprintf(irp->f, "@StructFieldPtr(&");
417 ir_print_other_instruction(irp, instruction->struct_ptr);417 ir_print_other_instruction(irp, instruction->struct_ptr);
...@@ -575,6 +575,17 @@ static void ir_print_static_eval(IrPrint *irp, IrInstructionStaticEval *instruct...@@ -575,6 +575,17 @@ static void ir_print_static_eval(IrPrint *irp, IrInstructionStaticEval *instruct
575 fprintf(irp->f, ")");575 fprintf(irp->f, ")");
576}576}
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
578static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {589static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
579 ir_print_prefix(irp, instruction);590 ir_print_prefix(irp, instruction);
580 switch (instruction->id) {591 switch (instruction->id) {
...@@ -643,9 +654,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -643,9 +654,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
643 case IrInstructionIdFieldPtr:654 case IrInstructionIdFieldPtr:
644 ir_print_field_ptr(irp, (IrInstructionFieldPtr *)instruction);655 ir_print_field_ptr(irp, (IrInstructionFieldPtr *)instruction);
645 break;656 break;
646 case IrInstructionIdReadField:
647 ir_print_read_field(irp, (IrInstructionReadField *)instruction);
648 break;
649 case IrInstructionIdStructFieldPtr:657 case IrInstructionIdStructFieldPtr:
650 ir_print_struct_field_ptr(irp, (IrInstructionStructFieldPtr *)instruction);658 ir_print_struct_field_ptr(irp, (IrInstructionStructFieldPtr *)instruction);
651 break;659 break;
...@@ -700,6 +708,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -700,6 +708,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
700 case IrInstructionIdStaticEval:708 case IrInstructionIdStaticEval:
701 ir_print_static_eval(irp, (IrInstructionStaticEval *)instruction);709 ir_print_static_eval(irp, (IrInstructionStaticEval *)instruction);
702 break;710 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;
703 }717 }
704 fprintf(irp->f, "\n");718 fprintf(irp->f, "\n");
705}719}
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 @@...@@ -1,3 +1,5 @@
1const case_namespace_fn_call = @import("cases/namespace_fn_call.zig");
2
1pub const SYS_write = 1;3pub const SYS_write = 1;
2pub const SYS_exit = 60;4pub const SYS_exit = 60;
3pub const stdout_fileno = 1;5pub const stdout_fileno = 1;
...@@ -61,6 +63,10 @@ fn testInlineSwitch() {...@@ -61,6 +63,10 @@ fn testInlineSwitch() {
61 assert(result + 1 == 14);63 assert(result + 1 == 14);
62}64}
6365
66fn testNamespaceFnCall() {
67 assert(case_namespace_fn_call.foo() == 1234);
68}
69
64fn assert(ok: bool) {70fn assert(ok: bool) {
65 if (!ok)71 if (!ok)
66 @unreachable();72 @unreachable();
...@@ -73,6 +79,7 @@ fn runAllTests() {...@@ -73,6 +79,7 @@ fn runAllTests() {
73 switchWithNumbers();79 switchWithNumbers();
74 switchWithAllRanges();80 switchWithAllRanges();
75 testInlineSwitch();81 testInlineSwitch();
82 testNamespaceFnCall();
76}83}
7784
78export nakedcc fn _start() -> unreachable {85export nakedcc fn _start() -> unreachable {