authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-01 23:25:09-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-04 03:40:40-05:00
log2f259b8176184f063f555aed34087cf7560124fb
treeb4e1cc89b32673c159c68a46ba1e0683ea208102
parentf6cbb73c7402fc100bbfb26c1a35c9f23b3f36ff

IR: re-organize where state goes to prepare for generics

* Rip out legacy code for generics * put scope in instruction instead of AST nodes * separate top level decl stuff from AST nodes - remove the assumption that there is a 1:1 correspondence between an output instruction and an AST node - This way we won't have to clone AST nodes for generics.

10 files changed, 1495 insertions(+), 1886 deletions(-)

src/all_types.hpp+88-202
...@@ -20,6 +20,8 @@ struct AstNode;...@@ -20,6 +20,8 @@ struct AstNode;
20struct ImportTableEntry;20struct ImportTableEntry;
21struct FnTableEntry;21struct FnTableEntry;
22struct Scope;22struct Scope;
23struct ScopeBlock;
24struct ScopeFnDef;
23struct TypeTableEntry;25struct TypeTableEntry;
24struct VariableTableEntry;26struct VariableTableEntry;
25struct ErrorTableEntry;27struct ErrorTableEntry;
...@@ -33,6 +35,13 @@ struct IrInstructionCast;...@@ -33,6 +35,13 @@ struct IrInstructionCast;
33struct IrBasicBlock;35struct IrBasicBlock;
34struct ScopeDecls;36struct ScopeDecls;
3537
38struct IrGotoItem {
39 AstNode *source_node;
40 IrBasicBlock *bb;
41 size_t instruction_index;
42 Scope *scope;
43};
44
36struct IrExecutable {45struct IrExecutable {
37 ZigList<IrBasicBlock *> basic_block_list;46 ZigList<IrBasicBlock *> basic_block_list;
38 size_t mem_slot_count;47 size_t mem_slot_count;
...@@ -41,8 +50,9 @@ struct IrExecutable {...@@ -41,8 +50,9 @@ struct IrExecutable {
41 size_t backward_branch_quota;50 size_t backward_branch_quota;
42 bool invalid;51 bool invalid;
43 ZigList<LabelTableEntry *> all_labels;52 ZigList<LabelTableEntry *> all_labels;
44 ZigList<AstNode *> goto_list;53 ZigList<IrGotoItem> goto_list;
45 bool is_inline;54 bool is_inline;
55 FnTableEntry *fn_entry;
46};56};
4757
48enum OutType {58enum OutType {
...@@ -129,36 +139,62 @@ enum ReturnKnowledge {...@@ -129,36 +139,62 @@ enum ReturnKnowledge {
129 ReturnKnowledgeSkipDefers,139 ReturnKnowledgeSkipDefers,
130};140};
131141
132struct StructValExprCodeGen {
133 TypeTableEntry *type_entry;
134 LLVMValueRef ptr;
135 AstNode *source_node;
136};
137
138enum VisibMod {142enum VisibMod {
139 VisibModPrivate,143 VisibModPrivate,
140 VisibModPub,144 VisibModPub,
141 VisibModExport,145 VisibModExport,
142};146};
143147
148enum TldId {
149 TldIdVar,
150 TldIdFn,
151 TldIdContainer,
152 TldIdTypeDef,
153};
154
144enum TldResolution {155enum TldResolution {
145 TldResolutionUnresolved,156 TldResolutionUnresolved,
146 TldResolutionInvalid,157 TldResolutionInvalid,
147 TldResolutionOk,158 TldResolutionOk,
148};159};
149160
150struct TopLevelDecl {161struct Tld {
151 // populated by parser162 TldId id;
152 Buf *name;163 Buf *name;
153 VisibMod visib_mod;164 VisibMod visib_mod;
165 AstNode *source_node;
154166
155 // populated by semantic analyzer
156 ImportTableEntry *import;167 ImportTableEntry *import;
168 Scope *parent_scope;
157 // set this flag temporarily to detect infinite loops169 // set this flag temporarily to detect infinite loops
158 bool dep_loop_flag;170 bool dep_loop_flag;
159 TldResolution resolution;171 TldResolution resolution;
160 AstNode *parent_decl;172 Tld *parent_tld;
161 IrInstruction *value;173};
174
175struct TldVar {
176 Tld base;
177
178 VariableTableEntry *var;
179};
180
181struct TldFn {
182 Tld base;
183
184 FnTableEntry *fn_entry;
185};
186
187struct TldContainer {
188 Tld base;
189
190 ScopeDecls *decls_scope;
191 TypeTableEntry *type_entry;
192};
193
194struct TldTypeDef {
195 Tld base;
196
197 TypeTableEntry *type_entry;
162};198};
163199
164struct TypeEnumField {200struct TypeEnumField {
...@@ -223,7 +259,7 @@ struct AstNodeRoot {...@@ -223,7 +259,7 @@ struct AstNodeRoot {
223};259};
224260
225struct AstNodeFnProto {261struct AstNodeFnProto {
226 TopLevelDecl top_level_decl;262 VisibMod visib_mod;
227 Buf *name;263 Buf *name;
228 ZigList<AstNode *> params;264 ZigList<AstNode *> params;
229 AstNode *return_type;265 AstNode *return_type;
...@@ -232,28 +268,12 @@ struct AstNodeFnProto {...@@ -232,28 +268,12 @@ struct AstNodeFnProto {
232 bool is_inline;268 bool is_inline;
233 bool is_coldcc;269 bool is_coldcc;
234 bool is_nakedcc;270 bool is_nakedcc;
235
236 // populated by semantic analyzer:
237
238 // the function definition this fn proto is inside. can be null.
239 AstNode *fn_def_node;271 AstNode *fn_def_node;
240 FnTableEntry *fn_table_entry;
241 bool skip;
242 // computed from params field
243 size_t inline_arg_count;
244 size_t inline_or_var_type_arg_count;
245 // if this is a generic function implementation, this points to the generic node
246 AstNode *generic_proto_node;
247};272};
248273
249struct AstNodeFnDef {274struct AstNodeFnDef {
250 AstNode *fn_proto;275 AstNode *fn_proto;
251 AstNode *body;276 AstNode *body;
252
253 // populated by semantic analyzer
254 TypeTableEntry *implicit_return_type;
255 Scope *containing_scope;
256 Scope *child_scope;
257};277};
258278
259struct AstNodeFnDecl {279struct AstNodeFnDecl {
...@@ -265,21 +285,10 @@ struct AstNodeParamDecl {...@@ -265,21 +285,10 @@ struct AstNodeParamDecl {
265 AstNode *type;285 AstNode *type;
266 bool is_noalias;286 bool is_noalias;
267 bool is_inline;287 bool is_inline;
268
269 // populated by semantic analyzer
270 VariableTableEntry *variable;
271};288};
272289
273struct AstNodeBlock {290struct AstNodeBlock {
274 ZigList<AstNode *> statements;291 ZigList<AstNode *> statements;
275
276 // populated by semantic analyzer
277 // this one is the scope that the block itself introduces
278 Scope *child_block;
279 // this is the innermost scope created by defers and var decls.
280 // you can follow its parents up to child_block. it will equal
281 // child_block if there are no defers or var decls in the block.
282 Scope *nested_block;
283};292};
284293
285enum ReturnKind {294enum ReturnKind {
...@@ -298,14 +307,13 @@ struct AstNodeDefer {...@@ -298,14 +307,13 @@ struct AstNodeDefer {
298 ReturnKind kind;307 ReturnKind kind;
299 AstNode *expr;308 AstNode *expr;
300309
301 // populated by semantic analyzer:310 // temporary data used in IR generation
302 size_t index_in_block;311 // TODO populate during gen_defer
303 LLVMBasicBlockRef basic_block;312 Scope *child_scope;
304 Scope *child_block;
305};313};
306314
307struct AstNodeVariableDeclaration {315struct AstNodeVariableDeclaration {
308 TopLevelDecl top_level_decl;316 VisibMod visib_mod;
309 Buf *symbol;317 Buf *symbol;
310 bool is_const;318 bool is_const;
311 bool is_inline;319 bool is_inline;
...@@ -313,28 +321,19 @@ struct AstNodeVariableDeclaration {...@@ -313,28 +321,19 @@ struct AstNodeVariableDeclaration {
313 // one or both of type and expr will be non null321 // one or both of type and expr will be non null
314 AstNode *type;322 AstNode *type;
315 AstNode *expr;323 AstNode *expr;
316
317 // populated by semantic analyzer
318 VariableTableEntry *variable;
319};324};
320325
321struct AstNodeTypeDecl {326struct AstNodeTypeDecl {
322 TopLevelDecl top_level_decl;327 VisibMod visib_mod;
323 Buf *symbol;328 Buf *symbol;
324 AstNode *child_type;329 AstNode *child_type;
325
326 // populated by semantic analyzer
327 // if this is set, don't process the node; we've already done so
328 // and here is the type (with id TypeTableEntryIdTypeDecl)
329 TypeTableEntry *override_type;
330 TypeTableEntry *child_type_entry;
331};330};
332331
333struct AstNodeErrorValueDecl {332struct AstNodeErrorValueDecl {
334 TopLevelDecl top_level_decl;333 // always invalid if it's not VisibModPrivate but can be parsed that way
334 VisibMod visib_mod;
335 Buf *name;335 Buf *name;
336336
337 // populated by semantic analyzer
338 ErrorTableEntry *err;337 ErrorTableEntry *err;
339};338};
340339
...@@ -388,19 +387,12 @@ struct AstNodeBinOpExpr {...@@ -388,19 +387,12 @@ struct AstNodeBinOpExpr {
388 AstNode *op1;387 AstNode *op1;
389 BinOpType bin_op;388 BinOpType bin_op;
390 AstNode *op2;389 AstNode *op2;
391
392 // populated by semantic analyzer:
393 // for when op is BinOpTypeAssign
394 VariableTableEntry *var_entry;
395};390};
396391
397struct AstNodeUnwrapErrorExpr {392struct AstNodeUnwrapErrorExpr {
398 AstNode *op1;393 AstNode *op1;
399 AstNode *symbol; // can be null394 AstNode *symbol; // can be null
400 AstNode *op2;395 AstNode *op2;
401
402 // populated by semantic analyzer:
403 VariableTableEntry *var;
404};396};
405397
406enum CastOp {398enum CastOp {
...@@ -429,21 +421,11 @@ struct AstNodeFnCallExpr {...@@ -429,21 +421,11 @@ struct AstNodeFnCallExpr {
429 AstNode *fn_ref_expr;421 AstNode *fn_ref_expr;
430 ZigList<AstNode *> params;422 ZigList<AstNode *> params;
431 bool is_builtin;423 bool is_builtin;
432
433 // populated by semantic analyzer:
434 BuiltinFnEntry *builtin_fn;
435 FnTableEntry *fn_entry;
436 CastOp cast_op;
437 // if cast_op is CastOpArrayToString, this will be a pointer to
438 // the string struct on the stack
439 LLVMValueRef tmp_ptr;
440};424};
441425
442struct AstNodeArrayAccessExpr {426struct AstNodeArrayAccessExpr {
443 AstNode *array_ref_expr;427 AstNode *array_ref_expr;
444 AstNode *subscript;428 AstNode *subscript;
445
446 // populated by semantic analyzer:
447};429};
448430
449struct AstNodeSliceExpr {431struct AstNodeSliceExpr {
...@@ -451,22 +433,11 @@ struct AstNodeSliceExpr {...@@ -451,22 +433,11 @@ struct AstNodeSliceExpr {
451 AstNode *start;433 AstNode *start;
452 AstNode *end;434 AstNode *end;
453 bool is_const;435 bool is_const;
454
455 // populated by semantic analyzer:
456 StructValExprCodeGen resolved_struct_val_expr;
457};436};
458437
459struct AstNodeFieldAccessExpr {438struct AstNodeFieldAccessExpr {
460 AstNode *struct_expr;439 AstNode *struct_expr;
461 Buf *field_name;440 Buf *field_name;
462
463 // populated by semantic analyzer
464 TypeStructField *type_struct_field;
465 TypeEnumField *type_enum_field;
466 StructValExprCodeGen resolved_struct_val_expr; // for enum values
467 TypeTableEntry *bare_container_type;
468 bool is_member_fn;
469 AstNode *container_init_expr_node;
470};441};
471442
472enum PrefixOp {443enum PrefixOp {
...@@ -487,24 +458,21 @@ enum PrefixOp {...@@ -487,24 +458,21 @@ enum PrefixOp {
487struct AstNodePrefixOpExpr {458struct AstNodePrefixOpExpr {
488 PrefixOp prefix_op;459 PrefixOp prefix_op;
489 AstNode *primary_expr;460 AstNode *primary_expr;
490
491 // populated by semantic analyzer
492};461};
493462
494struct AstNodeUse {463struct AstNodeUse {
464 VisibMod visib_mod;
495 AstNode *expr;465 AstNode *expr;
496466
497 // populated by semantic analyzer467 TldResolution resolution;
498 TopLevelDecl top_level_decl;468 IrInstruction *value;
499};469};
500470
501struct AstNodeIfBoolExpr {471struct AstNodeIfBoolExpr {
502 AstNode *condition;472 AstNode *condition;
503 AstNode *then_block;473 AstNode *then_block;
504 AstNode *else_node; // null, block node, or other if expr node474 AstNode *else_node; // null, block node, or other if expr node
505 bool is_inline; // TODO475 bool is_inline; // TODO parse inline if
506
507 // populated by semantic analyzer
508};476};
509477
510struct AstNodeIfVarExpr {478struct AstNodeIfVarExpr {
...@@ -512,10 +480,7 @@ struct AstNodeIfVarExpr {...@@ -512,10 +480,7 @@ struct AstNodeIfVarExpr {
512 AstNode *then_block;480 AstNode *then_block;
513 AstNode *else_node; // null, block node, or other if expr node481 AstNode *else_node; // null, block node, or other if expr node
514 bool var_is_ptr;482 bool var_is_ptr;
515 bool is_inline; // TODO483 bool is_inline; // TODO parse inline ?if?
516
517 // populated by semantic analyzer
518 TypeTableEntry *type;
519};484};
520485
521struct AstNodeWhileExpr {486struct AstNodeWhileExpr {
...@@ -523,11 +488,6 @@ struct AstNodeWhileExpr {...@@ -523,11 +488,6 @@ struct AstNodeWhileExpr {
523 AstNode *continue_expr;488 AstNode *continue_expr;
524 AstNode *body;489 AstNode *body;
525 bool is_inline;490 bool is_inline;
526
527 // populated by semantic analyzer
528 bool condition_always_true;
529 bool contains_break;
530 bool contains_continue;
531};491};
532492
533struct AstNodeForExpr {493struct AstNodeForExpr {
...@@ -537,20 +497,12 @@ struct AstNodeForExpr {...@@ -537,20 +497,12 @@ struct AstNodeForExpr {
537 AstNode *body;497 AstNode *body;
538 bool elem_is_ptr;498 bool elem_is_ptr;
539 bool is_inline;499 bool is_inline;
540
541 // populated by semantic analyzer
542 bool contains_break;
543 bool contains_continue;
544 VariableTableEntry *elem_var;
545 VariableTableEntry *index_var;
546};500};
547501
548struct AstNodeSwitchExpr {502struct AstNodeSwitchExpr {
549 AstNode *expr;503 AstNode *expr;
550 ZigList<AstNode *> prongs;504 ZigList<AstNode *> prongs;
551 bool is_inline;505 bool is_inline;
552
553 // populated by semantic analyzer
554};506};
555507
556struct AstNodeSwitchProng {508struct AstNodeSwitchProng {
...@@ -573,10 +525,6 @@ struct AstNodeLabel {...@@ -573,10 +525,6 @@ struct AstNodeLabel {
573struct AstNodeGoto {525struct AstNodeGoto {
574 Buf *name;526 Buf *name;
575 bool is_inline;527 bool is_inline;
576
577 // populated by semantic analyzer
578 IrBasicBlock *bb;
579 size_t instruction_index;
580};528};
581529
582struct AsmOutput {530struct AsmOutput {
...@@ -584,9 +532,6 @@ struct AsmOutput {...@@ -584,9 +532,6 @@ struct AsmOutput {
584 Buf *constraint;532 Buf *constraint;
585 Buf *variable_name;533 Buf *variable_name;
586 AstNode *return_type; // null unless "=r" and return534 AstNode *return_type; // null unless "=r" and return
587
588 // populated by semantic analyzer
589 VariableTableEntry *variable;
590};535};
591536
592struct AsmInput {537struct AsmInput {
...@@ -619,8 +564,6 @@ struct AstNodeAsmExpr {...@@ -619,8 +564,6 @@ struct AstNodeAsmExpr {
619 ZigList<AsmOutput*> output_list;564 ZigList<AsmOutput*> output_list;
620 ZigList<AsmInput*> input_list;565 ZigList<AsmInput*> input_list;
621 ZigList<Buf*> clobber_list;566 ZigList<Buf*> clobber_list;
622
623 // populated by semantic analyzer
624};567};
625568
626enum ContainerKind {569enum ContainerKind {
...@@ -630,23 +573,17 @@ enum ContainerKind {...@@ -630,23 +573,17 @@ enum ContainerKind {
630};573};
631574
632struct AstNodeStructDecl {575struct AstNodeStructDecl {
633 TopLevelDecl top_level_decl;576 VisibMod visib_mod;
634 Buf *name;577 Buf *name;
635 ContainerKind kind;578 ContainerKind kind;
636 ZigList<AstNode *> generic_params;579 ZigList<AstNode *> generic_params;
637 bool generic_params_is_var_args; // always an error but it can happen from parsing580 bool generic_params_is_var_args; // always an error but it can happen from parsing
638 ZigList<AstNode *> fields;581 ZigList<AstNode *> fields;
639 ZigList<AstNode *> decls;582 ZigList<AstNode *> decls;
640
641 // populated by semantic analyzer
642 ScopeDecls *decls_scope;
643 TypeTableEntry *type_entry;
644 TypeTableEntry *generic_fn_type;
645 bool skip;
646};583};
647584
648struct AstNodeStructField {585struct AstNodeStructField {
649 TopLevelDecl top_level_decl;586 VisibMod visib_mod;
650 Buf *name;587 Buf *name;
651 AstNode *type;588 AstNode *type;
652};589};
...@@ -654,14 +591,10 @@ struct AstNodeStructField {...@@ -654,14 +591,10 @@ struct AstNodeStructField {
654struct AstNodeStringLiteral {591struct AstNodeStringLiteral {
655 Buf *buf;592 Buf *buf;
656 bool c;593 bool c;
657
658 // populated by semantic analyzer:
659};594};
660595
661struct AstNodeCharLiteral {596struct AstNodeCharLiteral {
662 uint8_t value;597 uint8_t value;
663
664 // populated by semantic analyzer:
665};598};
666599
667struct AstNodeNumberLiteral {600struct AstNodeNumberLiteral {
...@@ -670,16 +603,11 @@ struct AstNodeNumberLiteral {...@@ -670,16 +603,11 @@ struct AstNodeNumberLiteral {
670 // overflow is true if when parsing the number, we discovered it would not603 // overflow is true if when parsing the number, we discovered it would not
671 // fit without losing data in a uint64_t or double604 // fit without losing data in a uint64_t or double
672 bool overflow;605 bool overflow;
673
674 // populated by semantic analyzer
675};606};
676607
677struct AstNodeStructValueField {608struct AstNodeStructValueField {
678 Buf *name;609 Buf *name;
679 AstNode *expr;610 AstNode *expr;
680
681 // populated by semantic analyzer
682 TypeStructField *type_struct_field;
683};611};
684612
685enum ContainerInitKind {613enum ContainerInitKind {
...@@ -691,68 +619,47 @@ struct AstNodeContainerInitExpr {...@@ -691,68 +619,47 @@ struct AstNodeContainerInitExpr {
691 AstNode *type;619 AstNode *type;
692 ZigList<AstNode *> entries;620 ZigList<AstNode *> entries;
693 ContainerInitKind kind;621 ContainerInitKind kind;
694
695 // populated by semantic analyzer
696 StructValExprCodeGen resolved_struct_val_expr;
697 TypeTableEntry *enum_type;
698};622};
699623
700struct AstNodeNullLiteral {624struct AstNodeNullLiteral {
701 // populated by semantic analyzer
702};625};
703626
704struct AstNodeUndefinedLiteral {627struct AstNodeUndefinedLiteral {
705 // populated by semantic analyzer
706};628};
707629
708struct AstNodeZeroesLiteral {630struct AstNodeZeroesLiteral {
709 // populated by semantic analyzer
710};631};
711632
712struct AstNodeThisLiteral {633struct AstNodeThisLiteral {
713 // populated by semantic analyzer
714};634};
715635
716struct AstNodeSymbolExpr {636struct AstNodeSymbolExpr {
717 Buf *symbol;637 Buf *symbol;
718
719 // populated by semantic analyzer
720 TypeEnumField *enum_field;
721 uint32_t err_value;
722};638};
723639
724struct AstNodeBoolLiteral {640struct AstNodeBoolLiteral {
725 bool value;641 bool value;
726
727 // populated by semantic analyzer
728};642};
729643
730struct AstNodeBreakExpr {644struct AstNodeBreakExpr {
731 // populated by semantic analyzer
732};645};
733646
734struct AstNodeContinueExpr {647struct AstNodeContinueExpr {
735 // populated by semantic analyzer
736};648};
737649
738struct AstNodeArrayType {650struct AstNodeArrayType {
739 AstNode *size;651 AstNode *size;
740 AstNode *child_type;652 AstNode *child_type;
741 bool is_const;653 bool is_const;
742
743 // populated by semantic analyzer
744};654};
745655
746struct AstNodeErrorType {656struct AstNodeErrorType {
747 // populated by semantic analyzer
748};657};
749658
750struct AstNodeTypeLiteral {659struct AstNodeTypeLiteral {
751 // populated by semantic analyzer
752};660};
753661
754struct AstNodeVarLiteral {662struct AstNodeVarLiteral {
755 // populated by semantic analyzer
756};663};
757664
758struct AstNode {665struct AstNode {
...@@ -761,9 +668,6 @@ struct AstNode {...@@ -761,9 +668,6 @@ struct AstNode {
761 size_t column;668 size_t column;
762 uint32_t create_index; // for determinism purposes669 uint32_t create_index; // for determinism purposes
763 ImportTableEntry *owner;670 ImportTableEntry *owner;
764 // the context in which this expression/node is evaluated.
765 // for blocks, this points to the containing scope, not the block's own scope for its children.
766 Scope *scope;
767 union {671 union {
768 AstNodeRoot root;672 AstNodeRoot root;
769 AstNodeFnDef fn_def;673 AstNodeFnDef fn_def;
...@@ -822,26 +726,12 @@ struct FnTypeParamInfo {...@@ -822,26 +726,12 @@ struct FnTypeParamInfo {
822 TypeTableEntry *type;726 TypeTableEntry *type;
823};727};
824728
825struct GenericParamValue {
826 TypeTableEntry *type;
827 AstNode *node;
828 size_t impl_index;
829};
830
831struct GenericFnTypeId {
832 AstNode *decl_node; // the generic fn or container decl node
833 GenericParamValue *generic_params;
834 size_t generic_param_count;
835};
836
837uint32_t generic_fn_type_id_hash(GenericFnTypeId *id);
838bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b);
839
840729
841struct FnTypeId {730struct FnTypeId {
842 TypeTableEntry *return_type;731 TypeTableEntry *return_type;
843 FnTypeParamInfo *param_info;732 FnTypeParamInfo *param_info;
844 size_t param_count;733 size_t param_count;
734 size_t next_param_index;
845 bool is_var_args;735 bool is_var_args;
846 bool is_naked;736 bool is_naked;
847 bool is_cold;737 bool is_cold;
...@@ -945,6 +835,7 @@ struct FnGenParamInfo {...@@ -945,6 +835,7 @@ struct FnGenParamInfo {
945835
946struct TypeTableEntryFn {836struct TypeTableEntryFn {
947 FnTypeId fn_type_id;837 FnTypeId fn_type_id;
838 bool is_generic;
948 TypeTableEntry *gen_return_type;839 TypeTableEntry *gen_return_type;
949 size_t gen_param_count;840 size_t gen_param_count;
950 FnGenParamInfo *gen_param_info;841 FnGenParamInfo *gen_param_info;
...@@ -955,10 +846,6 @@ struct TypeTableEntryFn {...@@ -955,10 +846,6 @@ struct TypeTableEntryFn {
955 TypeTableEntry *bound_fn_parent;846 TypeTableEntry *bound_fn_parent;
956};847};
957848
958struct TypeTableEntryGenericFn {
959 AstNode *decl_node;
960};
961
962struct TypeTableEntryBoundFn {849struct TypeTableEntryBoundFn {
963 TypeTableEntry *fn_type;850 TypeTableEntry *fn_type;
964};851};
...@@ -993,7 +880,6 @@ enum TypeTableEntryId {...@@ -993,7 +880,6 @@ enum TypeTableEntryId {
993 TypeTableEntryIdTypeDecl,880 TypeTableEntryIdTypeDecl,
994 TypeTableEntryIdNamespace,881 TypeTableEntryIdNamespace,
995 TypeTableEntryIdBlock,882 TypeTableEntryIdBlock,
996 TypeTableEntryIdGenericFn,
997 TypeTableEntryIdBoundFn,883 TypeTableEntryIdBoundFn,
998};884};
999885
...@@ -1018,7 +904,6 @@ struct TypeTableEntry {...@@ -1018,7 +904,6 @@ struct TypeTableEntry {
1018 TypeTableEntryUnion unionation;904 TypeTableEntryUnion unionation;
1019 TypeTableEntryFn fn;905 TypeTableEntryFn fn;
1020 TypeTableEntryTypeDecl type_decl;906 TypeTableEntryTypeDecl type_decl;
1021 TypeTableEntryGenericFn generic_fn;
1022 TypeTableEntryBoundFn bound_fn;907 TypeTableEntryBoundFn bound_fn;
1023 } data;908 } data;
1024909
...@@ -1056,10 +941,9 @@ enum FnAnalState {...@@ -1056,10 +941,9 @@ enum FnAnalState {
1056 FnAnalStateReady,941 FnAnalStateReady,
1057 FnAnalStateProbing,942 FnAnalStateProbing,
1058 FnAnalStateComplete,943 FnAnalStateComplete,
1059 FnAnalStateSkipped,944 FnAnalStateInvalid,
1060};945};
1061946
1062
1063enum FnInline {947enum FnInline {
1064 FnInlineAuto,948 FnInlineAuto,
1065 FnInlineAlways,949 FnInlineAlways,
...@@ -1067,14 +951,18 @@ enum FnInline {...@@ -1067,14 +951,18 @@ enum FnInline {
1067};951};
1068952
1069struct FnTableEntry {953struct FnTableEntry {
1070 LLVMValueRef fn_value;954 LLVMValueRef llvm_value;
1071 AstNode *proto_node;955 AstNode *proto_node;
1072 AstNode *fn_def_node;956 AstNode *fn_def_node;
957 ScopeFnDef *fndef_scope; // parent should be the top level decls or container decls
958 Scope *child_scope; // parent is scope for last parameter
959 ScopeBlock *def_scope; // parent is child_scope
1073 ImportTableEntry *import_entry;960 ImportTableEntry *import_entry;
1074 Buf symbol_name;961 Buf symbol_name;
1075 TypeTableEntry *type_entry; // function type962 TypeTableEntry *type_entry; // function type
963 TypeTableEntry *implicit_return_type;
1076 bool internal_linkage;964 bool internal_linkage;
1077 bool is_extern;965 bool disable_export;
1078 bool is_test;966 bool is_test;
1079 FnInline fn_inline;967 FnInline fn_inline;
1080 FnAnalState anal_state;968 FnAnalState anal_state;
...@@ -1161,11 +1049,10 @@ struct CodeGen {...@@ -1161,11 +1049,10 @@ struct CodeGen {
1161 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> primitive_type_table;1049 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> primitive_type_table;
1162 HashMap<FnTypeId *, TypeTableEntry *, fn_type_id_hash, fn_type_id_eql> fn_type_table;1050 HashMap<FnTypeId *, TypeTableEntry *, fn_type_id_hash, fn_type_id_eql> fn_type_table;
1163 HashMap<Buf *, ErrorTableEntry *, buf_hash, buf_eql_buf> error_table;1051 HashMap<Buf *, ErrorTableEntry *, buf_hash, buf_eql_buf> error_table;
1164 HashMap<GenericFnTypeId *, AstNode *, generic_fn_type_id_hash, generic_fn_type_id_eql> generic_table;
11651052
1166 ZigList<ImportTableEntry *> import_queue;1053 ZigList<ImportTableEntry *> import_queue;
1167 size_t import_queue_index;1054 size_t import_queue_index;
1168 ZigList<AstNode *> resolve_queue;1055 ZigList<Tld *> resolve_queue;
1169 size_t resolve_queue_index;1056 size_t resolve_queue_index;
1170 ZigList<AstNode *> use_queue;1057 ZigList<AstNode *> use_queue;
1171 size_t use_queue_index;1058 size_t use_queue_index;
...@@ -1249,6 +1136,7 @@ struct CodeGen {...@@ -1249,6 +1136,7 @@ struct CodeGen {
1249 // The function definitions this module includes. There must be a corresponding1136 // The function definitions this module includes. There must be a corresponding
1250 // fn_protos entry.1137 // fn_protos entry.
1251 ZigList<FnTableEntry *> fn_defs;1138 ZigList<FnTableEntry *> fn_defs;
1139 size_t fn_defs_index;
1252 // The function prototypes this module includes. In the case of external declarations,1140 // The function prototypes this module includes. In the case of external declarations,
1253 // there will not be a corresponding fn_defs entry.1141 // there will not be a corresponding fn_defs entry.
1254 ZigList<FnTableEntry *> fn_protos;1142 ZigList<FnTableEntry *> fn_protos;
...@@ -1258,6 +1146,7 @@ struct CodeGen {...@@ -1258,6 +1146,7 @@ struct CodeGen {
1258 FnTableEntry *cur_fn;1146 FnTableEntry *cur_fn;
1259 FnTableEntry *main_fn;1147 FnTableEntry *main_fn;
1260 LLVMValueRef cur_ret_ptr;1148 LLVMValueRef cur_ret_ptr;
1149 LLVMValueRef cur_fn_val;
1261 ZigList<LLVMBasicBlockRef> break_block_stack;1150 ZigList<LLVMBasicBlockRef> break_block_stack;
1262 ZigList<LLVMBasicBlockRef> continue_block_stack;1151 ZigList<LLVMBasicBlockRef> continue_block_stack;
1263 bool c_want_stdint;1152 bool c_want_stdint;
...@@ -1295,6 +1184,7 @@ struct CodeGen {...@@ -1295,6 +1184,7 @@ struct CodeGen {
1295 IrInstruction *invalid_instruction;1184 IrInstruction *invalid_instruction;
1296};1185};
12971186
1187// TODO after merging IR branch, we can probably delete some of these fields
1298struct VariableTableEntry {1188struct VariableTableEntry {
1299 Buf name;1189 Buf name;
1300 TypeTableEntry *type;1190 TypeTableEntry *type;
...@@ -1304,8 +1194,6 @@ struct VariableTableEntry {...@@ -1304,8 +1194,6 @@ struct VariableTableEntry {
1304 bool is_inline;1194 bool is_inline;
1305 // which node is the declaration of the variable1195 // which node is the declaration of the variable
1306 AstNode *decl_node;1196 AstNode *decl_node;
1307 // which node contains the ConstExprValue for this variable's value
1308 AstNode *val_node;
1309 ZigLLVMDILocalVariable *di_loc_var;1197 ZigLLVMDILocalVariable *di_loc_var;
1310 size_t src_arg_index;1198 size_t src_arg_index;
1311 size_t gen_arg_index;1199 size_t gen_arg_index;
...@@ -1313,10 +1201,10 @@ struct VariableTableEntry {...@@ -1313,10 +1201,10 @@ struct VariableTableEntry {
1313 Scope *child_scope;1201 Scope *child_scope;
1314 LLVMValueRef param_value_ref;1202 LLVMValueRef param_value_ref;
1315 bool force_depends_on_compile_var;1203 bool force_depends_on_compile_var;
1316 ImportTableEntry *import;
1317 bool shadowable;1204 bool shadowable;
1318 size_t mem_slot_index;1205 size_t mem_slot_index;
1319 size_t ref_count;1206 size_t ref_count;
1207 ConstExprValue *value;
1320};1208};
13211209
1322struct ErrorTableEntry {1210struct ErrorTableEntry {
...@@ -1339,9 +1227,6 @@ struct Scope {...@@ -1339,9 +1227,6 @@ struct Scope {
1339 Scope *parent;1227 Scope *parent;
13401228
1341 ZigLLVMDIScope *di_scope;1229 ZigLLVMDIScope *di_scope;
1342
1343 bool safety_off;
1344 AstNode *safety_set_node;
1345};1230};
13461231
1347// This scope comes from global declarations or from1232// This scope comes from global declarations or from
...@@ -1350,15 +1235,12 @@ struct Scope {...@@ -1350,15 +1235,12 @@ struct Scope {
1350struct ScopeDecls {1235struct ScopeDecls {
1351 Scope base;1236 Scope base;
13521237
1353 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> decl_table;1238 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> decl_table;
1354};1239 bool safety_off;
13551240 AstNode *safety_set_node;
1356// This scope comes from a container declaration such as a struct,1241 ImportTableEntry *import;
1357// enum, or union.1242 // If this is a scope from a container, this is the type entry, otherwise null
1358struct ScopeContainer {1243 TypeTableEntry *container_type;
1359 Scope base;
1360
1361 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> decl_table;
1362};1244};
13631245
1364// This scope comes from a block expression in user code.1246// This scope comes from a block expression in user code.
...@@ -1367,6 +1249,8 @@ struct ScopeBlock {...@@ -1367,6 +1249,8 @@ struct ScopeBlock {
1367 Scope base;1249 Scope base;
13681250
1369 HashMap<Buf *, LabelTableEntry *, buf_hash, buf_eql_buf> label_table; 1251 HashMap<Buf *, LabelTableEntry *, buf_hash, buf_eql_buf> label_table;
1252 bool safety_off;
1253 AstNode *safety_set_node;
1370};1254};
13711255
1372// This scope is created from every defer expression.1256// This scope is created from every defer expression.
...@@ -1401,7 +1285,7 @@ struct ScopeLoop {...@@ -1401,7 +1285,7 @@ struct ScopeLoop {
14011285
1402// This scope is created for a function definition.1286// This scope is created for a function definition.
1403// NodeTypeFnDef1287// NodeTypeFnDef
1404struct ScopeFnBody {1288struct ScopeFnDef {
1405 Scope base;1289 Scope base;
14061290
1407 FnTableEntry *fn_entry;1291 FnTableEntry *fn_entry;
...@@ -1479,6 +1363,7 @@ enum IrInstructionId {...@@ -1479,6 +1363,7 @@ enum IrInstructionId {
14791363
1480struct IrInstruction {1364struct IrInstruction {
1481 IrInstructionId id;1365 IrInstructionId id;
1366 Scope *scope;
1482 AstNode *source_node;1367 AstNode *source_node;
1483 ConstExprValue static_value;1368 ConstExprValue static_value;
1484 TypeTableEntry *type_entry;1369 TypeTableEntry *type_entry;
...@@ -1798,6 +1683,7 @@ struct IrInstructionAsm {...@@ -1798,6 +1683,7 @@ struct IrInstructionAsm {
1798 // Most information on inline assembly comes from the source node.1683 // Most information on inline assembly comes from the source node.
1799 IrInstruction **input_list;1684 IrInstruction **input_list;
1800 IrInstruction **output_types;1685 IrInstruction **output_types;
1686 VariableTableEntry **output_vars;
1801 size_t return_count;1687 size_t return_count;
1802 bool has_side_effects;1688 bool has_side_effects;
1803};1689};
src/analyze.cpp+496-806
...@@ -19,8 +19,8 @@...@@ -19,8 +19,8 @@
1919
20static const size_t default_backward_branch_quota = 1000;20static const size_t default_backward_branch_quota = 1000;
2121
22static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type);22static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type);
23static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type);23static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type);
2424
25AstNode *first_executing_node(AstNode *node) {25AstNode *first_executing_node(AstNode *node) {
26 switch (node->type) {26 switch (node->type) {
...@@ -130,9 +130,82 @@ ScopeDecls *get_container_scope(TypeTableEntry *type_entry) {...@@ -130,9 +130,82 @@ ScopeDecls *get_container_scope(TypeTableEntry *type_entry) {
130 return *get_container_scope_ptr(type_entry);130 return *get_container_scope_ptr(type_entry);
131}131}
132132
133void init_scope(Scope *dest, AstNode *node, Scope *parent) {
134 dest->node = node;
135 dest->parent = parent;
136}
137
138static ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, TypeTableEntry *container_type, ImportTableEntry *import) {
139 assert(node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl);
140 ScopeDecls *scope = allocate<ScopeDecls>(1);
141 init_scope(&scope->base, node, parent);
142 scope->decl_table.init(4);
143 scope->container_type = container_type;
144 scope->import = import;
145 return scope;
146}
147
148Scope *create_block_scope(AstNode *node, Scope *parent) {
149 assert(node->type == NodeTypeBlock);
150 ScopeBlock *scope = allocate<ScopeBlock>(1);
151 init_scope(&scope->base, node, parent);
152 scope->label_table.init(1);
153 return &scope->base;
154}
155
156Scope *create_defer_scope(AstNode *node, Scope *parent) {
157 assert(node->type == NodeTypeDefer);
158 ScopeDefer *scope = allocate<ScopeDefer>(1);
159 init_scope(&scope->base, node, parent);
160 return &scope->base;
161}
162
163Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var) {
164 assert(node->type == NodeTypeVariableDeclaration || node->type == NodeTypeParamDecl);
165 ScopeVarDecl *scope = allocate<ScopeVarDecl>(1);
166 init_scope(&scope->base, node, parent);
167 scope->var = var;
168 return &scope->base;
169}
170
171Scope *create_cimport_scope(AstNode *node, Scope *parent) {
172 assert(node->type == NodeTypeFnCallExpr);
173 ScopeCImport *scope = allocate<ScopeCImport>(1);
174 init_scope(&scope->base, node, parent);
175 buf_resize(&scope->c_import_buf, 0);
176 return &scope->base;
177}
178
179Scope *create_loop_scope(AstNode *node, Scope *parent) {
180 assert(node->type == NodeTypeWhileExpr || node->type == NodeTypeForExpr);
181 ScopeLoop *scope = allocate<ScopeLoop>(1);
182 init_scope(&scope->base, node, parent);
183 return &scope->base;
184}
185
186ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_entry) {
187 assert(node->type == NodeTypeFnDef);
188 ScopeFnDef *scope = allocate<ScopeFnDef>(1);
189 init_scope(&scope->base, node, parent);
190 scope->fn_entry = fn_entry;
191 return scope;
192}
193
194ImportTableEntry *get_scope_import(Scope *scope) {
195 while (scope) {
196 if (scope->node->type == NodeTypeRoot || scope->node->type == NodeTypeContainerDecl) {
197 ScopeDecls *decls_scope = (ScopeDecls *)scope;
198 assert(decls_scope->import);
199 return decls_scope->import;
200 }
201 scope = scope->parent;
202 }
203 zig_unreachable();
204}
205
133static TypeTableEntry *new_container_type_entry(TypeTableEntryId id, AstNode *source_node, Scope *parent_scope) {206static TypeTableEntry *new_container_type_entry(TypeTableEntryId id, AstNode *source_node, Scope *parent_scope) {
134 TypeTableEntry *entry = new_type_table_entry(id);207 TypeTableEntry *entry = new_type_table_entry(id);
135 *get_container_scope_ptr(entry) = create_decls_scope(source_node, parent_scope);208 *get_container_scope_ptr(entry) = create_decls_scope(source_node, parent_scope, entry, get_scope_import(parent_scope));
136 return entry;209 return entry;
137}210}
138211
...@@ -179,7 +252,6 @@ bool type_is_complete(TypeTableEntry *type_entry) {...@@ -179,7 +252,6 @@ bool type_is_complete(TypeTableEntry *type_entry) {
179 case TypeTableEntryIdTypeDecl:252 case TypeTableEntryIdTypeDecl:
180 case TypeTableEntryIdNamespace:253 case TypeTableEntryIdNamespace:
181 case TypeTableEntryIdBlock:254 case TypeTableEntryIdBlock:
182 case TypeTableEntryIdGenericFn:
183 case TypeTableEntryIdBoundFn:255 case TypeTableEntryIdBoundFn:
184 return true;256 return true;
185 }257 }
...@@ -202,14 +274,6 @@ TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {...@@ -202,14 +274,6 @@ TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
202 return get_int_type(g, false, bits_needed_for_unsigned(x));274 return get_int_type(g, false, bits_needed_for_unsigned(x));
203}275}
204276
205static TypeTableEntry *get_generic_fn_type(CodeGen *g, AstNode *decl_node) {
206 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdGenericFn);
207 buf_init_from_str(&entry->name, "(generic function)");
208 entry->zero_bits = true;
209 entry->data.generic_fn.decl_node = decl_node;
210 return entry;
211}
212
213TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) {277TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) {
214 assert(child_type->id != TypeTableEntryIdInvalid);278 assert(child_type->id != TypeTableEntryIdInvalid);
215 TypeTableEntry **parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)];279 TypeTableEntry **parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)];
...@@ -643,8 +707,7 @@ TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry) {...@@ -643,8 +707,7 @@ TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry) {
643 return bound_fn_type;707 return bound_fn_type;
644}708}
645709
646// accepts ownership of fn_type_id memory710TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
647TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id, bool gen_debug_info) {
648 auto table_entry = g->fn_type_table.maybe_get(fn_type_id);711 auto table_entry = g->fn_type_table.maybe_get(fn_type_id);
649 if (table_entry) {712 if (table_entry) {
650 return table_entry->value;713 return table_entry->value;
...@@ -685,67 +748,65 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id, bool gen_debug_inf...@@ -685,67 +748,65 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id, bool gen_debug_inf
685 buf_appendf(&fn_type->name, " -> %s", buf_ptr(&fn_type_id->return_type->name));748 buf_appendf(&fn_type->name, " -> %s", buf_ptr(&fn_type_id->return_type->name));
686 }749 }
687750
688 if (gen_debug_info) {751 // next, loop over the parameters again and compute debug information
689 // next, loop over the parameters again and compute debug information752 // and codegen information
690 // and codegen information753 bool first_arg_return = !fn_type_id->is_extern && handle_is_ptr(fn_type_id->return_type);
691 bool first_arg_return = !fn_type_id->is_extern && handle_is_ptr(fn_type_id->return_type);754 // +1 for maybe making the first argument the return value
692 // +1 for maybe making the first argument the return value755 LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(1 + fn_type_id->param_count);
693 LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(1 + fn_type_id->param_count);756 // +1 because 0 is the return type and +1 for maybe making first arg ret val
694 // +1 because 0 is the return type and +1 for maybe making first arg ret val757 ZigLLVMDIType **param_di_types = allocate<ZigLLVMDIType*>(2 + fn_type_id->param_count);
695 ZigLLVMDIType **param_di_types = allocate<ZigLLVMDIType*>(2 + fn_type_id->param_count);758 param_di_types[0] = fn_type_id->return_type->di_type;
696 param_di_types[0] = fn_type_id->return_type->di_type;759 size_t gen_param_index = 0;
697 size_t gen_param_index = 0;760 TypeTableEntry *gen_return_type;
698 TypeTableEntry *gen_return_type;761 if (!type_has_bits(fn_type_id->return_type)) {
699 if (!type_has_bits(fn_type_id->return_type)) {762 gen_return_type = g->builtin_types.entry_void;
700 gen_return_type = g->builtin_types.entry_void;763 } else if (first_arg_return) {
701 } else if (first_arg_return) {764 TypeTableEntry *gen_type = get_pointer_to_type(g, fn_type_id->return_type, false);
702 TypeTableEntry *gen_type = get_pointer_to_type(g, fn_type_id->return_type, false);765 gen_param_types[gen_param_index] = gen_type->type_ref;
766 gen_param_index += 1;
767 // after the gen_param_index += 1 because 0 is the return type
768 param_di_types[gen_param_index] = gen_type->di_type;
769 gen_return_type = g->builtin_types.entry_void;
770 } else {
771 gen_return_type = fn_type_id->return_type;
772 }
773 fn_type->data.fn.gen_return_type = gen_return_type;
774
775 fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count);
776 for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
777 FnTypeParamInfo *src_param_info = &fn_type->data.fn.fn_type_id.param_info[i];
778 TypeTableEntry *type_entry = src_param_info->type;
779 FnGenParamInfo *gen_param_info = &fn_type->data.fn.gen_param_info[i];
780
781 gen_param_info->src_index = i;
782 gen_param_info->gen_index = SIZE_MAX;
783
784 assert(type_is_complete(type_entry));
785 if (type_has_bits(type_entry)) {
786 TypeTableEntry *gen_type;
787 if (handle_is_ptr(type_entry)) {
788 gen_type = get_pointer_to_type(g, type_entry, true);
789 gen_param_info->is_byval = true;
790 } else {
791 gen_type = type_entry;
792 }
703 gen_param_types[gen_param_index] = gen_type->type_ref;793 gen_param_types[gen_param_index] = gen_type->type_ref;
794 gen_param_info->gen_index = gen_param_index;
795 gen_param_info->type = gen_type;
796
704 gen_param_index += 1;797 gen_param_index += 1;
798
705 // after the gen_param_index += 1 because 0 is the return type799 // after the gen_param_index += 1 because 0 is the return type
706 param_di_types[gen_param_index] = gen_type->di_type;800 param_di_types[gen_param_index] = gen_type->di_type;
707 gen_return_type = g->builtin_types.entry_void;
708 } else {
709 gen_return_type = fn_type_id->return_type;
710 }801 }
711 fn_type->data.fn.gen_return_type = gen_return_type;802 }
712
713 fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count);
714 for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
715 FnTypeParamInfo *src_param_info = &fn_type->data.fn.fn_type_id.param_info[i];
716 TypeTableEntry *type_entry = src_param_info->type;
717 FnGenParamInfo *gen_param_info = &fn_type->data.fn.gen_param_info[i];
718
719 gen_param_info->src_index = i;
720 gen_param_info->gen_index = SIZE_MAX;
721
722 assert(type_is_complete(type_entry));
723 if (type_has_bits(type_entry)) {
724 TypeTableEntry *gen_type;
725 if (handle_is_ptr(type_entry)) {
726 gen_type = get_pointer_to_type(g, type_entry, true);
727 gen_param_info->is_byval = true;
728 } else {
729 gen_type = type_entry;
730 }
731 gen_param_types[gen_param_index] = gen_type->type_ref;
732 gen_param_info->gen_index = gen_param_index;
733 gen_param_info->type = gen_type;
734803
735 gen_param_index += 1;804 fn_type->data.fn.gen_param_count = gen_param_index;
736805
737 // after the gen_param_index += 1 because 0 is the return type806 fn_type->data.fn.raw_type_ref = LLVMFunctionType(gen_return_type->type_ref,
738 param_di_types[gen_param_index] = gen_type->di_type;807 gen_param_types, gen_param_index, fn_type_id->is_var_args);
739 }808 fn_type->type_ref = LLVMPointerType(fn_type->data.fn.raw_type_ref, 0);
740 }809 fn_type->di_type = ZigLLVMCreateSubroutineType(g->dbuilder, param_di_types, gen_param_index + 1, 0);
741
742 fn_type->data.fn.gen_param_count = gen_param_index;
743
744 fn_type->data.fn.raw_type_ref = LLVMFunctionType(gen_return_type->type_ref,
745 gen_param_types, gen_param_index, fn_type_id->is_var_args);
746 fn_type->type_ref = LLVMPointerType(fn_type->data.fn.raw_type_ref, 0);
747 fn_type->di_type = ZigLLVMCreateSubroutineType(g->dbuilder, param_di_types, gen_param_index + 1, 0);
748 }
749810
750 g->fn_type_table.put(&fn_type->data.fn.fn_type_id, fn_type);811 g->fn_type_table.put(&fn_type->data.fn.fn_type_id, fn_type);
751812
...@@ -767,6 +828,7 @@ static TypeTableEntryId container_to_type(ContainerKind kind) {...@@ -767,6 +828,7 @@ static TypeTableEntryId container_to_type(ContainerKind kind) {
767TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, Scope *scope,828TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, Scope *scope,
768 ContainerKind kind, AstNode *decl_node, const char *name)829 ContainerKind kind, AstNode *decl_node, const char *name)
769{830{
831
770 TypeTableEntryId type_id = container_to_type(kind);832 TypeTableEntryId type_id = container_to_type(kind);
771 TypeTableEntry *entry = new_container_type_entry(type_id, decl_node, scope);833 TypeTableEntry *entry = new_container_type_entry(type_id, decl_node, scope);
772834
...@@ -782,7 +844,7 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import,...@@ -782,7 +844,7 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import,
782 break;844 break;
783 }845 }
784846
785 unsigned line = decl_node ? decl_node->line : 0;847 unsigned line = decl_node->line;
786848
787 entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), name);849 entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), name);
788 entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,850 entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
...@@ -794,6 +856,14 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import,...@@ -794,6 +856,14 @@ TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import,
794 return entry;856 return entry;
795}857}
796858
859static TypeTableEntry *get_partial_container_type_tld(CodeGen *g, Scope *scope, TldContainer *tld_container) {
860 ImportTableEntry *import = tld_container->base.import;
861 AstNode *container_node = tld_container->base.source_node;
862 assert(container_node->type == NodeTypeContainerDecl);
863 ContainerKind kind = container_node->data.struct_decl.kind;
864 return get_partial_container_type(g, import, scope, kind, container_node, buf_ptr(tld_container->base.name));
865}
866
797867
798TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry) {868TypeTableEntry *get_underlying_type(TypeTableEntry *type_entry) {
799 if (type_entry->id == TypeTableEntryIdTypeDecl) {869 if (type_entry->id == TypeTableEntryIdTypeDecl) {
...@@ -842,9 +912,7 @@ static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *nod...@@ -842,9 +912,7 @@ static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *nod
842 return result;912 return result;
843}913}
844914
845static TypeTableEntry *analyze_type_expr(CodeGen *g, ImportTableEntry *import, Scope *scope,915static TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
846 AstNode *node)
847{
848 IrInstruction *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type);916 IrInstruction *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type);
849 if (result->type_entry->id == TypeTableEntryIdInvalid)917 if (result->type_entry->id == TypeTableEntryIdInvalid)
850 return g->builtin_types.entry_invalid;918 return g->builtin_types.entry_invalid;
...@@ -853,71 +921,77 @@ static TypeTableEntry *analyze_type_expr(CodeGen *g, ImportTableEntry *import, S...@@ -853,71 +921,77 @@ static TypeTableEntry *analyze_type_expr(CodeGen *g, ImportTableEntry *import, S
853 return result->static_value.data.x_type;921 return result->static_value.data.x_type;
854}922}
855923
856static bool fn_wants_full_static_eval(FnTableEntry *fn_table_entry) {924static TypeTableEntry *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
857 assert(fn_table_entry);925 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn);
858 return false;926 fn_type->data.fn.fn_type_id = *fn_type_id;
927 fn_type->data.fn.is_generic = true;
928 return fn_type;
859}929}
860930
861// fn_table_entry is populated if and only if there is a function definition for this prototype931static TypeTableEntry *analyze_fn_type(CodeGen *g, TldFn *tld_fn) {
862static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *import, Scope *scope,932 AstNode *proto_node = tld_fn->base.source_node;
863 TypeTableEntry *expected_type, AstNode *node, bool is_naked, bool is_cold, FnTableEntry *fn_table_entry)933 assert(proto_node->type == NodeTypeFnProto);
864{934 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
865 assert(node->type == NodeTypeFnProto);
866 AstNodeFnProto *fn_proto = &node->data.fn_proto;
867
868 if (fn_proto->skip) {
869 return g->builtin_types.entry_invalid;
870 }
871935
872 FnTypeId fn_type_id = {0};936 FnTypeId fn_type_id = {0};
873 fn_type_id.is_extern = fn_proto->is_extern || (fn_proto->top_level_decl.visib_mod == VisibModExport);937 fn_type_id.is_extern = fn_proto->is_extern || (fn_proto->visib_mod == VisibModExport);
874 fn_type_id.is_naked = is_naked;938 fn_type_id.is_naked = fn_proto->is_nakedcc;
875 fn_type_id.is_cold = is_cold;939 fn_type_id.is_cold = fn_proto->is_coldcc;
876 fn_type_id.param_count = fn_proto->params.length;940 fn_type_id.param_count = fn_proto->params.length;
877 fn_type_id.param_info = allocate_nonzero<FnTypeParamInfo>(fn_type_id.param_count);941 fn_type_id.param_info = allocate_nonzero<FnTypeParamInfo>(fn_type_id.param_count);
878942 fn_type_id.next_param_index = 0;
879 fn_type_id.is_var_args = fn_proto->is_var_args;943 fn_type_id.is_var_args = fn_proto->is_var_args;
880944
881 for (size_t i = 0; i < fn_type_id.param_count; i += 1) {945 FnTableEntry *fn_entry = tld_fn->fn_entry;
882 AstNode *child = fn_proto->params.at(i);946 Scope *child_scope = fn_entry->fndef_scope ? &fn_entry->fndef_scope->base : tld_fn->base.parent_scope;
883 assert(child->type == NodeTypeParamDecl);
884947
885 TypeTableEntry *type_entry;948 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) {
886 if (fn_proto->skip) {949 AstNode *param_node = fn_proto->params.at(fn_type_id.next_param_index);
887 type_entry = g->builtin_types.entry_invalid;950 assert(param_node->type == NodeTypeParamDecl);
888 } else {951
889 type_entry = analyze_type_expr(g, import, scope, child->data.param_decl.type);952 bool param_is_inline = param_node->data.param_decl.is_inline;
953
954 if (param_is_inline) {
955 if (fn_type_id.is_extern) {
956 add_node_error(g, param_node,
957 buf_sprintf("inline parameter not allowed in extern function"));
958 return g->builtin_types.entry_invalid;
959 }
960 return get_generic_fn_type(g, &fn_type_id);
961 }
962
963 if (fn_entry && buf_len(param_node->data.param_decl.name) == 0) {
964 add_node_error(g, param_node, buf_sprintf("missing parameter name"));
890 }965 }
891966
967 TypeTableEntry *type_entry = analyze_type_expr(g, child_scope, param_node->data.param_decl.type);
968
892 switch (type_entry->id) {969 switch (type_entry->id) {
893 case TypeTableEntryIdInvalid:970 case TypeTableEntryIdInvalid:
894 fn_proto->skip = true;971 return g->builtin_types.entry_invalid;
895 break;972 case TypeTableEntryIdUnreachable:
896 case TypeTableEntryIdNumLitFloat:
897 case TypeTableEntryIdNumLitInt:
898 case TypeTableEntryIdUndefLit:973 case TypeTableEntryIdUndefLit:
899 case TypeTableEntryIdNullLit:974 case TypeTableEntryIdNullLit:
900 case TypeTableEntryIdUnreachable:975 add_node_error(g, param_node->data.param_decl.type,
976 buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name)));
977 return g->builtin_types.entry_invalid;
978 case TypeTableEntryIdVar:
979 if (fn_type_id.is_extern) {
980 add_node_error(g, param_node->data.param_decl.type,
981 buf_sprintf("parameter of type 'var' not allowed in extern function"));
982 return g->builtin_types.entry_invalid;
983 }
984 return get_generic_fn_type(g, &fn_type_id);
985 case TypeTableEntryIdNumLitFloat:
986 case TypeTableEntryIdNumLitInt:
901 case TypeTableEntryIdNamespace:987 case TypeTableEntryIdNamespace:
902 case TypeTableEntryIdBlock:988 case TypeTableEntryIdBlock:
903 case TypeTableEntryIdGenericFn:
904 case TypeTableEntryIdBoundFn:989 case TypeTableEntryIdBoundFn:
905 if (!fn_proto->skip) {
906 fn_proto->skip = true;
907 add_node_error(g, child->data.param_decl.type,
908 buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name)));
909 }
910 break;
911 case TypeTableEntryIdMetaType:990 case TypeTableEntryIdMetaType:
912 if (!child->data.param_decl.is_inline) {991 add_node_error(g, param_node->data.param_decl.type,
913 if (!fn_proto->skip) {992 buf_sprintf("parameter of type '%s' must be declared inline",
914 fn_proto->skip = true;993 buf_ptr(&type_entry->name)));
915 add_node_error(g, child->data.param_decl.type,994 return g->builtin_types.entry_invalid;
916 buf_sprintf("parameter of type '%s' must be declared inline",
917 buf_ptr(&type_entry->name)));
918 }
919 }
920 break;
921 case TypeTableEntryIdVoid:995 case TypeTableEntryIdVoid:
922 case TypeTableEntryIdBool:996 case TypeTableEntryIdBool:
923 case TypeTableEntryIdInt:997 case TypeTableEntryIdInt:
...@@ -933,44 +1007,38 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -933,44 +1007,38 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
933 case TypeTableEntryIdFn:1007 case TypeTableEntryIdFn:
934 case TypeTableEntryIdTypeDecl:1008 case TypeTableEntryIdTypeDecl:
935 break;1009 break;
936 case TypeTableEntryIdVar:
937 // var types are treated as generic functions; if we get to this code we should
938 // already be an instantiated function.
939 zig_unreachable();
940 }1010 }
941 if (type_entry->id == TypeTableEntryIdInvalid) {1011 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index];
942 fn_proto->skip = true;
943 }
944 FnTypeParamInfo *param_info = &fn_type_id.param_info[i];
945 param_info->type = type_entry;1012 param_info->type = type_entry;
946 param_info->is_noalias = child->data.param_decl.is_noalias;1013 param_info->is_noalias = param_node->data.param_decl.is_noalias;
947 }1014 }
9481015
949 if (fn_proto->skip) {1016 fn_type_id.return_type = analyze_type_expr(g, child_scope, fn_proto->return_type);
950 fn_type_id.return_type = g->builtin_types.entry_invalid;1017
951 } else {
952 fn_type_id.return_type = analyze_type_expr(g, import, scope, fn_proto->return_type);
953 }
954 switch (fn_type_id.return_type->id) {1018 switch (fn_type_id.return_type->id) {
955 case TypeTableEntryIdInvalid:1019 case TypeTableEntryIdInvalid:
956 fn_proto->skip = true;1020 return g->builtin_types.entry_invalid;
957 break;1021
958 case TypeTableEntryIdNumLitFloat:
959 case TypeTableEntryIdNumLitInt:
960 case TypeTableEntryIdUndefLit:1022 case TypeTableEntryIdUndefLit:
961 case TypeTableEntryIdNullLit:1023 case TypeTableEntryIdNullLit:
1024 add_node_error(g, fn_proto->return_type,
1025 buf_sprintf("return type '%s' not allowed", buf_ptr(&fn_type_id.return_type->name)));
1026 return g->builtin_types.entry_invalid;
1027
1028 case TypeTableEntryIdNumLitFloat:
1029 case TypeTableEntryIdNumLitInt:
962 case TypeTableEntryIdNamespace:1030 case TypeTableEntryIdNamespace:
963 case TypeTableEntryIdBlock:1031 case TypeTableEntryIdBlock:
964 case TypeTableEntryIdGenericFn:
965 case TypeTableEntryIdBoundFn:1032 case TypeTableEntryIdBoundFn:
966 case TypeTableEntryIdVar:1033 case TypeTableEntryIdVar:
967 if (!fn_proto->skip) {1034 case TypeTableEntryIdMetaType:
968 fn_proto->skip = true;1035 if (fn_type_id.is_extern) {
969 add_node_error(g, fn_proto->return_type,1036 add_node_error(g, fn_proto->return_type,
970 buf_sprintf("return type '%s' not allowed", buf_ptr(&fn_type_id.return_type->name)));1037 buf_sprintf("return type '%s' not allowed in extern function",
1038 buf_ptr(&fn_type_id.return_type->name)));
1039 return g->builtin_types.entry_invalid;
971 }1040 }
972 break;1041 return get_generic_fn_type(g, &fn_type_id);
973 case TypeTableEntryIdMetaType:
974 case TypeTableEntryIdUnreachable:1042 case TypeTableEntryIdUnreachable:
975 case TypeTableEntryIdVoid:1043 case TypeTableEntryIdVoid:
976 case TypeTableEntryIdBool:1044 case TypeTableEntryIdBool:
...@@ -989,114 +1057,10 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -989,114 +1057,10 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
989 break;1057 break;
990 }1058 }
9911059
9921060 return get_fn_type(g, &fn_type_id);
993 if (fn_proto->skip) {
994 return g->builtin_types.entry_invalid;
995 }
996
997 if (fn_table_entry && fn_type_id.return_type->id == TypeTableEntryIdMetaType) {
998 ErrorMsg *err_msg = nullptr;
999 for (size_t i = 0; i < fn_proto->params.length; i += 1) {
1000 AstNode *param_decl_node = fn_proto->params.at(i);
1001 assert(param_decl_node->type == NodeTypeParamDecl);
1002 if (!param_decl_node->data.param_decl.is_inline) {
1003 if (!err_msg) {
1004 err_msg = add_node_error(g, fn_proto->return_type,
1005 buf_sprintf("function with return type '%s' must declare all parameters inline",
1006 buf_ptr(&fn_type_id.return_type->name)));
1007 }
1008 add_error_note(g, err_msg, param_decl_node,
1009 buf_sprintf("non-inline parameter here"));
1010 }
1011 }
1012 if (err_msg) {
1013 fn_proto->skip = true;
1014 return g->builtin_types.entry_invalid;
1015 }
1016 }
1017
1018 bool gen_debug_info = fn_table_entry && !fn_wants_full_static_eval(fn_table_entry);
1019 return get_fn_type(g, &fn_type_id, gen_debug_info);
1020}
1021
1022static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_table_entry,
1023 ImportTableEntry *import, Scope *containing_scope)
1024{
1025 assert(node->type == NodeTypeFnProto);
1026 AstNodeFnProto *fn_proto = &node->data.fn_proto;
1027
1028 if (fn_proto->skip) {
1029 return;
1030 }
1031
1032 bool is_internal = (fn_proto->top_level_decl.visib_mod != VisibModExport);
1033 bool is_c_compat = !is_internal || fn_proto->is_extern;
1034 fn_table_entry->internal_linkage = !is_c_compat;
1035
1036
1037
1038 TypeTableEntry *fn_type = analyze_fn_proto_type(g, import, containing_scope, nullptr, node,
1039 fn_proto->is_nakedcc, fn_proto->is_coldcc, fn_table_entry);
1040
1041 fn_table_entry->type_entry = fn_type;
1042
1043 if (fn_type->id == TypeTableEntryIdInvalid) {
1044 fn_proto->skip = true;
1045 return;
1046 }
1047
1048 if (fn_proto->is_inline) {
1049 fn_table_entry->fn_inline = FnInlineAlways;
1050 }
1051
1052
1053 Buf *symbol_name;
1054 if (is_c_compat) {
1055 symbol_name = &fn_table_entry->symbol_name;
1056 } else {
1057 symbol_name = buf_sprintf("_%s", buf_ptr(&fn_table_entry->symbol_name));
1058 }
1059
1060 if (fn_table_entry->fn_def_node) {
1061 fn_table_entry->fn_def_node->data.fn_def.containing_scope = create_fndef_scope(
1062 fn_table_entry->fn_def_node, containing_scope, fn_table_entry);
1063 }
1064
1065 if (!fn_wants_full_static_eval(fn_table_entry)) {
1066 fn_table_entry->fn_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_type->data.fn.raw_type_ref);
1067
1068 switch (fn_table_entry->fn_inline) {
1069 case FnInlineAlways:
1070 LLVMAddFunctionAttr(fn_table_entry->fn_value, LLVMAlwaysInlineAttribute);
1071 break;
1072 case FnInlineNever:
1073 LLVMAddFunctionAttr(fn_table_entry->fn_value, LLVMNoInlineAttribute);
1074 break;
1075 case FnInlineAuto:
1076 break;
1077 }
1078 if (fn_type->data.fn.fn_type_id.is_naked) {
1079 LLVMAddFunctionAttr(fn_table_entry->fn_value, LLVMNakedAttribute);
1080 }
1081
1082 LLVMSetLinkage(fn_table_entry->fn_value, fn_table_entry->internal_linkage ?
1083 LLVMInternalLinkage : LLVMExternalLinkage);
1084
1085 if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdUnreachable) {
1086 LLVMAddFunctionAttr(fn_table_entry->fn_value, LLVMNoReturnAttribute);
1087 }
1088 LLVMSetFunctionCallConv(fn_table_entry->fn_value, fn_type->data.fn.calling_convention);
1089 if (!fn_table_entry->is_extern) {
1090 LLVMAddFunctionAttr(fn_table_entry->fn_value, LLVMNoUnwindAttribute);
1091 }
1092 if (!g->is_release_build && fn_table_entry->fn_inline != FnInlineAlways) {
1093 ZigLLVMAddFunctionAttr(fn_table_entry->fn_value, "no-frame-pointer-elim", "true");
1094 ZigLLVMAddFunctionAttr(fn_table_entry->fn_value, "no-frame-pointer-elim-non-leaf", nullptr);
1095 }
1096 }
1097}1061}
10981062
1099static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type) {1063static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
1100 // if you change this logic you likely must also change similar logic in parseh.cpp1064 // if you change this logic you likely must also change similar logic in parseh.cpp
1101 assert(enum_type->id == TypeTableEntryIdEnum);1065 assert(enum_type->id == TypeTableEntryIdEnum);
11021066
...@@ -1133,6 +1097,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -1133,6 +1097,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
1133 uint64_t biggest_union_member_size_in_bits = 0;1097 uint64_t biggest_union_member_size_in_bits = 0;
11341098
1135 Scope *scope = &enum_type->data.enumeration.decls_scope->base;1099 Scope *scope = &enum_type->data.enumeration.decls_scope->base;
1100 ImportTableEntry *import = get_scope_import(scope);
11361101
1137 // set temporary flag1102 // set temporary flag
1138 enum_type->data.enumeration.embedded_in_current = true;1103 enum_type->data.enumeration.embedded_in_current = true;
...@@ -1142,17 +1107,16 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -1142,17 +1107,16 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
1142 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);1107 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);
1143 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];1108 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];
1144 type_enum_field->name = field_node->data.struct_field.name;1109 type_enum_field->name = field_node->data.struct_field.name;
1145 TypeTableEntry *field_type = analyze_type_expr(g, import, scope,1110 TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type);
1146 field_node->data.struct_field.type);
1147 type_enum_field->type_entry = field_type;1111 type_enum_field->type_entry = field_type;
1148 type_enum_field->value = i;1112 type_enum_field->value = i;
11491113
1150 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);1114 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i);
11511115
1152 if (field_type->id == TypeTableEntryIdStruct) {1116 if (field_type->id == TypeTableEntryIdStruct) {
1153 resolve_struct_type(g, import, field_type);1117 resolve_struct_type(g, field_type);
1154 } else if (field_type->id == TypeTableEntryIdEnum) {1118 } else if (field_type->id == TypeTableEntryIdEnum) {
1155 resolve_enum_type(g, import, field_type);1119 resolve_enum_type(g, field_type);
1156 } else if (field_type->id == TypeTableEntryIdInvalid) {1120 } else if (field_type->id == TypeTableEntryIdInvalid) {
1157 enum_type->data.enumeration.is_invalid = true;1121 enum_type->data.enumeration.is_invalid = true;
1158 continue;1122 continue;
...@@ -1281,7 +1245,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt...@@ -1281,7 +1245,7 @@ static void resolve_enum_type(CodeGen *g, ImportTableEntry *import, TypeTableEnt
1281 }1245 }
1282}1246}
12831247
1284static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *struct_type) {1248static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
1285 // if you change the logic of this function likely you must make a similar change in1249 // if you change the logic of this function likely you must make a similar change in
1286 // parseh.cpp1250 // parseh.cpp
1287 assert(struct_type->id == TypeTableEntryIdStruct);1251 assert(struct_type->id == TypeTableEntryIdStruct);
...@@ -1319,22 +1283,23 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -1319,22 +1283,23 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
1319 struct_type->data.structure.embedded_in_current = true;1283 struct_type->data.structure.embedded_in_current = true;
13201284
1321 Scope *scope = &struct_type->data.structure.decls_scope->base;1285 Scope *scope = &struct_type->data.structure.decls_scope->base;
1286 ImportTableEntry *import = get_scope_import(scope);
13221287
1323 size_t gen_field_index = 0;1288 size_t gen_field_index = 0;
1324 for (size_t i = 0; i < field_count; i += 1) {1289 for (size_t i = 0; i < field_count; i += 1) {
1325 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);1290 AstNode *field_node = decl_node->data.struct_decl.fields.at(i);
1326 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];1291 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
1327 type_struct_field->name = field_node->data.struct_field.name;1292 type_struct_field->name = field_node->data.struct_field.name;
1328 TypeTableEntry *field_type = analyze_type_expr(g, import, scope,1293 TypeTableEntry *field_type = analyze_type_expr(g, scope,
1329 field_node->data.struct_field.type);1294 field_node->data.struct_field.type);
1330 type_struct_field->type_entry = field_type;1295 type_struct_field->type_entry = field_type;
1331 type_struct_field->src_index = i;1296 type_struct_field->src_index = i;
1332 type_struct_field->gen_index = SIZE_MAX;1297 type_struct_field->gen_index = SIZE_MAX;
13331298
1334 if (field_type->id == TypeTableEntryIdStruct) {1299 if (field_type->id == TypeTableEntryIdStruct) {
1335 resolve_struct_type(g, import, field_type);1300 resolve_struct_type(g, field_type);
1336 } else if (field_type->id == TypeTableEntryIdEnum) {1301 } else if (field_type->id == TypeTableEntryIdEnum) {
1337 resolve_enum_type(g, import, field_type);1302 resolve_enum_type(g, field_type);
1338 } else if (field_type->id == TypeTableEntryIdInvalid) {1303 } else if (field_type->id == TypeTableEntryIdInvalid) {
1339 struct_type->data.structure.is_invalid = true;1304 struct_type->data.structure.is_invalid = true;
1340 continue;1305 continue;
...@@ -1408,16 +1373,13 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE...@@ -1408,16 +1373,13 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE
1408 struct_type->zero_bits = (debug_size_in_bits == 0);1373 struct_type->zero_bits = (debug_size_in_bits == 0);
1409}1374}
14101375
1411static void resolve_union_type(CodeGen *g, ImportTableEntry *import, TypeTableEntry *enum_type) {1376static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
1412 zig_panic("TODO");1377 zig_panic("TODO");
1413}1378}
14141379
1415static void get_fully_qualified_decl_name(Buf *buf, AstNode *decl_node, uint8_t sep) {1380static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) {
1416 TopLevelDecl *tld = get_as_top_level_decl(decl_node);1381 if (tld->parent_tld) {
1417 AstNode *parent_decl = tld->parent_decl;1382 get_fully_qualified_decl_name(buf, tld->parent_tld, sep);
1418
1419 if (parent_decl) {
1420 get_fully_qualified_decl_name(buf, parent_decl, sep);
1421 buf_append_char(buf, sep);1383 buf_append_char(buf, sep);
1422 buf_append_buf(buf, tld->name);1384 buf_append_buf(buf, tld->name);
1423 } else {1385 } else {
...@@ -1425,183 +1387,109 @@ static void get_fully_qualified_decl_name(Buf *buf, AstNode *decl_node, uint8_t...@@ -1425,183 +1387,109 @@ static void get_fully_qualified_decl_name(Buf *buf, AstNode *decl_node, uint8_t
1425 }1387 }
1426}1388}
14271389
1428static void preview_generic_fn_proto(CodeGen *g, ImportTableEntry *import, AstNode *node) {1390static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
1429 assert(node->type == NodeTypeContainerDecl);1391 ImportTableEntry *import = tld_fn->base.import;
14301392 AstNode *proto_node = tld_fn->base.source_node;
1431 if (node->data.struct_decl.generic_params_is_var_args) {
1432 add_node_error(g, node, buf_sprintf("generic parameters cannot be var args"));
1433 node->data.struct_decl.skip = true;
1434 node->data.struct_decl.generic_fn_type = g->builtin_types.entry_invalid;
1435 return;
1436 }
1437
1438 node->data.struct_decl.generic_fn_type = get_generic_fn_type(g, node);
1439}
1440
1441static bool get_is_generic_fn(AstNode *proto_node) {
1442 assert(proto_node->type == NodeTypeFnProto);1393 assert(proto_node->type == NodeTypeFnProto);
1443 return proto_node->data.fn_proto.inline_or_var_type_arg_count > 0;1394 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
1444}
1445
1446static void preview_fn_proto_instance(CodeGen *g, ImportTableEntry *import, AstNode *proto_node,
1447 Scope *containing_scope)
1448{
1449 assert(proto_node->type == NodeTypeFnProto);
1450
1451 if (proto_node->data.fn_proto.skip) {
1452 return;
1453 }
14541395
1455 bool is_generic_instance = proto_node->data.fn_proto.generic_proto_node;1396 AstNode *fn_def_node = fn_proto->fn_def_node;
1456 bool is_generic_fn = get_is_generic_fn(proto_node);
1457 assert(!is_generic_instance || !is_generic_fn);
14581397
1459 AstNode *parent_decl = proto_node->data.fn_proto.top_level_decl.parent_decl;1398 if (fn_def_node && fn_proto->is_var_args) {
1460 Buf *proto_name = proto_node->data.fn_proto.name;
1461
1462 AstNode *fn_def_node = proto_node->data.fn_proto.fn_def_node;
1463 bool is_extern = proto_node->data.fn_proto.is_extern;
1464
1465 assert(!is_extern || !is_generic_instance);
1466
1467 if (fn_def_node && proto_node->data.fn_proto.is_var_args) {
1468 add_node_error(g, proto_node,1399 add_node_error(g, proto_node,
1469 buf_sprintf("variadic arguments only allowed in extern function declarations"));1400 buf_sprintf("variadic arguments only allowed in extern function declarations"));
1401 tld_fn->base.resolution = TldResolutionInvalid;
1402 return;
1470 }1403 }
14711404
1472 FnTableEntry *fn_table_entry = allocate<FnTableEntry>(1);1405 FnTableEntry *fn_table_entry = allocate<FnTableEntry>(1);
1473 fn_table_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota;1406 fn_table_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota;
1407 fn_table_entry->ir_executable.fn_entry = fn_table_entry;
1408 fn_table_entry->analyzed_executable.fn_entry = fn_table_entry;
1474 fn_table_entry->import_entry = import;1409 fn_table_entry->import_entry = import;
1475 fn_table_entry->proto_node = proto_node;1410 fn_table_entry->proto_node = proto_node;
1476 fn_table_entry->fn_def_node = fn_def_node;1411 fn_table_entry->fn_def_node = fn_def_node;
1477 fn_table_entry->is_extern = is_extern;1412 fn_table_entry->fn_inline = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto;
1413 fn_table_entry->internal_linkage = (fn_proto->visib_mod != VisibModExport);
14781414
1479 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, proto_node, '_');1415 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
14801416
1481 proto_node->data.fn_proto.fn_table_entry = fn_table_entry;1417 tld_fn->fn_entry = fn_table_entry;
14821418
1483 if (is_generic_fn) {1419 if (fn_table_entry->fn_def_node) {
1484 fn_table_entry->type_entry = get_generic_fn_type(g, proto_node);1420 fn_table_entry->fndef_scope = create_fndef_scope(
1421 fn_table_entry->fn_def_node, tld_fn->base.parent_scope, fn_table_entry);
1422 }
14851423
1486 if (is_extern || proto_node->data.fn_proto.top_level_decl.visib_mod == VisibModExport) {1424 fn_table_entry->type_entry = analyze_fn_type(g, tld_fn);
1487 for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
1488 AstNode *param_decl_node = proto_node->data.fn_proto.params.at(i);
1489 if (param_decl_node->data.param_decl.is_inline) {
1490 proto_node->data.fn_proto.skip = true;
1491 add_node_error(g, param_decl_node,
1492 buf_sprintf("inline parameter not allowed in extern function"));
1493 }
1494 }
1495 }
14961425
1426 if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) {
1427 tld_fn->base.resolution = TldResolutionInvalid;
1428 return;
1429 }
14971430
1498 } else {1431 if (!fn_table_entry->type_entry->data.fn.is_generic) {
1499 resolve_function_proto(g, proto_node, fn_table_entry, import, containing_scope);1432 g->fn_protos.append(fn_table_entry);
15001433
1501 if (!fn_wants_full_static_eval(fn_table_entry)) {1434 if (fn_def_node)
1502 g->fn_protos.append(fn_table_entry);1435 g->fn_defs.append(fn_table_entry);
15031436
1504 if (fn_def_node) {1437 Tld *parent_tld = tld_fn->base.parent_tld;
1505 g->fn_defs.append(fn_table_entry);1438 bool is_main_fn = !parent_tld && (import == g->root_import) &&
1506 }1439 buf_eql_str(&fn_table_entry->symbol_name, "main");
1440 if (is_main_fn)
1441 g->main_fn = fn_table_entry;
15071442
1508 bool is_main_fn = !is_generic_instance &&1443 if (is_main_fn && !g->link_libc) {
1509 !parent_decl && (import == g->root_import) &&1444 TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void);
1510 !proto_node->data.fn_proto.skip &&1445 TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type;
1511 buf_eql_str(proto_name, "main");1446 if (actual_return_type != err_void) {
1512 if (is_main_fn) {1447 add_node_error(g, fn_proto->return_type,
1513 g->main_fn = fn_table_entry;1448 buf_sprintf("expected return type of main to be '%%void', instead is '%s'",
1514 }1449 buf_ptr(&actual_return_type->name)));
1515
1516 if (is_main_fn && !g->link_libc) {
1517 TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void);
1518 TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type;
1519 if (actual_return_type != err_void) {
1520 AstNode *return_type_node = fn_table_entry->proto_node->data.fn_proto.return_type;
1521 add_node_error(g, return_type_node,
1522 buf_sprintf("expected return type of main to be '%%void', instead is '%s'",
1523 buf_ptr(&actual_return_type->name)));
1524 }
1525 }1450 }
1526 }1451 }
1527 }1452 }
1528}1453}
15291454
1530static void add_top_level_decl(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope,1455static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
1531 AstNode *node, Buf *name)
1532{
1533 assert(import);
1534
1535 TopLevelDecl *tld = get_as_top_level_decl(node);
1536 tld->import = import;
1537 tld->name = name;
1538
1539 bool want_to_resolve = (g->check_unused || g->is_test_build || tld->visib_mod == VisibModExport);1456 bool want_to_resolve = (g->check_unused || g->is_test_build || tld->visib_mod == VisibModExport);
1540 bool is_generic_container = (node->type == NodeTypeContainerDecl &&1457 if (want_to_resolve)
1541 node->data.struct_decl.generic_params.length > 0);1458 g->resolve_queue.append(tld);
1542 if (want_to_resolve && !is_generic_container) {
1543 g->resolve_queue.append(node);
1544 }
15451459
1546 node->scope = &decls_scope->base;1460 auto entry = decls_scope->decl_table.put_unique(tld->name, tld);
1547
1548 auto entry = decls_scope->decl_table.put_unique(name, node);
1549 if (entry) {1461 if (entry) {
1550 AstNode *other_decl_node = entry->value;1462 Tld *other_tld = entry->value;
1551 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("redefinition of '%s'", buf_ptr(name)));1463 ErrorMsg *msg = add_node_error(g, tld->source_node, buf_sprintf("redefinition of '%s'", buf_ptr(tld->name)));
1552 add_error_note(g, msg, other_decl_node, buf_sprintf("previous definition is here"));1464 add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition is here"));
1465 return;
1553 }1466 }
1554}1467}
15551468
1556static void scan_struct_decl(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, AstNode *node) {1469static void scan_struct_decl(CodeGen *g, ScopeDecls *decls_scope, TldContainer *tld_container) {
1557 assert(node->type == NodeTypeContainerDecl);1470 assert(!tld_container->type_entry);
15581471
1559 if (node->data.struct_decl.type_entry) {1472 AstNode *container_node = tld_container->base.source_node;
1560 // already scanned; we can ignore. This can happen from importing from an .h file.1473 assert(container_node->type == NodeTypeContainerDecl);
1561 return;
1562 }
15631474
1564 Buf *name = node->data.struct_decl.name;1475 TypeTableEntry *container_type = get_partial_container_type_tld(g, &decls_scope->base, tld_container);
1565 TypeTableEntry *container_type = get_partial_container_type(g, import, &decls_scope->base,1476 tld_container->type_entry = container_type;
1566 node->data.struct_decl.kind, node, buf_ptr(name));
1567 node->data.struct_decl.type_entry = container_type;
15681477
1569 // handle the member function definitions independently1478 // handle the member function definitions independently
1570 for (size_t i = 0; i < node->data.struct_decl.decls.length; i += 1) {1479 for (size_t i = 0; i < container_node->data.struct_decl.decls.length; i += 1) {
1571 AstNode *child_node = node->data.struct_decl.decls.at(i);1480 AstNode *child_node = container_node->data.struct_decl.decls.at(i);
1572 get_as_top_level_decl(child_node)->parent_decl = node;
1573 ScopeDecls *child_scope = get_container_scope(container_type);1481 ScopeDecls *child_scope = get_container_scope(container_type);
1574 scan_decls(g, import, child_scope, child_node);1482 scan_decls(g, tld_container->base.import, child_scope, child_node, &tld_container->base);
1575 }
1576}
1577
1578static void count_inline_and_var_args(AstNode *proto_node) {
1579 assert(proto_node->type == NodeTypeFnProto);
1580
1581 size_t *inline_arg_count = &proto_node->data.fn_proto.inline_arg_count;
1582 size_t *inline_or_var_type_arg_count = &proto_node->data.fn_proto.inline_or_var_type_arg_count;
1583
1584 *inline_arg_count = 0;
1585 *inline_or_var_type_arg_count = 0;
1586
1587 // TODO run these nodes through the type analysis system rather than looking for
1588 // specialized ast nodes. this would get fooled by `{var}` instead of `var` which
1589 // is supposed to be equivalent
1590 for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
1591 AstNode *param_node = proto_node->data.fn_proto.params.at(i);
1592 assert(param_node->type == NodeTypeParamDecl);
1593 if (param_node->data.param_decl.is_inline) {
1594 *inline_arg_count += 1;
1595 *inline_or_var_type_arg_count += 1;
1596 } else if (param_node->data.param_decl.type->type == NodeTypeVarLiteral) {
1597 *inline_or_var_type_arg_count += 1;
1598 }
1599 }1483 }
1600}1484}
16011485
1602static void preview_error_value_decl(CodeGen *g, AstNode *node) {1486static void preview_error_value_decl(CodeGen *g, AstNode *node) {
1603 assert(node->type == NodeTypeErrorValueDecl);1487 assert(node->type == NodeTypeErrorValueDecl);
16041488
1489 if (node->data.error_value_decl.visib_mod != VisibModPrivate) {
1490 add_node_error(g, node, buf_sprintf("error values require no visibility modifier"));
1491 }
1492
1605 ErrorTableEntry *err = allocate<ErrorTableEntry>(1);1493 ErrorTableEntry *err = allocate<ErrorTableEntry>(1);
16061494
1607 err->decl_node = node;1495 err->decl_node = node;
...@@ -1620,40 +1508,61 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {...@@ -1620,40 +1508,61 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {
1620 }1508 }
16211509
1622 node->data.error_value_decl.err = err;1510 node->data.error_value_decl.err = err;
1623 node->data.error_value_decl.top_level_decl.resolution = TldResolutionOk;
1624}1511}
16251512
1626void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, AstNode *node) {1513void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node,
1514 Scope *parent_scope, Tld *parent_tld)
1515{
1516 tld->id = id;
1517 tld->name = name;
1518 tld->visib_mod = visib_mod;
1519 tld->source_node = source_node;
1520 tld->import = source_node->owner;
1521 tld->parent_scope = parent_scope;
1522 tld->parent_tld = parent_tld;
1523}
1524
1525void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, AstNode *node, Tld *parent_tld) {
1627 switch (node->type) {1526 switch (node->type) {
1628 case NodeTypeRoot:1527 case NodeTypeRoot:
1629 for (size_t i = 0; i < import->root->data.root.top_level_decls.length; i += 1) {1528 for (size_t i = 0; i < import->root->data.root.top_level_decls.length; i += 1) {
1630 AstNode *child = import->root->data.root.top_level_decls.at(i);1529 AstNode *child = import->root->data.root.top_level_decls.at(i);
1631 scan_decls(g, import, decls_scope, child);1530 scan_decls(g, import, decls_scope, child, parent_tld);
1632 }1531 }
1633 break;1532 break;
1634 case NodeTypeContainerDecl:1533 case NodeTypeContainerDecl:
1635 {1534 {
1636 Buf *name = node->data.struct_decl.name;1535 Buf *name = node->data.struct_decl.name;
1637 add_top_level_decl(g, import, decls_scope, node, name);1536 VisibMod visib_mod = node->data.struct_decl.visib_mod;
1537 TldContainer *tld_container = allocate<TldContainer>(1);
1538 init_tld(&tld_container->base, TldIdContainer, name, visib_mod, node, &decls_scope->base, parent_tld);
1539 add_top_level_decl(g, decls_scope, &tld_container->base);
1638 if (node->data.struct_decl.generic_params.length == 0) {1540 if (node->data.struct_decl.generic_params.length == 0) {
1639 scan_struct_decl(g, import, decls_scope, node);1541 scan_struct_decl(g, decls_scope, tld_container);
1542 } else {
1543 zig_panic("TODO all structs anonymous?");
1640 }1544 }
1641 }1545 }
1642 break;1546 break;
1643 case NodeTypeFnDef:1547 case NodeTypeFnDef:
1644 node->data.fn_def.fn_proto->data.fn_proto.fn_def_node = node;1548 scan_decls(g, import, decls_scope, node->data.fn_def.fn_proto, parent_tld);
1645 scan_decls(g, import, decls_scope, node->data.fn_def.fn_proto);
1646 break;1549 break;
1647 case NodeTypeVariableDeclaration:1550 case NodeTypeVariableDeclaration:
1648 {1551 {
1649 Buf *name = node->data.variable_declaration.symbol;1552 Buf *name = node->data.variable_declaration.symbol;
1650 add_top_level_decl(g, import, decls_scope, node, name);1553 VisibMod visib_mod = node->data.variable_declaration.visib_mod;
1554 TldVar *tld_var = allocate<TldVar>(1);
1555 init_tld(&tld_var->base, TldIdVar, name, visib_mod, node, &decls_scope->base, parent_tld);
1556 add_top_level_decl(g, decls_scope, &tld_var->base);
1651 break;1557 break;
1652 }1558 }
1653 case NodeTypeTypeDecl:1559 case NodeTypeTypeDecl:
1654 {1560 {
1655 Buf *name = node->data.type_decl.symbol;1561 Buf *name = node->data.type_decl.symbol;
1656 add_top_level_decl(g, import, decls_scope, node, name);1562 VisibMod visib_mod = node->data.type_decl.visib_mod;
1563 TldTypeDef *tld_typedef = allocate<TldTypeDef>(1);
1564 init_tld(&tld_typedef->base, TldIdTypeDef, name, visib_mod, node, &decls_scope->base, parent_tld);
1565 add_top_level_decl(g, decls_scope, &tld_typedef->base);
1657 break;1566 break;
1658 }1567 }
1659 case NodeTypeFnProto:1568 case NodeTypeFnProto:
...@@ -1661,22 +1570,20 @@ void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, A...@@ -1661,22 +1570,20 @@ void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, A
1661 // if the name is missing, we immediately announce an error1570 // if the name is missing, we immediately announce an error
1662 Buf *fn_name = node->data.fn_proto.name;1571 Buf *fn_name = node->data.fn_proto.name;
1663 if (buf_len(fn_name) == 0) {1572 if (buf_len(fn_name) == 0) {
1664 node->data.fn_proto.skip = true;
1665 add_node_error(g, node, buf_sprintf("missing function name"));1573 add_node_error(g, node, buf_sprintf("missing function name"));
1666 break;1574 break;
1667 }1575 }
1668 count_inline_and_var_args(node);
16691576
1670 add_top_level_decl(g, import, decls_scope, node, fn_name);1577 VisibMod visib_mod = node->data.fn_proto.visib_mod;
1578 TldFn *tld_fn = allocate<TldFn>(1);
1579 init_tld(&tld_fn->base, TldIdFn, fn_name, visib_mod, node, &decls_scope->base, parent_tld);
1580 add_top_level_decl(g, decls_scope, &tld_fn->base);
1671 break;1581 break;
1672 }1582 }
1673 case NodeTypeUse:1583 case NodeTypeUse:
1674 {1584 {
1675 TopLevelDecl *tld = get_as_top_level_decl(node);
1676 tld->import = import;
1677 node->scope = &decls_scope->base;
1678 g->use_queue.append(node);1585 g->use_queue.append(node);
1679 tld->import->use_decls.append(node);1586 import->use_decls.append(node);
1680 break;1587 break;
1681 }1588 }
1682 case NodeTypeErrorValueDecl:1589 case NodeTypeErrorValueDecl:
...@@ -1727,30 +1634,22 @@ void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, A...@@ -1727,30 +1634,22 @@ void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, A
1727 }1634 }
1728}1635}
17291636
1730static void resolve_struct_instance(CodeGen *g, ImportTableEntry *import, AstNode *node) {1637static void resolve_decl_container(CodeGen *g, TldContainer *tld_container) {
1731 TypeTableEntry *type_entry = node->data.struct_decl.type_entry;1638 TypeTableEntry *type_entry = tld_container->type_entry;
1732 assert(type_entry);1639 assert(type_entry);
17331640
1734 // struct/enum member fns will get resolved independently1641 switch (type_entry->id) {
17351642 case TypeTableEntryIdStruct:
1736 switch (node->data.struct_decl.kind) {1643 resolve_struct_type(g, tld_container->type_entry);
1737 case ContainerKindStruct:1644 return;
1738 resolve_struct_type(g, import, type_entry);
1739 break;
1740 case ContainerKindEnum:1645 case ContainerKindEnum:
1741 resolve_enum_type(g, import, type_entry);1646 resolve_enum_type(g, tld_container->type_entry);
1742 break;1647 return;
1743 case ContainerKindUnion:1648 case ContainerKindUnion:
1744 resolve_union_type(g, import, type_entry);1649 resolve_union_type(g, tld_container->type_entry);
1745 break;1650 return;
1746 }1651 default:
1747}1652 zig_unreachable();
1748
1749static void resolve_struct_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
1750 if (node->data.struct_decl.generic_params.length > 0) {
1751 return preview_generic_fn_proto(g, import, node);
1752 } else {
1753 return resolve_struct_instance(g, import, node);
1754 }1653 }
1755}1654}
17561655
...@@ -1786,7 +1685,6 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt...@@ -1786,7 +1685,6 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt
1786 case TypeTableEntryIdEnum:1685 case TypeTableEntryIdEnum:
1787 case TypeTableEntryIdUnion:1686 case TypeTableEntryIdUnion:
1788 case TypeTableEntryIdFn:1687 case TypeTableEntryIdFn:
1789 case TypeTableEntryIdGenericFn:
1790 case TypeTableEntryIdBoundFn:1688 case TypeTableEntryIdBoundFn:
1791 return type_entry;1689 return type_entry;
1792 }1690 }
...@@ -1795,15 +1693,16 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt...@@ -1795,15 +1693,16 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt
17951693
1796// Set name to nullptr to make the variable anonymous (not visible to programmer).1694// Set name to nullptr to make the variable anonymous (not visible to programmer).
1797// TODO merge with definition of add_local_var in ir.cpp1695// TODO merge with definition of add_local_var in ir.cpp
1798static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, ImportTableEntry *import,1696VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name,
1799 Scope *parent_scope, Buf *name, TypeTableEntry *type_entry, bool is_const, AstNode *val_node)1697 TypeTableEntry *type_entry, bool is_const, ConstExprValue *init_value)
1800{1698{
1801 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);1699 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);
1802 variable_entry->type = type_entry;1700 variable_entry->type = type_entry;
1803 variable_entry->parent_scope = parent_scope;1701 variable_entry->parent_scope = parent_scope;
1804 variable_entry->import = import;
1805 variable_entry->shadowable = false;1702 variable_entry->shadowable = false;
1806 variable_entry->mem_slot_index = SIZE_MAX;1703 variable_entry->mem_slot_index = SIZE_MAX;
1704 variable_entry->value = init_value;
1705 variable_entry->src_arg_index = SIZE_MAX;
18071706
1808 assert(name);1707 assert(name);
18091708
...@@ -1824,11 +1723,11 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Impor...@@ -1824,11 +1723,11 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Impor
1824 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));1723 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));
1825 variable_entry->type = g->builtin_types.entry_invalid;1724 variable_entry->type = g->builtin_types.entry_invalid;
1826 } else {1725 } else {
1827 AstNode *decl_node = find_decl(parent_scope, name);1726 Tld *tld = find_decl(parent_scope, name);
1828 if (decl_node && decl_node->type != NodeTypeVariableDeclaration) {1727 if (tld && tld->id != TldIdVar) {
1829 ErrorMsg *msg = add_node_error(g, source_node,1728 ErrorMsg *msg = add_node_error(g, source_node,
1830 buf_sprintf("redefinition of '%s'", buf_ptr(name)));1729 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
1831 add_error_note(g, msg, decl_node, buf_sprintf("previous definition is here"));1730 add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here"));
1832 variable_entry->type = g->builtin_types.entry_invalid;1731 variable_entry->type = g->builtin_types.entry_invalid;
1833 }1732 }
1834 }1733 }
...@@ -1847,78 +1746,84 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Impor...@@ -1847,78 +1746,84 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Impor
1847 variable_entry->src_is_const = is_const;1746 variable_entry->src_is_const = is_const;
1848 variable_entry->gen_is_const = is_const;1747 variable_entry->gen_is_const = is_const;
1849 variable_entry->decl_node = source_node;1748 variable_entry->decl_node = source_node;
1850 variable_entry->val_node = val_node;
1851 variable_entry->child_scope = child_scope;1749 variable_entry->child_scope = child_scope;
18521750
18531751
1854 return variable_entry;1752 return variable_entry;
1855}1753}
18561754
1857static void resolve_var_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {1755static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
1858 assert(node->type == NodeTypeVariableDeclaration);1756 AstNodeVariableDeclaration *var_decl = &tld_var->base.source_node->data.variable_declaration;
18591757
1860 AstNodeVariableDeclaration *var_decl = &node->data.variable_declaration;
1861 Scope *scope = node->scope;
1862 bool is_const = var_decl->is_const;1758 bool is_const = var_decl->is_const;
1863 bool is_export = (var_decl->top_level_decl.visib_mod == VisibModExport);1759 bool is_export = (tld_var->base.visib_mod == VisibModExport);
1864 bool is_extern = var_decl->is_extern;1760 bool is_extern = var_decl->is_extern;
18651761
1866 TypeTableEntry *explicit_type = nullptr;1762 TypeTableEntry *explicit_type = nullptr;
1867 if (var_decl->type) {1763 if (var_decl->type) {
1868 TypeTableEntry *proposed_type = analyze_type_expr(g, import, scope, var_decl->type);1764 TypeTableEntry *proposed_type = analyze_type_expr(g, tld_var->base.parent_scope, var_decl->type);
1869 explicit_type = validate_var_type(g, var_decl->type, proposed_type);1765 explicit_type = validate_var_type(g, var_decl->type, proposed_type);
1870 }1766 }
18711767
1768 AstNode *source_node = tld_var->base.source_node;
1769
1770 IrInstruction *init_value = nullptr;
1771
1872 TypeTableEntry *implicit_type = nullptr;1772 TypeTableEntry *implicit_type = nullptr;
1873 if (explicit_type && explicit_type->id == TypeTableEntryIdInvalid) {1773 if (explicit_type && explicit_type->id == TypeTableEntryIdInvalid) {
1874 implicit_type = explicit_type;1774 implicit_type = explicit_type;
1875 } else if (var_decl->expr) {1775 } else if (var_decl->expr) {
1876 IrInstruction *result = analyze_const_value(g, scope, var_decl->expr, explicit_type);1776 init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type);
1877 assert(result);1777 assert(init_value);
1878 implicit_type = result->type_entry;1778 implicit_type = init_value->type_entry;
18791779
1880 if (implicit_type->id == TypeTableEntryIdUnreachable) {1780 if (implicit_type->id == TypeTableEntryIdUnreachable) {
1881 add_node_error(g, node, buf_sprintf("variable initialization is unreachable"));1781 add_node_error(g, source_node, buf_sprintf("variable initialization is unreachable"));
1882 implicit_type = g->builtin_types.entry_invalid;1782 implicit_type = g->builtin_types.entry_invalid;
1883 } else if ((!is_const || is_export) &&1783 } else if ((!is_const || is_export) &&
1884 (implicit_type->id == TypeTableEntryIdNumLitFloat ||1784 (implicit_type->id == TypeTableEntryIdNumLitFloat ||
1885 implicit_type->id == TypeTableEntryIdNumLitInt))1785 implicit_type->id == TypeTableEntryIdNumLitInt))
1886 {1786 {
1887 add_node_error(g, node, buf_sprintf("unable to infer variable type"));1787 add_node_error(g, source_node, buf_sprintf("unable to infer variable type"));
1888 implicit_type = g->builtin_types.entry_invalid;1788 implicit_type = g->builtin_types.entry_invalid;
1889 } else if (implicit_type->id == TypeTableEntryIdNullLit) {1789 } else if (implicit_type->id == TypeTableEntryIdNullLit) {
1890 add_node_error(g, node, buf_sprintf("unable to infer variable type"));1790 add_node_error(g, source_node, buf_sprintf("unable to infer variable type"));
1891 implicit_type = g->builtin_types.entry_invalid;1791 implicit_type = g->builtin_types.entry_invalid;
1892 } else if (implicit_type->id == TypeTableEntryIdMetaType && !is_const) {1792 } else if (implicit_type->id == TypeTableEntryIdMetaType && !is_const) {
1893 add_node_error(g, node, buf_sprintf("variable of type 'type' must be constant"));1793 add_node_error(g, source_node, buf_sprintf("variable of type 'type' must be constant"));
1894 implicit_type = g->builtin_types.entry_invalid;1794 implicit_type = g->builtin_types.entry_invalid;
1895 }1795 }
1896 if (implicit_type->id != TypeTableEntryIdInvalid) {1796 assert(implicit_type->id == TypeTableEntryIdInvalid || init_value->static_value.special != ConstValSpecialRuntime);
1897 assert(result->static_value.special != ConstValSpecialRuntime);
1898 var_decl->top_level_decl.value = result;
1899 }
1900 } else if (!is_extern) {1797 } else if (!is_extern) {
1901 add_node_error(g, node, buf_sprintf("variables must be initialized"));1798 add_node_error(g, source_node, buf_sprintf("variables must be initialized"));
1902 implicit_type = g->builtin_types.entry_invalid;1799 implicit_type = g->builtin_types.entry_invalid;
1903 }1800 }
19041801
1905 TypeTableEntry *type = explicit_type ? explicit_type : implicit_type;1802 TypeTableEntry *type = explicit_type ? explicit_type : implicit_type;
1906 assert(type != nullptr); // should have been caught by the parser1803 assert(type != nullptr); // should have been caught by the parser
19071804
1908 VariableTableEntry *var = add_local_var(g, node, import, scope,1805 tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope,
1909 var_decl->symbol, type, is_const, var_decl->expr);1806 var_decl->symbol, type, is_const, &init_value->static_value);
1807
1808 g->global_vars.append(tld_var->var);
1809}
19101810
1911 var_decl->variable = var;1811static void resolve_decl_typedef(CodeGen *g, TldTypeDef *tld_typedef) {
1812 AstNode *typedef_node = tld_typedef->base.source_node;
1813 assert(typedef_node->type == NodeTypeTypeDecl);
1814 AstNode *type_node = typedef_node->data.type_decl.child_type;
1815 Buf *decl_name = typedef_node->data.type_decl.symbol;
19121816
1913 g->global_vars.append(var);1817 TypeTableEntry *child_type = analyze_type_expr(g, tld_typedef->base.parent_scope, type_node);
1818 tld_typedef->type_entry = (child_type->id == TypeTableEntryIdInvalid) ?
1819 child_type : get_typedecl_type(g, buf_ptr(decl_name), child_type);
1914}1820}
19151821
1916void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only) {1822void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only) {
1917 TopLevelDecl *tld = get_as_top_level_decl(node);1823 if (tld->resolution != TldResolutionUnresolved)
1918 if (tld->resolution != TldResolutionUnresolved) {
1919 return;1824 return;
1920 }1825 if (pointer_only && tld->id == TldIdContainer) {
1921 if (pointer_only && node->type == NodeTypeContainerDecl) {1826 g->resolve_queue.append(tld);
1922 return;1827 return;
1923 }1828 }
19241829
...@@ -1926,90 +1831,38 @@ void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only) {...@@ -1926,90 +1831,38 @@ void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only) {
1926 assert(import);1831 assert(import);
19271832
1928 if (tld->dep_loop_flag) {1833 if (tld->dep_loop_flag) {
1929 add_node_error(g, node, buf_sprintf("'%s' depends on itself", buf_ptr(tld->name)));1834 add_node_error(g, tld->source_node, buf_sprintf("'%s' depends on itself", buf_ptr(tld->name)));
1930 tld->resolution = TldResolutionInvalid;1835 tld->resolution = TldResolutionInvalid;
1931 return;1836 return;
1932 } else {1837 } else {
1933 tld->dep_loop_flag = true;1838 tld->dep_loop_flag = true;
1934 }1839 }
19351840
1936 switch (node->type) {1841 switch (tld->id) {
1937 case NodeTypeFnProto:1842 case TldIdVar:
1938 preview_fn_proto_instance(g, import, node, node->scope);
1939 break;
1940 case NodeTypeContainerDecl:
1941 resolve_struct_decl(g, import, node);
1942 break;
1943 case NodeTypeVariableDeclaration:
1944 resolve_var_decl(g, import, node);
1945 break;
1946 case NodeTypeTypeDecl:
1947 {1843 {
1948 AstNode *type_node = node->data.type_decl.child_type;1844 TldVar *tld_var = (TldVar *)tld;
1949 Buf *decl_name = node->data.type_decl.symbol;1845 resolve_decl_var(g, tld_var);
19501846 break;
1951 TypeTableEntry *entry;1847 }
1952 if (node->data.type_decl.override_type) {1848 case TldIdFn:
1953 entry = node->data.type_decl.override_type;1849 {
1954 } else {1850 TldFn *tld_fn = (TldFn *)tld;
1955 TypeTableEntry *child_type = analyze_type_expr(g, import, &import->decls_scope->base, type_node);1851 resolve_decl_fn(g, tld_fn);
1956 if (child_type->id == TypeTableEntryIdInvalid) {1852 break;
1957 entry = child_type;1853 }
1958 } else {1854 case TldIdContainer:
1959 entry = get_typedecl_type(g, buf_ptr(decl_name), child_type);1855 {
1960 }1856 TldContainer *tld_container = (TldContainer *)tld;
1961 }1857 resolve_decl_container(g, tld_container);
1962 node->data.type_decl.child_type_entry = entry;1858 break;
1859 }
1860 case TldIdTypeDef:
1861 {
1862 TldTypeDef *tld_typedef = (TldTypeDef *)tld;
1863 resolve_decl_typedef(g, tld_typedef);
1963 break;1864 break;
1964 }1865 }
1965 case NodeTypeErrorValueDecl:
1966 break;
1967 case NodeTypeUse:
1968 zig_panic("TODO resolve_top_level_decl NodeTypeUse");
1969 break;
1970 case NodeTypeFnDef:
1971 case NodeTypeParamDecl:
1972 case NodeTypeFnDecl:
1973 case NodeTypeReturnExpr:
1974 case NodeTypeDefer:
1975 case NodeTypeRoot:
1976 case NodeTypeBlock:
1977 case NodeTypeBinOpExpr:
1978 case NodeTypeUnwrapErrorExpr:
1979 case NodeTypeFnCallExpr:
1980 case NodeTypeArrayAccessExpr:
1981 case NodeTypeSliceExpr:
1982 case NodeTypeNumberLiteral:
1983 case NodeTypeStringLiteral:
1984 case NodeTypeCharLiteral:
1985 case NodeTypeBoolLiteral:
1986 case NodeTypeNullLiteral:
1987 case NodeTypeUndefinedLiteral:
1988 case NodeTypeZeroesLiteral:
1989 case NodeTypeThisLiteral:
1990 case NodeTypeSymbol:
1991 case NodeTypePrefixOpExpr:
1992 case NodeTypeIfBoolExpr:
1993 case NodeTypeIfVarExpr:
1994 case NodeTypeWhileExpr:
1995 case NodeTypeForExpr:
1996 case NodeTypeSwitchExpr:
1997 case NodeTypeSwitchProng:
1998 case NodeTypeSwitchRange:
1999 case NodeTypeLabel:
2000 case NodeTypeGoto:
2001 case NodeTypeBreak:
2002 case NodeTypeContinue:
2003 case NodeTypeAsmExpr:
2004 case NodeTypeFieldAccessExpr:
2005 case NodeTypeStructField:
2006 case NodeTypeStructValueField:
2007 case NodeTypeContainerInitExpr:
2008 case NodeTypeArrayType:
2009 case NodeTypeErrorType:
2010 case NodeTypeTypeLiteral:
2011 case NodeTypeVarLiteral:
2012 zig_unreachable();
2013 }1866 }
20141867
2015 tld->resolution = TldResolutionOk;1868 tld->resolution = TldResolutionOk;
...@@ -2028,7 +1881,6 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {...@@ -2028,7 +1881,6 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {
2028 case TypeTableEntryIdNullLit:1881 case TypeTableEntryIdNullLit:
2029 case TypeTableEntryIdNamespace:1882 case TypeTableEntryIdNamespace:
2030 case TypeTableEntryIdBlock:1883 case TypeTableEntryIdBlock:
2031 case TypeTableEntryIdGenericFn:
2032 case TypeTableEntryIdBoundFn:1884 case TypeTableEntryIdBoundFn:
2033 return false;1885 return false;
20341886
...@@ -2142,68 +1994,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *...@@ -2142,68 +1994,7 @@ bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *
2142 return false;1994 return false;
2143}1995}
21441996
2145ScopeDecls *create_decls_scope(AstNode *node, Scope *parent) {1997Tld *find_decl(Scope *scope, Buf *name) {
2146 assert(node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl);
2147 ScopeDecls *scope = allocate<ScopeDecls>(1);
2148 scope->base.node = node;
2149 scope->base.parent = parent;
2150 scope->decl_table.init(4);
2151 return scope;
2152}
2153
2154Scope *create_block_scope(AstNode *node, Scope *parent) {
2155 assert(node->type == NodeTypeBlock);
2156 ScopeBlock *scope = allocate<ScopeBlock>(1);
2157 scope->base.node = node;
2158 scope->base.parent = parent;
2159 scope->label_table.init(1);
2160 return &scope->base;
2161}
2162
2163Scope *create_defer_scope(AstNode *node, Scope *parent) {
2164 assert(node->type == NodeTypeDefer);
2165 ScopeDefer *scope = allocate<ScopeDefer>(1);
2166 scope->base.node = node;
2167 scope->base.parent = parent;
2168 return &scope->base;
2169}
2170
2171Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var) {
2172 assert(node->type == NodeTypeVariableDeclaration || node->type == NodeTypeParamDecl);
2173 ScopeVarDecl *scope = allocate<ScopeVarDecl>(1);
2174 scope->base.node = node;
2175 scope->base.parent = parent;
2176 scope->var = var;
2177 return &scope->base;
2178}
2179
2180Scope *create_cimport_scope(AstNode *node, Scope *parent) {
2181 assert(node->type == NodeTypeFnCallExpr);
2182 ScopeCImport *scope = allocate<ScopeCImport>(1);
2183 scope->base.node = node;
2184 scope->base.parent = parent;
2185 buf_resize(&scope->c_import_buf, 0);
2186 return &scope->base;
2187}
2188
2189Scope *create_loop_scope(AstNode *node, Scope *parent) {
2190 assert(node->type == NodeTypeWhileExpr || node->type == NodeTypeForExpr);
2191 ScopeLoop *scope = allocate<ScopeLoop>(1);
2192 scope->base.node = node;
2193 scope->base.parent = parent;
2194 return &scope->base;
2195}
2196
2197Scope *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_entry) {
2198 assert(node->type == NodeTypeFnDef);
2199 ScopeFnBody *scope = allocate<ScopeFnBody>(1);
2200 scope->base.node = node;
2201 scope->base.parent = parent;
2202 scope->fn_entry = fn_entry;
2203 return &scope->base;
2204}
2205
2206AstNode *find_decl(Scope *scope, Buf *name) {
2207 while (scope) {1998 while (scope) {
2208 if (scope->node->type == NodeTypeRoot ||1999 if (scope->node->type == NodeTypeRoot ||
2209 scope->node->type == NodeTypeContainerDecl)2000 scope->node->type == NodeTypeContainerDecl)
...@@ -2232,11 +2023,11 @@ VariableTableEntry *find_variable(CodeGen *g, Scope *scope, Buf *name) {...@@ -2232,11 +2023,11 @@ VariableTableEntry *find_variable(CodeGen *g, Scope *scope, Buf *name) {
2232 ScopeDecls *decls_scope = (ScopeDecls *)scope;2023 ScopeDecls *decls_scope = (ScopeDecls *)scope;
2233 auto entry = decls_scope->decl_table.maybe_get(name);2024 auto entry = decls_scope->decl_table.maybe_get(name);
2234 if (entry) {2025 if (entry) {
2235 AstNode *decl_node = entry->value;2026 Tld *tld = entry->value;
2236 if (decl_node->type == NodeTypeVariableDeclaration) {2027 if (tld->id == TldIdVar) {
2237 VariableTableEntry *var = decl_node->data.variable_declaration.variable;2028 TldVar *tld_var = (TldVar *)tld;
2238 if (var)2029 if (tld_var->var)
2239 return var;2030 return tld_var->var;
2240 }2031 }
2241 }2032 }
2242 }2033 }
...@@ -2246,6 +2037,17 @@ VariableTableEntry *find_variable(CodeGen *g, Scope *scope, Buf *name) {...@@ -2246,6 +2037,17 @@ VariableTableEntry *find_variable(CodeGen *g, Scope *scope, Buf *name) {
2246 return nullptr;2037 return nullptr;
2247}2038}
22482039
2040FnTableEntry *scope_fn_entry(Scope *scope) {
2041 while (scope) {
2042 if (scope->node->type == NodeTypeFnDef) {
2043 ScopeFnDef *fn_scope = (ScopeFnDef *)scope;
2044 return fn_scope->fn_entry;
2045 }
2046 scope = scope->parent;
2047 }
2048 return nullptr;
2049}
2050
2249TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name) {2051TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name) {
2250 for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) {2052 for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) {
2251 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];2053 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];
...@@ -2296,7 +2098,6 @@ static bool is_container(TypeTableEntry *type_entry) {...@@ -2296,7 +2098,6 @@ static bool is_container(TypeTableEntry *type_entry) {
2296 case TypeTableEntryIdTypeDecl:2098 case TypeTableEntryIdTypeDecl:
2297 case TypeTableEntryIdNamespace:2099 case TypeTableEntryIdNamespace:
2298 case TypeTableEntryIdBlock:2100 case TypeTableEntryIdBlock:
2299 case TypeTableEntryIdGenericFn:
2300 case TypeTableEntryIdBoundFn:2101 case TypeTableEntryIdBoundFn:
2301 return false;2102 return false;
2302 }2103 }
...@@ -2317,13 +2118,13 @@ TypeTableEntry *container_ref_type(TypeTableEntry *type_entry) {...@@ -2317,13 +2118,13 @@ TypeTableEntry *container_ref_type(TypeTableEntry *type_entry) {
2317void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {2118void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
2318 switch (type_entry->id) {2119 switch (type_entry->id) {
2319 case TypeTableEntryIdStruct:2120 case TypeTableEntryIdStruct:
2320 resolve_struct_type(g, type_entry->data.structure.decl_node->owner, type_entry);2121 resolve_struct_type(g, type_entry);
2321 break;2122 break;
2322 case TypeTableEntryIdEnum:2123 case TypeTableEntryIdEnum:
2323 resolve_enum_type(g, type_entry->data.enumeration.decl_node->owner, type_entry);2124 resolve_enum_type(g, type_entry);
2324 break;2125 break;
2325 case TypeTableEntryIdUnion:2126 case TypeTableEntryIdUnion:
2326 resolve_union_type(g, type_entry->data.unionation.decl_node->owner, type_entry);2127 resolve_union_type(g, type_entry);
2327 break;2128 break;
2328 case TypeTableEntryIdPointer:2129 case TypeTableEntryIdPointer:
2329 case TypeTableEntryIdMetaType:2130 case TypeTableEntryIdMetaType:
...@@ -2344,7 +2145,6 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {...@@ -2344,7 +2145,6 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
2344 case TypeTableEntryIdTypeDecl:2145 case TypeTableEntryIdTypeDecl:
2345 case TypeTableEntryIdNamespace:2146 case TypeTableEntryIdNamespace:
2346 case TypeTableEntryIdBlock:2147 case TypeTableEntryIdBlock:
2347 case TypeTableEntryIdGenericFn:
2348 case TypeTableEntryIdBoundFn:2148 case TypeTableEntryIdBoundFn:
2349 case TypeTableEntryIdInvalid:2149 case TypeTableEntryIdInvalid:
2350 case TypeTableEntryIdVar:2150 case TypeTableEntryIdVar:
...@@ -2362,54 +2162,41 @@ bool type_is_codegen_pointer(TypeTableEntry *type) {...@@ -2362,54 +2162,41 @@ bool type_is_codegen_pointer(TypeTableEntry *type) {
2362 return false;2162 return false;
2363}2163}
23642164
2365
2366
2367static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {2165static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
2368 ImportTableEntry *import = fn_table_entry->import_entry;2166 assert(fn_table_entry->anal_state != FnAnalStateProbing);
2369 AstNode *node = fn_table_entry->fn_def_node;2167 if (fn_table_entry->anal_state != FnAnalStateReady)
2370 assert(node->type == NodeTypeFnDef);
2371
2372 AstNode *fn_proto_node = node->data.fn_def.fn_proto;
2373 assert(fn_proto_node->type == NodeTypeFnProto);
2374
2375 if (fn_proto_node->data.fn_proto.skip) {
2376 // we detected an error with this function definition which prevents us
2377 // from further analyzing it.
2378 fn_table_entry->anal_state = FnAnalStateSkipped;
2379 return;2168 return;
2380 }2169
2381 fn_table_entry->anal_state = FnAnalStateProbing;2170 fn_table_entry->anal_state = FnAnalStateProbing;
23822171
2383 Scope *child_scope = node->data.fn_def.containing_scope;2172 AstNodeFnProto *fn_proto = &fn_table_entry->proto_node->data.fn_proto;
23842173
2174 Scope *child_scope = &fn_table_entry->fndef_scope->base;
2175 assert(child_scope);
2176
2177 // define local variables for parameters
2385 TypeTableEntry *fn_type = fn_table_entry->type_entry;2178 TypeTableEntry *fn_type = fn_table_entry->type_entry;
2179 assert(!fn_type->data.fn.is_generic);
2386 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;2180 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
2387 AstNodeFnProto *fn_proto = &fn_proto_node->data.fn_proto;2181 for (size_t i = 0; i < fn_type_id->param_count; i += 1) {
2388 for (size_t i = 0; i < fn_proto->params.length; i += 1) {
2389 AstNode *param_decl_node = fn_proto->params.at(i);2182 AstNode *param_decl_node = fn_proto->params.at(i);
2390 assert(param_decl_node->type == NodeTypeParamDecl);
2391
2392 // define local variables for parameters
2393 AstNodeParamDecl *param_decl = &param_decl_node->data.param_decl;2183 AstNodeParamDecl *param_decl = &param_decl_node->data.param_decl;
2394 TypeTableEntry *type = fn_type_id->param_info[i].type;2184 FnTypeParamInfo *param_info = &fn_type_id->param_info[i];
23952185
2396 if (param_decl->is_noalias && !type_is_codegen_pointer(type)) {2186 TypeTableEntry *param_type = param_info->type;
2187 bool is_noalias = param_info->is_noalias;
2188
2189 if (is_noalias && !type_is_codegen_pointer(param_type)) {
2397 add_node_error(g, param_decl_node, buf_sprintf("noalias on non-pointer parameter"));2190 add_node_error(g, param_decl_node, buf_sprintf("noalias on non-pointer parameter"));
2398 }2191 }
23992192
2400 if (fn_type->data.fn.fn_type_id.is_extern && handle_is_ptr(type)) {2193 if (fn_type_id->is_extern && handle_is_ptr(param_type)) {
2401 add_node_error(g, param_decl_node,2194 add_node_error(g, param_decl_node,
2402 buf_sprintf("byvalue types not yet supported on extern function parameters"));2195 buf_sprintf("byvalue types not yet supported on extern function parameters"));
2403 }2196 }
24042197
2405 if (buf_len(param_decl->name) == 0) {2198 VariableTableEntry *var = add_variable(g, param_decl_node, child_scope, param_decl->name, param_type, true, nullptr);
2406 add_node_error(g, param_decl_node, buf_sprintf("missing parameter name"));
2407 }
2408
2409 VariableTableEntry *var = add_local_var(g, param_decl_node, import, child_scope, param_decl->name,
2410 type, true, nullptr);
2411 var->src_arg_index = i;2199 var->src_arg_index = i;
2412 param_decl_node->data.param_decl.variable = var;
2413 child_scope = var->child_scope;2200 child_scope = var->child_scope;
2414 fn_table_entry->variable_list.append(var);2201 fn_table_entry->variable_list.append(var);
24152202
...@@ -2418,19 +2205,18 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -2418,19 +2205,18 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
2418 }2205 }
2419 }2206 }
24202207
2421 node->data.fn_def.child_scope = child_scope;2208 fn_table_entry->child_scope = child_scope;
24222209
2423 TypeTableEntry *expected_type = fn_type->data.fn.fn_type_id.return_type;2210 TypeTableEntry *expected_type = fn_type_id->return_type;
24242211
2425 if (fn_type->data.fn.fn_type_id.is_extern && handle_is_ptr(expected_type)) {2212 if (fn_type_id->is_extern && handle_is_ptr(expected_type)) {
2426 add_node_error(g, fn_proto_node->data.fn_proto.return_type,2213 add_node_error(g, fn_proto->return_type,
2427 buf_sprintf("byvalue types not yet supported on extern function return values"));2214 buf_sprintf("byvalue types not yet supported on extern function return values"));
2428 }2215 }
24292216
2430 ir_gen_fn(g, fn_table_entry);2217 ir_gen_fn(g, fn_table_entry);
2431 if (fn_table_entry->ir_executable.invalid) {2218 if (fn_table_entry->ir_executable.invalid) {
2432 fn_proto_node->data.fn_proto.skip = true;2219 fn_table_entry->anal_state = FnAnalStateInvalid;
2433 fn_table_entry->anal_state = FnAnalStateSkipped;
2434 return;2220 return;
2435 }2221 }
2436 if (g->verbose) {2222 if (g->verbose) {
...@@ -2443,9 +2229,16 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -2443,9 +2229,16 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
24432229
2444 TypeTableEntry *block_return_type = ir_analyze(g, &fn_table_entry->ir_executable,2230 TypeTableEntry *block_return_type = ir_analyze(g, &fn_table_entry->ir_executable,
2445 &fn_table_entry->analyzed_executable, expected_type, fn_proto->return_type);2231 &fn_table_entry->analyzed_executable, expected_type, fn_proto->return_type);
2446 node->data.fn_def.implicit_return_type = block_return_type;2232 fn_table_entry->implicit_return_type = block_return_type;
24472233
2448 if (block_return_type->id != TypeTableEntryIdInvalid && g->verbose) {2234 if (block_return_type->id == TypeTableEntryIdInvalid ||
2235 fn_table_entry->analyzed_executable.invalid)
2236 {
2237 fn_table_entry->anal_state = FnAnalStateInvalid;
2238 return;
2239 }
2240
2241 if (g->verbose) {
2449 fprintf(stderr, "{ // (analyzed)\n");2242 fprintf(stderr, "{ // (analyzed)\n");
2450 ir_print(stderr, &fn_table_entry->analyzed_executable, 4);2243 ir_print(stderr, &fn_table_entry->analyzed_executable, 4);
2451 fprintf(stderr, "}\n");2244 fprintf(stderr, "}\n");
...@@ -2454,16 +2247,14 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -2454,16 +2247,14 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
2454 fn_table_entry->anal_state = FnAnalStateComplete;2247 fn_table_entry->anal_state = FnAnalStateComplete;
2455}2248}
24562249
2457static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node) {2250static void add_symbols_from_import(CodeGen *g, AstNode *dst_use_node) {
2458 TopLevelDecl *tld = get_as_top_level_decl(dst_use_node);2251 IrInstruction *use_target_value = dst_use_node->data.use.value;
2459
2460 IrInstruction *use_target_value = tld->value;
2461 if (use_target_value->type_entry->id == TypeTableEntryIdInvalid) {2252 if (use_target_value->type_entry->id == TypeTableEntryIdInvalid) {
2462 tld->import->any_imports_failed = true;2253 dst_use_node->owner->any_imports_failed = true;
2463 return;2254 return;
2464 }2255 }
24652256
2466 tld->resolution = TldResolutionOk;2257 dst_use_node->data.use.resolution = TldResolutionOk;
24672258
2468 ConstExprValue *const_val = &use_target_value->static_value;2259 ConstExprValue *const_val = &use_target_value->static_value;
2469 assert(const_val->special != ConstValSpecialRuntime);2260 assert(const_val->special != ConstValSpecialRuntime);
...@@ -2472,59 +2263,60 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *...@@ -2472,59 +2263,60 @@ static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *
2472 assert(target_import);2263 assert(target_import);
24732264
2474 if (target_import->any_imports_failed) {2265 if (target_import->any_imports_failed) {
2475 tld->import->any_imports_failed = true;2266 dst_use_node->owner->any_imports_failed = true;
2476 }2267 }
24772268
2478 for (size_t i = 0; i < target_import->root->data.root.top_level_decls.length; i += 1) {2269 auto it = target_import->decls_scope->decl_table.entry_iterator();
2479 AstNode *decl_node = target_import->root->data.root.top_level_decls.at(i);2270 for (;;) {
2480 if (decl_node->type == NodeTypeFnDef) {2271 auto *entry = it.next();
2481 decl_node = decl_node->data.fn_def.fn_proto;2272 if (!entry)
2482 }2273 break;
2483 TopLevelDecl *target_tld = get_as_top_level_decl(decl_node);2274
2484 if (!target_tld->name) {2275 Tld *target_tld = entry->value;
2276 if (target_tld->import != target_import ||
2277 target_tld->visib_mod == VisibModPrivate)
2278 {
2485 continue;2279 continue;
2486 }2280 }
2487 if (target_tld->visib_mod != VisibModPrivate) {2281
2488 auto existing_entry = tld->import->decls_scope->decl_table.put_unique(target_tld->name, decl_node);2282 auto existing_entry = dst_use_node->owner->decls_scope->decl_table.put_unique(target_tld->name, target_tld);
2489 if (existing_entry) {2283 if (existing_entry) {
2490 AstNode *existing_decl = existing_entry->value;2284 Tld *existing_decl = existing_entry->value;
2491 if (existing_decl != decl_node) {2285 if (existing_decl != target_tld) {
2492 ErrorMsg *msg = add_node_error(g, dst_use_node,2286 ErrorMsg *msg = add_node_error(g, dst_use_node,
2493 buf_sprintf("import of '%s' overrides existing definition",2287 buf_sprintf("import of '%s' overrides existing definition",
2494 buf_ptr(target_tld->name)));2288 buf_ptr(target_tld->name)));
2495 add_error_note(g, msg, existing_decl, buf_sprintf("previous definition here"));2289 add_error_note(g, msg, existing_decl->source_node, buf_sprintf("previous definition here"));
2496 add_error_note(g, msg, decl_node, buf_sprintf("imported definition here"));2290 add_error_note(g, msg, target_tld->source_node, buf_sprintf("imported definition here"));
2497 }
2498 }2291 }
2499 }2292 }
2500 }2293 }
25012294
2502 for (size_t i = 0; i < target_import->use_decls.length; i += 1) {2295 for (size_t i = 0; i < target_import->use_decls.length; i += 1) {
2503 AstNode *use_decl_node = target_import->use_decls.at(i);2296 AstNode *use_decl_node = target_import->use_decls.at(i);
2504 TopLevelDecl *target_tld = get_as_top_level_decl(use_decl_node);2297 if (use_decl_node->data.use.visib_mod != VisibModPrivate)
2505 if (target_tld->visib_mod != VisibModPrivate) {2298 add_symbols_from_import(g, dst_use_node);
2506 add_symbols_from_import(g, use_decl_node, dst_use_node);
2507 }
2508 }2299 }
2509
2510}2300}
25112301
2512void resolve_use_decl(CodeGen *g, AstNode *node) {2302void resolve_use_decl(CodeGen *g, AstNode *node) {
2513 assert(node->type == NodeTypeUse);2303 assert(node->type == NodeTypeUse);
2514 if (get_as_top_level_decl(node)->resolution != TldResolutionUnresolved) {2304
2305 if (node->data.use.resolution != TldResolutionUnresolved)
2515 return;2306 return;
2516 }2307 add_symbols_from_import(g, node);
2517 add_symbols_from_import(g, node, node);
2518}2308}
25192309
2520void preview_use_decl(CodeGen *g, AstNode *node) {2310void preview_use_decl(CodeGen *g, AstNode *node) {
2521 assert(node->type == NodeTypeUse);2311 assert(node->type == NodeTypeUse);
2522 TopLevelDecl *tld = get_as_top_level_decl(node);
25232312
2524 IrInstruction *result = analyze_const_value(g, &tld->import->decls_scope->base, node->data.use.expr,2313 IrInstruction *result = analyze_const_value(g, &node->owner->decls_scope->base,
2525 g->builtin_types.entry_namespace);2314 node->data.use.expr, g->builtin_types.entry_namespace);
2315
2526 if (result->type_entry->id == TypeTableEntryIdInvalid)2316 if (result->type_entry->id == TypeTableEntryIdInvalid)
2527 tld->import->any_imports_failed = true;2317 node->owner->any_imports_failed = true;
2318
2319 node->data.use.value = result;
2528}2320}
25292321
2530ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,2322ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
...@@ -2580,7 +2372,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,...@@ -2580,7 +2372,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
2580 g->import_table.put(abs_full_path, import_entry);2372 g->import_table.put(abs_full_path, import_entry);
2581 g->import_queue.append(import_entry);2373 g->import_queue.append(import_entry);
25822374
2583 import_entry->decls_scope = create_decls_scope(import_entry->root, nullptr);2375 import_entry->decls_scope = create_decls_scope(import_entry->root, nullptr, nullptr, import_entry);
25842376
25852377
2586 assert(import_entry->root->type == NodeTypeRoot);2378 assert(import_entry->root->type == NodeTypeRoot);
...@@ -2592,7 +2384,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,...@@ -2592,7 +2384,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
2592 assert(proto_node->type == NodeTypeFnProto);2384 assert(proto_node->type == NodeTypeFnProto);
2593 Buf *proto_name = proto_node->data.fn_proto.name;2385 Buf *proto_name = proto_node->data.fn_proto.name;
25942386
2595 bool is_private = (proto_node->data.fn_proto.top_level_decl.visib_mod == VisibModPrivate);2387 bool is_private = (proto_node->data.fn_proto.visib_mod == VisibModPrivate);
25962388
2597 if (buf_eql_str(proto_name, "main") && !is_private) {2389 if (buf_eql_str(proto_name, "main") && !is_private) {
2598 g->have_exported_main = true;2390 g->have_exported_main = true;
...@@ -2607,7 +2399,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,...@@ -2607,7 +2399,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package,
2607void semantic_analyze(CodeGen *g) {2399void semantic_analyze(CodeGen *g) {
2608 for (; g->import_queue_index < g->import_queue.length; g->import_queue_index += 1) {2400 for (; g->import_queue_index < g->import_queue.length; g->import_queue_index += 1) {
2609 ImportTableEntry *import = g->import_queue.at(g->import_queue_index);2401 ImportTableEntry *import = g->import_queue.at(g->import_queue_index);
2610 scan_decls(g, import, import->decls_scope, import->root);2402 scan_decls(g, import, import->decls_scope, import->root, nullptr);
2611 }2403 }
26122404
2613 for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) {2405 for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) {
...@@ -2620,82 +2412,22 @@ void semantic_analyze(CodeGen *g) {...@@ -2620,82 +2412,22 @@ void semantic_analyze(CodeGen *g) {
2620 resolve_use_decl(g, use_decl_node);2412 resolve_use_decl(g, use_decl_node);
2621 }2413 }
26222414
2623 for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) {2415 while (g->resolve_queue_index < g->resolve_queue.length ||
2624 AstNode *decl_node = g->resolve_queue.at(g->resolve_queue_index);2416 g->fn_defs_index < g->fn_defs.length)
2625 bool pointer_only = false;2417 {
2626 resolve_top_level_decl(g, decl_node, pointer_only);2418 for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) {
2627 }2419 Tld *tld = g->resolve_queue.at(g->resolve_queue_index);
2420 bool pointer_only = false;
2421 resolve_top_level_decl(g, tld, pointer_only);
2422 }
26282423
2629 for (size_t i = 0; i < g->fn_defs.length; i += 1) {2424 for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) {
2630 FnTableEntry *fn_entry = g->fn_defs.at(i);2425 FnTableEntry *fn_entry = g->fn_defs.at(g->fn_defs_index);
2631 if (fn_entry->anal_state == FnAnalStateReady) {
2632 analyze_fn_body(g, fn_entry);2426 analyze_fn_body(g, fn_entry);
2633 }2427 }
2634 }2428 }
2635}2429}
26362430
2637TopLevelDecl *get_as_top_level_decl(AstNode *node) {
2638 switch (node->type) {
2639 case NodeTypeVariableDeclaration:
2640 return &node->data.variable_declaration.top_level_decl;
2641 case NodeTypeFnProto:
2642 return &node->data.fn_proto.top_level_decl;
2643 case NodeTypeFnDef:
2644 return &node->data.fn_def.fn_proto->data.fn_proto.top_level_decl;
2645 case NodeTypeContainerDecl:
2646 return &node->data.struct_decl.top_level_decl;
2647 case NodeTypeErrorValueDecl:
2648 return &node->data.error_value_decl.top_level_decl;
2649 case NodeTypeUse:
2650 return &node->data.use.top_level_decl;
2651 case NodeTypeTypeDecl:
2652 return &node->data.type_decl.top_level_decl;
2653 case NodeTypeNumberLiteral:
2654 case NodeTypeReturnExpr:
2655 case NodeTypeDefer:
2656 case NodeTypeBinOpExpr:
2657 case NodeTypeUnwrapErrorExpr:
2658 case NodeTypePrefixOpExpr:
2659 case NodeTypeFnCallExpr:
2660 case NodeTypeArrayAccessExpr:
2661 case NodeTypeSliceExpr:
2662 case NodeTypeFieldAccessExpr:
2663 case NodeTypeIfBoolExpr:
2664 case NodeTypeIfVarExpr:
2665 case NodeTypeWhileExpr:
2666 case NodeTypeForExpr:
2667 case NodeTypeSwitchExpr:
2668 case NodeTypeSwitchProng:
2669 case NodeTypeSwitchRange:
2670 case NodeTypeAsmExpr:
2671 case NodeTypeContainerInitExpr:
2672 case NodeTypeRoot:
2673 case NodeTypeFnDecl:
2674 case NodeTypeParamDecl:
2675 case NodeTypeBlock:
2676 case NodeTypeStringLiteral:
2677 case NodeTypeCharLiteral:
2678 case NodeTypeSymbol:
2679 case NodeTypeBoolLiteral:
2680 case NodeTypeNullLiteral:
2681 case NodeTypeUndefinedLiteral:
2682 case NodeTypeZeroesLiteral:
2683 case NodeTypeThisLiteral:
2684 case NodeTypeLabel:
2685 case NodeTypeGoto:
2686 case NodeTypeBreak:
2687 case NodeTypeContinue:
2688 case NodeTypeStructField:
2689 case NodeTypeStructValueField:
2690 case NodeTypeArrayType:
2691 case NodeTypeErrorType:
2692 case NodeTypeTypeLiteral:
2693 case NodeTypeVarLiteral:
2694 zig_unreachable();
2695 }
2696 zig_unreachable();
2697}
2698
2699bool is_node_void_expr(AstNode *node) {2431bool is_node_void_expr(AstNode *node) {
2700 if (node->type == NodeTypeContainerInitExpr &&2432 if (node->type == NodeTypeContainerInitExpr &&
2701 node->data.container_init_expr.kind == ContainerInitKindArray)2433 node->data.container_init_expr.kind == ContainerInitKindArray)
...@@ -2749,7 +2481,6 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {...@@ -2749,7 +2481,6 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
2749 case TypeTableEntryIdNullLit:2481 case TypeTableEntryIdNullLit:
2750 case TypeTableEntryIdNamespace:2482 case TypeTableEntryIdNamespace:
2751 case TypeTableEntryIdBlock:2483 case TypeTableEntryIdBlock:
2752 case TypeTableEntryIdGenericFn:
2753 case TypeTableEntryIdBoundFn:2484 case TypeTableEntryIdBoundFn:
2754 case TypeTableEntryIdVar:2485 case TypeTableEntryIdVar:
2755 zig_unreachable();2486 zig_unreachable();
...@@ -2902,7 +2633,6 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)...@@ -2902,7 +2633,6 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)
2902 return hash_ptr(const_val->data.x_import);2633 return hash_ptr(const_val->data.x_import);
2903 case TypeTableEntryIdBlock:2634 case TypeTableEntryIdBlock:
2904 return hash_ptr(const_val->data.x_block);2635 return hash_ptr(const_val->data.x_block);
2905 case TypeTableEntryIdGenericFn:
2906 case TypeTableEntryIdBoundFn:2636 case TypeTableEntryIdBoundFn:
2907 case TypeTableEntryIdInvalid:2637 case TypeTableEntryIdInvalid:
2908 case TypeTableEntryIdUnreachable:2638 case TypeTableEntryIdUnreachable:
...@@ -2912,45 +2642,6 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)...@@ -2912,45 +2642,6 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)
2912 zig_unreachable();2642 zig_unreachable();
2913}2643}
29142644
2915uint32_t generic_fn_type_id_hash(GenericFnTypeId *id) {
2916 zig_panic("TODO generic_fn_type_id_hash");
2917 //uint32_t result = 0;
2918 //result += hash_ptr(id->decl_node);
2919 //for (size_t i = 0; i < id->generic_param_count; i += 1) {
2920 // GenericParamValue *generic_param = &id->generic_params[i];
2921 // if (generic_param->node) {
2922 // ConstExprValue *const_val = &get_resolved_expr(generic_param->node)->instruction->static_value;
2923 // assert(const_val->special != ConstValSpecialRuntime);
2924 // result += hash_const_val(generic_param->type, const_val);
2925 // }
2926 // result += hash_ptr(generic_param->type);
2927 //}
2928 //return result;
2929}
2930
2931bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) {
2932 zig_panic("TODO generic_fn_type_id_eql");
2933 //if (a->decl_node != b->decl_node) return false;
2934 //assert(a->generic_param_count == b->generic_param_count);
2935 //for (size_t i = 0; i < a->generic_param_count; i += 1) {
2936 // GenericParamValue *a_val = &a->generic_params[i];
2937 // GenericParamValue *b_val = &b->generic_params[i];
2938 // if (a_val->type != b_val->type) return false;
2939 // if (a_val->node && b_val->node) {
2940 // ConstExprValue *a_const_val = &get_resolved_expr(a_val->node)->instruction->static_value;
2941 // ConstExprValue *b_const_val = &get_resolved_expr(b_val->node)->instruction->static_value;
2942 // assert(a_const_val->special != ConstValSpecialRuntime);
2943 // assert(b_const_val->special != ConstValSpecialRuntime);
2944 // if (!const_values_equal(a_const_val, b_const_val, a_val->type)) {
2945 // return false;
2946 // }
2947 // } else {
2948 // assert(!a_val->node && !b_val->node);
2949 // }
2950 //}
2951 //return true;
2952}
2953
2954bool type_has_bits(TypeTableEntry *type_entry) {2645bool type_has_bits(TypeTableEntry *type_entry) {
2955 assert(type_entry);2646 assert(type_entry);
2956 assert(type_entry->id != TypeTableEntryIdInvalid);2647 assert(type_entry->id != TypeTableEntryIdInvalid);
...@@ -2981,7 +2672,6 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)...@@ -2981,7 +2672,6 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)
2981 case TypeTableEntryIdVoid:2672 case TypeTableEntryIdVoid:
2982 case TypeTableEntryIdNamespace:2673 case TypeTableEntryIdNamespace:
2983 case TypeTableEntryIdBlock:2674 case TypeTableEntryIdBlock:
2984 case TypeTableEntryIdGenericFn:
2985 case TypeTableEntryIdBoundFn:2675 case TypeTableEntryIdBoundFn:
2986 case TypeTableEntryIdVar:2676 case TypeTableEntryIdVar:
2987 zig_unreachable();2677 zig_unreachable();
src/analyze.hpp+12-8
...@@ -22,11 +22,11 @@ TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, size_t size_in_bits);...@@ -22,11 +22,11 @@ TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, size_t size_in_bits);
22TypeTableEntry **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type);22TypeTableEntry **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type);
23TypeTableEntry *get_c_int_type(CodeGen *g, CIntType c_int_type);23TypeTableEntry *get_c_int_type(CodeGen *g, CIntType c_int_type);
24TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *child_type);24TypeTableEntry *get_typedecl_type(CodeGen *g, const char *name, TypeTableEntry *child_type);
25TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id, bool gen_debug_info);25TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id);
26TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type);26TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type);
27TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size);27TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size);
28TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);28TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const);
29TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, Scope *context,29TypeTableEntry *get_partial_container_type(CodeGen *g, ImportTableEntry *import, Scope *scope,
30 ContainerKind kind, AstNode *decl_node, const char *name);30 ContainerKind kind, AstNode *decl_node, const char *name);
31TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);31TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);
32TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type);32TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type);
...@@ -49,9 +49,8 @@ AstNode *first_executing_node(AstNode *node);...@@ -49,9 +49,8 @@ AstNode *first_executing_node(AstNode *node);
49// TODO move these over, these used to be static49// TODO move these over, these used to be static
50bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type);50bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type);
51VariableTableEntry *find_variable(CodeGen *g, Scope *orig_context, Buf *name);51VariableTableEntry *find_variable(CodeGen *g, Scope *orig_context, Buf *name);
52AstNode *find_decl(Scope *context, Buf *name);52Tld *find_decl(Scope *scope, Buf *name);
53void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only);53void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only);
54TopLevelDecl *get_as_top_level_decl(AstNode *node);
55bool type_is_codegen_pointer(TypeTableEntry *type);54bool type_is_codegen_pointer(TypeTableEntry *type);
56TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);55TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry);
57TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);56TypeTableEntry *container_ref_type(TypeTableEntry *type_entry);
...@@ -61,16 +60,21 @@ TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name);...@@ -61,16 +60,21 @@ TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name);
61ScopeDecls *get_container_scope(TypeTableEntry *type_entry);60ScopeDecls *get_container_scope(TypeTableEntry *type_entry);
62TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name);61TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name);
63bool is_container_ref(TypeTableEntry *type_entry);62bool is_container_ref(TypeTableEntry *type_entry);
64void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, AstNode *node);63void scan_decls(CodeGen *g, ImportTableEntry *import, ScopeDecls *decls_scope, AstNode *node, Tld *parent_tld);
65void preview_use_decl(CodeGen *g, AstNode *node);64void preview_use_decl(CodeGen *g, AstNode *node);
66void resolve_use_decl(CodeGen *g, AstNode *node);65void resolve_use_decl(CodeGen *g, AstNode *node);
66FnTableEntry *scope_fn_entry(Scope *scope);
67ImportTableEntry *get_scope_import(Scope *scope);
68void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node,
69 Scope *parent_scope, Tld *parent_tld);
70VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name,
71 TypeTableEntry *type_entry, bool is_const, ConstExprValue *init_value);
6772
68ScopeDecls *create_decls_scope(AstNode *node, Scope *parent);
69Scope *create_block_scope(AstNode *node, Scope *parent);73Scope *create_block_scope(AstNode *node, Scope *parent);
70Scope *create_defer_scope(AstNode *node, Scope *parent);74Scope *create_defer_scope(AstNode *node, Scope *parent);
71Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var);75Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var);
72Scope *create_cimport_scope(AstNode *node, Scope *parent);76Scope *create_cimport_scope(AstNode *node, Scope *parent);
73Scope *create_loop_scope(AstNode *node, Scope *parent);77Scope *create_loop_scope(AstNode *node, Scope *parent);
74Scope *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_entry);78ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_entry);
7579
76#endif80#endif
src/ast_render.cpp+4-4
...@@ -377,7 +377,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -377,7 +377,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
377 break;377 break;
378 case NodeTypeFnProto:378 case NodeTypeFnProto:
379 {379 {
380 const char *pub_str = visib_mod_string(node->data.fn_proto.top_level_decl.visib_mod);380 const char *pub_str = visib_mod_string(node->data.fn_proto.visib_mod);
381 const char *extern_str = extern_string(node->data.fn_proto.is_extern);381 const char *extern_str = extern_string(node->data.fn_proto.is_extern);
382 const char *inline_str = inline_string(node->data.fn_proto.is_inline);382 const char *inline_str = inline_string(node->data.fn_proto.is_inline);
383 fprintf(ar->f, "%s%s%sfn ", pub_str, inline_str, extern_str);383 fprintf(ar->f, "%s%s%sfn ", pub_str, inline_str, extern_str);
...@@ -460,7 +460,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -460,7 +460,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
460 }460 }
461 case NodeTypeVariableDeclaration:461 case NodeTypeVariableDeclaration:
462 {462 {
463 const char *pub_str = visib_mod_string(node->data.variable_declaration.top_level_decl.visib_mod);463 const char *pub_str = visib_mod_string(node->data.variable_declaration.visib_mod);
464 const char *extern_str = extern_string(node->data.variable_declaration.is_extern);464 const char *extern_str = extern_string(node->data.variable_declaration.is_extern);
465 const char *const_or_var = const_or_var_string(node->data.variable_declaration.is_const);465 const char *const_or_var = const_or_var_string(node->data.variable_declaration.is_const);
466 fprintf(ar->f, "%s%s%s ", pub_str, extern_str, const_or_var);466 fprintf(ar->f, "%s%s%s ", pub_str, extern_str, const_or_var);
...@@ -478,7 +478,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -478,7 +478,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
478 }478 }
479 case NodeTypeTypeDecl:479 case NodeTypeTypeDecl:
480 {480 {
481 const char *pub_str = visib_mod_string(node->data.type_decl.top_level_decl.visib_mod);481 const char *pub_str = visib_mod_string(node->data.type_decl.visib_mod);
482 const char *var_name = buf_ptr(node->data.type_decl.symbol);482 const char *var_name = buf_ptr(node->data.type_decl.symbol);
483 fprintf(ar->f, "%stype %s = ", pub_str, var_name);483 fprintf(ar->f, "%stype %s = ", pub_str, var_name);
484 render_node_grouped(ar, node->data.type_decl.child_type);484 render_node_grouped(ar, node->data.type_decl.child_type);
...@@ -575,7 +575,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -575,7 +575,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
575 case NodeTypeContainerDecl:575 case NodeTypeContainerDecl:
576 {576 {
577 const char *struct_name = buf_ptr(node->data.struct_decl.name);577 const char *struct_name = buf_ptr(node->data.struct_decl.name);
578 const char *pub_str = visib_mod_string(node->data.struct_decl.top_level_decl.visib_mod);578 const char *pub_str = visib_mod_string(node->data.struct_decl.visib_mod);
579 const char *container_str = container_string(node->data.struct_decl.kind);579 const char *container_str = container_string(node->data.struct_decl.kind);
580 fprintf(ar->f, "%s%s %s {\n", pub_str, container_str, struct_name);580 fprintf(ar->f, "%s%s %s {\n", pub_str, container_str, struct_name);
581 ar->indent += ar->indent_size;581 ar->indent += ar->indent_size;
src/codegen.cpp+168-116
...@@ -60,7 +60,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {...@@ -60,7 +60,6 @@ CodeGen *codegen_create(Buf *root_source_dir, const ZigTarget *target) {
60 g->primitive_type_table.init(32);60 g->primitive_type_table.init(32);
61 g->fn_type_table.init(32);61 g->fn_type_table.init(32);
62 g->error_table.init(16);62 g->error_table.init(16);
63 g->generic_table.init(16);
64 g->is_release_build = false;63 g->is_release_build = false;
65 g->is_test_build = false;64 g->is_test_build = false;
66 g->want_h_file = true;65 g->want_h_file = true;
...@@ -227,13 +226,59 @@ void codegen_set_rdynamic(CodeGen *g, bool rdynamic) {...@@ -227,13 +226,59 @@ void codegen_set_rdynamic(CodeGen *g, bool rdynamic) {
227static void render_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val);226static void render_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val);
228static void render_const_val_global(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val);227static void render_const_val_global(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val);
229228
229static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
230 if (fn_table_entry->llvm_value)
231 return fn_table_entry->llvm_value;
232
233 Buf *symbol_name;
234 if (!fn_table_entry->internal_linkage) {
235 symbol_name = &fn_table_entry->symbol_name;
236 } else {
237 symbol_name = buf_sprintf("_%s", buf_ptr(&fn_table_entry->symbol_name));
238 }
239
240 TypeTableEntry *fn_type = fn_table_entry->type_entry;
241 fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_type->data.fn.raw_type_ref);
242
243 switch (fn_table_entry->fn_inline) {
244 case FnInlineAlways:
245 LLVMAddFunctionAttr(fn_table_entry->llvm_value, LLVMAlwaysInlineAttribute);
246 break;
247 case FnInlineNever:
248 LLVMAddFunctionAttr(fn_table_entry->llvm_value, LLVMNoInlineAttribute);
249 break;
250 case FnInlineAuto:
251 break;
252 }
253 if (fn_type->data.fn.fn_type_id.is_naked) {
254 LLVMAddFunctionAttr(fn_table_entry->llvm_value, LLVMNakedAttribute);
255 }
256
257 LLVMSetLinkage(fn_table_entry->llvm_value, fn_table_entry->internal_linkage ?
258 LLVMInternalLinkage : LLVMExternalLinkage);
259
260 if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdUnreachable) {
261 LLVMAddFunctionAttr(fn_table_entry->llvm_value, LLVMNoReturnAttribute);
262 }
263 LLVMSetFunctionCallConv(fn_table_entry->llvm_value, fn_type->data.fn.calling_convention);
264 if (!fn_type->data.fn.fn_type_id.is_extern) {
265 LLVMAddFunctionAttr(fn_table_entry->llvm_value, LLVMNoUnwindAttribute);
266 }
267 if (!g->is_release_build && fn_table_entry->fn_inline != FnInlineAlways) {
268 ZigLLVMAddFunctionAttr(fn_table_entry->llvm_value, "no-frame-pointer-elim", "true");
269 ZigLLVMAddFunctionAttr(fn_table_entry->llvm_value, "no-frame-pointer-elim-non-leaf", nullptr);
270 }
271
272 return fn_table_entry->llvm_value;
273}
274
230static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {275static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
231 if (scope->di_scope)276 if (scope->di_scope)
232 return scope->di_scope;277 return scope->di_scope;
233278
234 if (scope->node->type == NodeTypeFnDef) {279 if (scope->node->type == NodeTypeFnDef) {
235 assert(scope->parent);280 assert(scope->parent);
236 ScopeFnBody *fn_scope = (ScopeFnBody *)scope;281 ScopeFnDef *fn_scope = (ScopeFnDef *)scope;
237 FnTableEntry *fn_table_entry = fn_scope->fn_entry;282 FnTableEntry *fn_table_entry = fn_scope->fn_entry;
238 unsigned line_number = fn_table_entry->proto_node->line + 1;283 unsigned line_number = fn_table_entry->proto_node->line + 1;
239 unsigned scope_line = line_number;284 unsigned scope_line = line_number;
...@@ -247,11 +292,13 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {...@@ -247,11 +292,13 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
247 is_definition, scope_line, flags, is_optimized, nullptr);292 is_definition, scope_line, flags, is_optimized, nullptr);
248293
249 scope->di_scope = ZigLLVMSubprogramToScope(subprogram);294 scope->di_scope = ZigLLVMSubprogramToScope(subprogram);
250 ZigLLVMFnSetSubprogram(fn_table_entry->fn_value, subprogram);295 ZigLLVMFnSetSubprogram(fn_llvm_value(g, fn_table_entry), subprogram);
251 } else if (scope->node->type == NodeTypeRoot ||296 } else if (scope->node->type == NodeTypeRoot) {
252 scope->node->type == NodeTypeContainerDecl)
253 {
254 scope->di_scope = ZigLLVMFileToScope(scope->node->owner->di_file);297 scope->di_scope = ZigLLVMFileToScope(scope->node->owner->di_file);
298 } else if (scope->node->type == NodeTypeContainerDecl) {
299 ScopeDecls *decls_scope = (ScopeDecls *)scope;
300 assert(decls_scope->container_type);
301 scope->di_scope = ZigLLVMTypeToScope(decls_scope->container_type->di_type);
255 } else {302 } else {
256 assert(scope->parent);303 assert(scope->parent);
257 ZigLLVMDILexicalBlock *di_block = ZigLLVMCreateLexicalBlock(g->dbuilder,304 ZigLLVMDILexicalBlock *di_block = ZigLLVMCreateLexicalBlock(g->dbuilder,
...@@ -265,11 +312,6 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {...@@ -265,11 +312,6 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
265 return scope->di_scope;312 return scope->di_scope;
266}313}
267314
268static void set_debug_source_node(CodeGen *g, AstNode *node) {
269 assert(node->scope);
270 ZigLLVMSetCurrentDebugLocation(g->builder, node->line + 1, node->column + 1, get_di_scope(g, node->scope));
271}
272
273static void clear_debug_source_node(CodeGen *g) {315static void clear_debug_source_node(CodeGen *g) {
274 ZigLLVMClearCurrentDebugLocation(g->builder);316 ZigLLVMClearCurrentDebugLocation(g->builder);
275}317}
...@@ -350,24 +392,25 @@ static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, TypeTableEntr...@@ -350,24 +392,25 @@ static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, TypeTableEntr
350 }392 }
351}393}
352394
353static bool want_debug_safety_recursive(CodeGen *g, Scope *context) {395static bool ir_want_debug_safety(CodeGen *g, IrInstruction *instruction) {
354 if (context->safety_set_node || !context->parent) {396 if (g->is_release_build)
355 return !context->safety_off;
356 }
357 context->safety_off = !want_debug_safety_recursive(g, context->parent);
358 context->safety_set_node = context->parent->safety_set_node;
359 return !context->safety_off;
360}
361
362static bool want_debug_safety(CodeGen *g, AstNode *node) {
363 if (g->is_release_build) {
364 return false;397 return false;
365 }
366 return want_debug_safety_recursive(g, node->scope);
367}
368398
369static bool ir_want_debug_safety(CodeGen *g, IrInstruction *instruction) {399 // TODO memoize
370 return want_debug_safety(g, instruction->source_node);400 Scope *scope = instruction->scope;
401 while (scope) {
402 if (scope->node->type == NodeTypeBlock) {
403 ScopeBlock *block_scope = (ScopeBlock *)scope;
404 if (block_scope->safety_set_node)
405 return !block_scope->safety_off;
406 } else if (scope->node->type == NodeTypeRoot || scope->node->type == NodeTypeContainerDecl) {
407 ScopeDecls *decls_scope = (ScopeDecls *)scope;
408 if (decls_scope->safety_set_node)
409 return !decls_scope->safety_off;
410 }
411 scope = scope->parent;
412 }
413 return true;
371}414}
372415
373static void gen_debug_safety_crash(CodeGen *g) {416static void gen_debug_safety_crash(CodeGen *g) {
...@@ -388,10 +431,10 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,...@@ -388,10 +431,10 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
388 upper_value = nullptr;431 upper_value = nullptr;
389 }432 }
390433
391 LLVMBasicBlockRef bounds_check_fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoundsCheckFail");434 LLVMBasicBlockRef bounds_check_fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "BoundsCheckFail");
392 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "BoundsCheckOk");435 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "BoundsCheckOk");
393 LLVMBasicBlockRef lower_ok_block = upper_value ?436 LLVMBasicBlockRef lower_ok_block = upper_value ?
394 LLVMAppendBasicBlock(g->cur_fn->fn_value, "FirstBoundsCheckOk") : ok_block;437 LLVMAppendBasicBlock(g->cur_fn_val, "FirstBoundsCheckOk") : ok_block;
395438
396 LLVMValueRef lower_ok_val = LLVMBuildICmp(g->builder, lower_pred, target_val, lower_value, "");439 LLVMValueRef lower_ok_val = LLVMBuildICmp(g->builder, lower_pred, target_val, lower_value, "");
397 LLVMBuildCondBr(g->builder, lower_ok_val, lower_ok_block, bounds_check_fail_block);440 LLVMBuildCondBr(g->builder, lower_ok_val, lower_ok_block, bounds_check_fail_block);
...@@ -408,7 +451,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,...@@ -408,7 +451,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
408 LLVMPositionBuilderAtEnd(g->builder, ok_block);451 LLVMPositionBuilderAtEnd(g->builder, ok_block);
409}452}
410453
411static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeTableEntry *actual_type_non_canon,454static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, TypeTableEntry *actual_type_non_canon,
412 TypeTableEntry *wanted_type_non_canon, LLVMValueRef expr_val)455 TypeTableEntry *wanted_type_non_canon, LLVMValueRef expr_val)
413{456{
414 TypeTableEntry *actual_type = get_underlying_type(actual_type_non_canon);457 TypeTableEntry *actual_type = get_underlying_type(actual_type_non_canon);
...@@ -430,13 +473,13 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT...@@ -430,13 +473,13 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT
430473
431 if (actual_bits >= wanted_bits && actual_type->id == TypeTableEntryIdInt &&474 if (actual_bits >= wanted_bits && actual_type->id == TypeTableEntryIdInt &&
432 !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed &&475 !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed &&
433 want_debug_safety(g, source_node))476 want_debug_safety)
434 {477 {
435 LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);478 LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
436 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntSGE, expr_val, zero, "");479 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntSGE, expr_val, zero, "");
437480
438 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "SignCastOk");481 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SignCastOk");
439 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "SignCastFail");482 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SignCastFail");
440 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);483 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
441484
442 LLVMPositionBuilderAtEnd(g->builder, fail_block);485 LLVMPositionBuilderAtEnd(g->builder, fail_block);
...@@ -464,7 +507,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT...@@ -464,7 +507,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT
464 return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, "");507 return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, "");
465 } else if (actual_type->id == TypeTableEntryIdInt) {508 } else if (actual_type->id == TypeTableEntryIdInt) {
466 LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");509 LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");
467 if (!want_debug_safety(g, source_node)) {510 if (!want_debug_safety) {
468 return trunc_val;511 return trunc_val;
469 }512 }
470 LLVMValueRef orig_val;513 LLVMValueRef orig_val;
...@@ -474,8 +517,8 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT...@@ -474,8 +517,8 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, AstNode *source_node, TypeT
474 orig_val = LLVMBuildZExt(g->builder, trunc_val, actual_type->type_ref, "");517 orig_val = LLVMBuildZExt(g->builder, trunc_val, actual_type->type_ref, "");
475 }518 }
476 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, expr_val, orig_val, "");519 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, expr_val, orig_val, "");
477 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "CastShortenOk");520 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenOk");
478 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "CastShortenFail");521 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenFail");
479 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);522 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
480523
481 LLVMPositionBuilderAtEnd(g->builder, fail_block);524 LLVMPositionBuilderAtEnd(g->builder, fail_block);
...@@ -502,8 +545,8 @@ static LLVMValueRef gen_overflow_op(CodeGen *g, TypeTableEntry *type_entry, AddS...@@ -502,8 +545,8 @@ static LLVMValueRef gen_overflow_op(CodeGen *g, TypeTableEntry *type_entry, AddS
502 LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, "");545 LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, "");
503 LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, "");546 LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, "");
504 LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, "");547 LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, "");
505 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "OverflowFail");548 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowFail");
506 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "OverflowOk");549 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowOk");
507 LLVMBuildCondBr(g->builder, overflow_bit, fail_block, ok_block);550 LLVMBuildCondBr(g->builder, overflow_bit, fail_block, ok_block);
508551
509 LLVMPositionBuilderAtEnd(g->builder, fail_block);552 LLVMPositionBuilderAtEnd(g->builder, fail_block);
...@@ -645,8 +688,8 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, TypeTableEntry *type_entry,...@@ -645,8 +688,8 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, TypeTableEntry *type_entry,
645 }688 }
646 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, val1, orig_val, "");689 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, val1, orig_val, "");
647690
648 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "OverflowOk");691 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowOk");
649 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "OverflowFail");692 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowFail");
650 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);693 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
651694
652 LLVMPositionBuilderAtEnd(g->builder, fail_block);695 LLVMPositionBuilderAtEnd(g->builder, fail_block);
...@@ -656,11 +699,11 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, TypeTableEntry *type_entry,...@@ -656,11 +699,11 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, TypeTableEntry *type_entry,
656 return result;699 return result;
657}700}
658701
659static LLVMValueRef gen_div(CodeGen *g, AstNode *source_node, LLVMValueRef val1, LLVMValueRef val2,702static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, LLVMValueRef val1, LLVMValueRef val2,
660 TypeTableEntry *type_entry, bool exact)703 TypeTableEntry *type_entry, bool exact)
661{704{
662705
663 if (want_debug_safety(g, source_node)) {706 if (want_debug_safety) {
664 LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);707 LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);
665 LLVMValueRef is_zero_bit;708 LLVMValueRef is_zero_bit;
666 if (type_entry->id == TypeTableEntryIdInt) {709 if (type_entry->id == TypeTableEntryIdInt) {
...@@ -670,8 +713,8 @@ static LLVMValueRef gen_div(CodeGen *g, AstNode *source_node, LLVMValueRef val1,...@@ -670,8 +713,8 @@ static LLVMValueRef gen_div(CodeGen *g, AstNode *source_node, LLVMValueRef val1,
670 } else {713 } else {
671 zig_unreachable();714 zig_unreachable();
672 }715 }
673 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "DivZeroOk");716 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivZeroOk");
674 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "DivZeroFail");717 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivZeroFail");
675 LLVMBuildCondBr(g->builder, is_zero_bit, fail_block, ok_block);718 LLVMBuildCondBr(g->builder, is_zero_bit, fail_block, ok_block);
676719
677 LLVMPositionBuilderAtEnd(g->builder, fail_block);720 LLVMPositionBuilderAtEnd(g->builder, fail_block);
...@@ -688,7 +731,7 @@ static LLVMValueRef gen_div(CodeGen *g, AstNode *source_node, LLVMValueRef val1,...@@ -688,7 +731,7 @@ static LLVMValueRef gen_div(CodeGen *g, AstNode *source_node, LLVMValueRef val1,
688 assert(type_entry->id == TypeTableEntryIdInt);731 assert(type_entry->id == TypeTableEntryIdInt);
689732
690 if (exact) {733 if (exact) {
691 if (want_debug_safety(g, source_node)) {734 if (want_debug_safety) {
692 LLVMValueRef remainder_val;735 LLVMValueRef remainder_val;
693 if (type_entry->data.integral.is_signed) {736 if (type_entry->data.integral.is_signed) {
694 remainder_val = LLVMBuildSRem(g->builder, val1, val2, "");737 remainder_val = LLVMBuildSRem(g->builder, val1, val2, "");
...@@ -698,8 +741,8 @@ static LLVMValueRef gen_div(CodeGen *g, AstNode *source_node, LLVMValueRef val1,...@@ -698,8 +741,8 @@ static LLVMValueRef gen_div(CodeGen *g, AstNode *source_node, LLVMValueRef val1,
698 LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);741 LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);
699 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");742 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
700743
701 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "DivExactOk");744 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactOk");
702 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "DivExactFail");745 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail");
703 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);746 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
704747
705 LLVMPositionBuilderAtEnd(g->builder, fail_block);748 LLVMPositionBuilderAtEnd(g->builder, fail_block);
...@@ -727,7 +770,6 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -727,7 +770,6 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
727 IrBinOp op_id = bin_op_instruction->op_id;770 IrBinOp op_id = bin_op_instruction->op_id;
728 IrInstruction *op1 = bin_op_instruction->op1;771 IrInstruction *op1 = bin_op_instruction->op1;
729 IrInstruction *op2 = bin_op_instruction->op2;772 IrInstruction *op2 = bin_op_instruction->op2;
730 AstNode *source_node = bin_op_instruction->base.source_node;
731773
732 assert(op1->type_entry == op2->type_entry);774 assert(op1->type_entry == op2->type_entry);
733775
...@@ -801,7 +843,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -801,7 +843,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
801 bool is_wrapping = (op_id == IrBinOpBitShiftLeftWrap);843 bool is_wrapping = (op_id == IrBinOpBitShiftLeftWrap);
802 if (is_wrapping) {844 if (is_wrapping) {
803 return LLVMBuildShl(g->builder, op1_value, op2_value, "");845 return LLVMBuildShl(g->builder, op1_value, op2_value, "");
804 } else if (want_debug_safety(g, source_node)) {846 } else if (ir_want_debug_safety(g, &bin_op_instruction->base)) {
805 return gen_overflow_shl_op(g, op1->type_entry, op1_value, op2_value);847 return gen_overflow_shl_op(g, op1->type_entry, op1_value, op2_value);
806 } else if (op1->type_entry->data.integral.is_signed) {848 } else if (op1->type_entry->data.integral.is_signed) {
807 return ZigLLVMBuildNSWShl(g->builder, op1_value, op2_value, "");849 return ZigLLVMBuildNSWShl(g->builder, op1_value, op2_value, "");
...@@ -824,7 +866,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -824,7 +866,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
824 bool is_wrapping = (op_id == IrBinOpSubWrap);866 bool is_wrapping = (op_id == IrBinOpSubWrap);
825 if (is_wrapping) {867 if (is_wrapping) {
826 return LLVMBuildSub(g->builder, op1_value, op2_value, "");868 return LLVMBuildSub(g->builder, op1_value, op2_value, "");
827 } else if (want_debug_safety(g, source_node)) {869 } else if (ir_want_debug_safety(g, &bin_op_instruction->base)) {
828 return gen_overflow_op(g, op1->type_entry, AddSubMulSub, op1_value, op2_value);870 return gen_overflow_op(g, op1->type_entry, AddSubMulSub, op1_value, op2_value);
829 } else if (op1->type_entry->data.integral.is_signed) {871 } else if (op1->type_entry->data.integral.is_signed) {
830 return LLVMBuildNSWSub(g->builder, op1_value, op2_value, "");872 return LLVMBuildNSWSub(g->builder, op1_value, op2_value, "");
...@@ -842,7 +884,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -842,7 +884,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
842 bool is_wrapping = (op_id == IrBinOpMultWrap);884 bool is_wrapping = (op_id == IrBinOpMultWrap);
843 if (is_wrapping) {885 if (is_wrapping) {
844 return LLVMBuildMul(g->builder, op1_value, op2_value, "");886 return LLVMBuildMul(g->builder, op1_value, op2_value, "");
845 } else if (want_debug_safety(g, source_node)) {887 } else if (ir_want_debug_safety(g, &bin_op_instruction->base)) {
846 return gen_overflow_op(g, op1->type_entry, AddSubMulMul, op1_value, op2_value);888 return gen_overflow_op(g, op1->type_entry, AddSubMulMul, op1_value, op2_value);
847 } else if (op1->type_entry->data.integral.is_signed) {889 } else if (op1->type_entry->data.integral.is_signed) {
848 return LLVMBuildNSWMul(g->builder, op1_value, op2_value, "");890 return LLVMBuildNSWMul(g->builder, op1_value, op2_value, "");
...@@ -853,7 +895,8 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -853,7 +895,8 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
853 zig_unreachable();895 zig_unreachable();
854 }896 }
855 case IrBinOpDiv:897 case IrBinOpDiv:
856 return gen_div(g, source_node, op1_value, op2_value, op1->type_entry, false);898 return gen_div(g, ir_want_debug_safety(g, &bin_op_instruction->base),
899 op1_value, op2_value, op1->type_entry, false);
857 case IrBinOpMod:900 case IrBinOpMod:
858 if (op1->type_entry->id == TypeTableEntryIdFloat) {901 if (op1->type_entry->id == TypeTableEntryIdFloat) {
859 return LLVMBuildFRem(g->builder, op1_value, op2_value, "");902 return LLVMBuildFRem(g->builder, op1_value, op2_value, "");
...@@ -885,8 +928,8 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,...@@ -885,8 +928,8 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
885 case CastOpErrToInt:928 case CastOpErrToInt:
886 assert(actual_type->id == TypeTableEntryIdErrorUnion);929 assert(actual_type->id == TypeTableEntryIdErrorUnion);
887 if (!type_has_bits(actual_type->data.error.child_type)) {930 if (!type_has_bits(actual_type->data.error.child_type)) {
888 return gen_widen_or_shorten(g, cast_instruction->base.source_node,931 return gen_widen_or_shorten(g, ir_want_debug_safety(g, &cast_instruction->base),
889 g->err_tag_type, wanted_type, expr_val);932 g->err_tag_type, wanted_type, expr_val);
890 } else {933 } else {
891 zig_panic("TODO");934 zig_panic("TODO");
892 }935 }
...@@ -954,7 +997,8 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,...@@ -954,7 +997,8 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
954 case CastOpPointerReinterpret:997 case CastOpPointerReinterpret:
955 return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, "");998 return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, "");
956 case CastOpWidenOrShorten:999 case CastOpWidenOrShorten:
957 return gen_widen_or_shorten(g, cast_instruction->base.source_node, actual_type, wanted_type, expr_val);1000 return gen_widen_or_shorten(g, ir_want_debug_safety(g, &cast_instruction->base),
1001 actual_type, wanted_type, expr_val);
958 case CastOpToUnknownSizeArray:1002 case CastOpToUnknownSizeArray:
959 {1003 {
960 assert(cast_instruction->tmp_ptr);1004 assert(cast_instruction->tmp_ptr);
...@@ -1021,8 +1065,8 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,...@@ -1021,8 +1065,8 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
1021 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");1065 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");
1022 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->type_ref);1066 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->type_ref);
1023 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");1067 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
1024 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "SliceWidenOk");1068 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenOk");
1025 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "SliceWidenFail");1069 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenFail");
1026 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);1070 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
10271071
1028 LLVMPositionBuilderAtEnd(g->builder, fail_block);1072 LLVMPositionBuilderAtEnd(g->builder, fail_block);
...@@ -1087,10 +1131,10 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,...@@ -1087,10 +1131,10 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
1087 return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, "");1131 return LLVMBuildZExt(g->builder, expr_val, wanted_type->type_ref, "");
10881132
1089 case CastOpIntToEnum:1133 case CastOpIntToEnum:
1090 return gen_widen_or_shorten(g, cast_instruction->base.source_node,1134 return gen_widen_or_shorten(g, ir_want_debug_safety(g, &cast_instruction->base),
1091 actual_type, wanted_type->data.enumeration.tag_type, expr_val);1135 actual_type, wanted_type->data.enumeration.tag_type, expr_val);
1092 case CastOpEnumToInt:1136 case CastOpEnumToInt:
1093 return gen_widen_or_shorten(g, cast_instruction->base.source_node,1137 return gen_widen_or_shorten(g, ir_want_debug_safety(g, &cast_instruction->base),
1094 actual_type->data.enumeration.tag_type, wanted_type, expr_val);1138 actual_type->data.enumeration.tag_type, wanted_type, expr_val);
1095 }1139 }
1096 zig_unreachable();1140 zig_unreachable();
...@@ -1197,8 +1241,8 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst...@@ -1197,8 +1241,8 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
1197 }1241 }
1198 LLVMValueRef zero = LLVMConstNull(g->err_tag_type->type_ref);1242 LLVMValueRef zero = LLVMConstNull(g->err_tag_type->type_ref);
1199 LLVMValueRef cond_val = LLVMBuildICmp(g->builder, LLVMIntEQ, err_val, zero, "");1243 LLVMValueRef cond_val = LLVMBuildICmp(g->builder, LLVMIntEQ, err_val, zero, "");
1200 LLVMBasicBlockRef err_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrError");1244 LLVMBasicBlockRef err_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapErrError");
1201 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapErrOk");1245 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapErrOk");
1202 LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);1246 LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);
12031247
1204 LLVMPositionBuilderAtEnd(g->builder, err_block);1248 LLVMPositionBuilderAtEnd(g->builder, err_block);
...@@ -1231,8 +1275,8 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst...@@ -1231,8 +1275,8 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
1231 cond_val = LLVMBuildLoad(g->builder, maybe_null_ptr, "");1275 cond_val = LLVMBuildLoad(g->builder, maybe_null_ptr, "");
1232 }1276 }
12331277
1234 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapMaybeOk");1278 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeOk");
1235 LLVMBasicBlockRef null_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapMaybeNull");1279 LLVMBasicBlockRef null_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeNull");
1236 LLVMBuildCondBr(g->builder, cond_val, ok_block, null_block);1280 LLVMBuildCondBr(g->builder, cond_val, ok_block, null_block);
12371281
1238 LLVMPositionBuilderAtEnd(g->builder, null_block);1282 LLVMPositionBuilderAtEnd(g->builder, null_block);
...@@ -1408,7 +1452,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr...@@ -1408,7 +1452,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
1408 LLVMValueRef fn_val;1452 LLVMValueRef fn_val;
1409 TypeTableEntry *fn_type;1453 TypeTableEntry *fn_type;
1410 if (instruction->fn_entry) {1454 if (instruction->fn_entry) {
1411 fn_val = instruction->fn_entry->fn_value;1455 fn_val = fn_llvm_value(g, instruction->fn_entry);
1412 fn_type = instruction->fn_entry->type_entry;1456 fn_type = instruction->fn_entry->type_entry;
1413 } else {1457 } else {
1414 assert(instruction->fn_ref);1458 assert(instruction->fn_ref);
...@@ -1563,7 +1607,7 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru...@@ -1563,7 +1607,7 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru
1563 }1607 }
15641608
1565 if (!is_return) {1609 if (!is_return) {
1566 VariableTableEntry *variable = asm_output->variable;1610 VariableTableEntry *variable = instruction->output_vars[i];
1567 assert(variable);1611 assert(variable);
1568 param_types[param_index] = LLVMTypeOf(variable->value_ref);1612 param_types[param_index] = LLVMTypeOf(variable->value_ref);
1569 param_values[param_index] = variable->value_ref;1613 param_values[param_index] = variable->value_ref;
...@@ -1638,8 +1682,8 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,...@@ -1638,8 +1682,8 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,
1638 LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value);1682 LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value);
1639 if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on) {1683 if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on) {
1640 LLVMValueRef nonnull_bit = gen_null_bit(g, ptr_type, maybe_ptr);1684 LLVMValueRef nonnull_bit = gen_null_bit(g, ptr_type, maybe_ptr);
1641 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapMaybeOk");1685 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeOk");
1642 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "UnwrapMaybeFail");1686 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeFail");
1643 LLVMBuildCondBr(g->builder, nonnull_bit, ok_block, fail_block);1687 LLVMBuildCondBr(g->builder, nonnull_bit, ok_block, fail_block);
16441688
1645 LLVMPositionBuilderAtEnd(g->builder, fail_block);1689 LLVMPositionBuilderAtEnd(g->builder, fail_block);
...@@ -1730,8 +1774,18 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstru...@@ -1730,8 +1774,18 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstru
1730 }1774 }
1731}1775}
17321776
1777static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
1778 AstNode *source_node = instruction->source_node;
1779 Scope *scope = instruction->scope;
1780
1781 assert(source_node);
1782 assert(scope);
1783
1784 ZigLLVMSetCurrentDebugLocation(g->builder, source_node->line + 1, source_node->column + 1, get_di_scope(g, scope));
1785}
1786
1733static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {1787static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) {
1734 set_debug_source_node(g, instruction->source_node);1788 set_debug_location(g, instruction);
17351789
1736 switch (instruction->id) {1790 switch (instruction->id) {
1737 case IrInstructionIdInvalid:1791 case IrInstructionIdInvalid:
...@@ -1961,7 +2015,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE...@@ -1961,7 +2015,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
1961 }2015 }
1962 }2016 }
1963 case TypeTableEntryIdFn:2017 case TypeTableEntryIdFn:
1964 return const_val->data.x_fn->fn_value;2018 return fn_llvm_value(g, const_val->data.x_fn);
1965 case TypeTableEntryIdPointer:2019 case TypeTableEntryIdPointer:
1966 {2020 {
1967 TypeTableEntry *child_type = type_entry->data.pointer.child_type;2021 TypeTableEntry *child_type = type_entry->data.pointer.child_type;
...@@ -2021,7 +2075,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE...@@ -2021,7 +2075,6 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
2021 case TypeTableEntryIdNullLit:2075 case TypeTableEntryIdNullLit:
2022 case TypeTableEntryIdNamespace:2076 case TypeTableEntryIdNamespace:
2023 case TypeTableEntryIdBlock:2077 case TypeTableEntryIdBlock:
2024 case TypeTableEntryIdGenericFn:
2025 case TypeTableEntryIdBoundFn:2078 case TypeTableEntryIdBoundFn:
2026 case TypeTableEntryIdVar:2079 case TypeTableEntryIdVar:
2027 zig_unreachable();2080 zig_unreachable();
...@@ -2107,7 +2160,7 @@ static LLVMValueRef gen_test_fn_val(CodeGen *g, FnTableEntry *fn_entry) {...@@ -2107,7 +2160,7 @@ static LLVMValueRef gen_test_fn_val(CodeGen *g, FnTableEntry *fn_entry) {
2107 LLVMValueRef name_val = LLVMConstStruct(name_fields, 2, false);2160 LLVMValueRef name_val = LLVMConstStruct(name_fields, 2, false);
2108 LLVMValueRef fields[] = {2161 LLVMValueRef fields[] = {
2109 name_val,2162 name_val,
2110 fn_entry->fn_value,2163 fn_llvm_value(g, fn_entry),
2111 };2164 };
2112 return LLVMConstStruct(fields, 2, false);2165 return LLVMConstStruct(fields, 2, false);
2113}2166}
...@@ -2157,7 +2210,7 @@ static void build_all_basic_blocks(CodeGen *g, FnTableEntry *fn) {...@@ -2157,7 +2210,7 @@ static void build_all_basic_blocks(CodeGen *g, FnTableEntry *fn) {
2157 assert(executable->basic_block_list.length > 0);2210 assert(executable->basic_block_list.length > 0);
2158 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {2211 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {
2159 IrBasicBlock *bb = executable->basic_block_list.at(block_i);2212 IrBasicBlock *bb = executable->basic_block_list.at(block_i);
2160 bb->llvm_block = LLVMAppendBasicBlock(fn->fn_value, bb->name_hint);2213 bb->llvm_block = LLVMAppendBasicBlock(fn_llvm_value(g, fn), bb->name_hint);
2161 }2214 }
2162 IrBasicBlock *entry_bb = executable->basic_block_list.at(0);2215 IrBasicBlock *entry_bb = executable->basic_block_list.at(0);
2163 LLVMPositionBuilderAtEnd(g->builder, entry_bb->llvm_block);2216 LLVMPositionBuilderAtEnd(g->builder, entry_bb->llvm_block);
...@@ -2167,11 +2220,14 @@ static void gen_global_var(CodeGen *g, VariableTableEntry *var, LLVMValueRef ini...@@ -2167,11 +2220,14 @@ static void gen_global_var(CodeGen *g, VariableTableEntry *var, LLVMValueRef ini
2167 TypeTableEntry *type_entry)2220 TypeTableEntry *type_entry)
2168{2221{
2169 assert(var->gen_is_const);2222 assert(var->gen_is_const);
2170 assert(var->import);
2171 assert(type_entry);2223 assert(type_entry);
2224
2225 ImportTableEntry *import = get_scope_import(var->parent_scope);
2226 assert(import);
2227
2172 bool is_local_to_unit = true;2228 bool is_local_to_unit = true;
2173 ZigLLVMCreateGlobalVariable(g->dbuilder, get_di_scope(g, var->parent_scope), buf_ptr(&var->name),2229 ZigLLVMCreateGlobalVariable(g->dbuilder, get_di_scope(g, var->parent_scope), buf_ptr(&var->name),
2174 buf_ptr(&var->name), var->import->di_file, var->decl_node->line + 1,2230 buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,
2175 type_entry->di_type, is_local_to_unit, init_val);2231 type_entry->di_type, is_local_to_unit, init_val);
2176}2232}
21772233
...@@ -2187,7 +2243,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2187,7 +2243,7 @@ static void do_code_gen(CodeGen *g) {
21872243
2188 if (var->type->id == TypeTableEntryIdNumLitFloat) {2244 if (var->type->id == TypeTableEntryIdNumLitFloat) {
2189 // Generate debug info for it but that's it.2245 // Generate debug info for it but that's it.
2190 ConstExprValue *const_val = &var->decl_node->data.variable_declaration.top_level_decl.value->static_value;2246 ConstExprValue *const_val = var->value;
2191 assert(const_val->special != ConstValSpecialRuntime);2247 assert(const_val->special != ConstValSpecialRuntime);
2192 TypeTableEntry *var_type = g->builtin_types.entry_f64;2248 TypeTableEntry *var_type = g->builtin_types.entry_f64;
2193 LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float);2249 LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float);
...@@ -2197,7 +2253,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2197,7 +2253,7 @@ static void do_code_gen(CodeGen *g) {
21972253
2198 if (var->type->id == TypeTableEntryIdNumLitInt) {2254 if (var->type->id == TypeTableEntryIdNumLitInt) {
2199 // Generate debug info for it but that's it.2255 // Generate debug info for it but that's it.
2200 ConstExprValue *const_val = &var->decl_node->data.variable_declaration.top_level_decl.value->static_value;2256 ConstExprValue *const_val = var->value;
2201 assert(const_val->special != ConstValSpecialRuntime);2257 assert(const_val->special != ConstValSpecialRuntime);
2202 TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?2258 TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?
2203 g->builtin_types.entry_isize : g->builtin_types.entry_usize;2259 g->builtin_types.entry_isize : g->builtin_types.entry_usize;
...@@ -2222,13 +2278,12 @@ static void do_code_gen(CodeGen *g) {...@@ -2222,13 +2278,12 @@ static void do_code_gen(CodeGen *g) {
22222278
2223 LLVMSetLinkage(global_value, LLVMExternalLinkage);2279 LLVMSetLinkage(global_value, LLVMExternalLinkage);
2224 } else {2280 } else {
2225 IrInstruction *instruction = var->decl_node->data.variable_declaration.top_level_decl.value;2281 render_const_val(g, var->type, var->value);
2226 render_const_val(g, instruction->type_entry, &instruction->static_value);2282 render_const_val_global(g, var->type, var->value);
2227 render_const_val_global(g, instruction->type_entry, &instruction->static_value);2283 global_value = var->value->llvm_global;
2228 global_value = instruction->static_value.llvm_global;
2229 // TODO debug info for function pointers2284 // TODO debug info for function pointers
2230 if (var->gen_is_const && var->type->id != TypeTableEntryIdFn) {2285 if (var->gen_is_const && var->type->id != TypeTableEntryIdFn) {
2231 gen_global_var(g, var, instruction->static_value.llvm_value, var->type);2286 gen_global_var(g, var, var->value->llvm_value, var->type);
2232 }2287 }
2233 }2288 }
22342289
...@@ -2246,12 +2301,8 @@ static void do_code_gen(CodeGen *g) {...@@ -2246,12 +2301,8 @@ static void do_code_gen(CodeGen *g) {
2246 // Generate function prototypes2301 // Generate function prototypes
2247 for (size_t fn_proto_i = 0; fn_proto_i < g->fn_protos.length; fn_proto_i += 1) {2302 for (size_t fn_proto_i = 0; fn_proto_i < g->fn_protos.length; fn_proto_i += 1) {
2248 FnTableEntry *fn_table_entry = g->fn_protos.at(fn_proto_i);2303 FnTableEntry *fn_table_entry = g->fn_protos.at(fn_proto_i);
2249 if (should_skip_fn_codegen(g, fn_table_entry)) {2304 if (should_skip_fn_codegen(g, fn_table_entry))
2250 // huge time saver
2251 LLVMDeleteFunction(fn_table_entry->fn_value);
2252 fn_table_entry->fn_value = nullptr;
2253 continue;2305 continue;
2254 }
22552306
2256 AstNode *proto_node = fn_table_entry->proto_node;2307 AstNode *proto_node = fn_table_entry->proto_node;
2257 assert(proto_node->type == NodeTypeFnProto);2308 assert(proto_node->type == NodeTypeFnProto);
...@@ -2259,16 +2310,18 @@ static void do_code_gen(CodeGen *g) {...@@ -2259,16 +2310,18 @@ static void do_code_gen(CodeGen *g) {
22592310
2260 TypeTableEntry *fn_type = fn_table_entry->type_entry;2311 TypeTableEntry *fn_type = fn_table_entry->type_entry;
22612312
2313 LLVMValueRef fn_val = fn_llvm_value(g, fn_table_entry);
2314
2262 if (!type_has_bits(fn_type->data.fn.fn_type_id.return_type)) {2315 if (!type_has_bits(fn_type->data.fn.fn_type_id.return_type)) {
2263 // nothing to do2316 // nothing to do
2264 } else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer) {2317 } else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer) {
2265 ZigLLVMAddNonNullAttr(fn_table_entry->fn_value, 0);2318 ZigLLVMAddNonNullAttr(fn_val, 0);
2266 } else if (handle_is_ptr(fn_type->data.fn.fn_type_id.return_type) &&2319 } else if (handle_is_ptr(fn_type->data.fn.fn_type_id.return_type) &&
2267 !fn_type->data.fn.fn_type_id.is_extern)2320 !fn_type->data.fn.fn_type_id.is_extern)
2268 {2321 {
2269 LLVMValueRef first_arg = LLVMGetParam(fn_table_entry->fn_value, 0);2322 LLVMValueRef first_arg = LLVMGetParam(fn_val, 0);
2270 LLVMAddAttribute(first_arg, LLVMStructRetAttribute);2323 LLVMAddAttribute(first_arg, LLVMStructRetAttribute);
2271 ZigLLVMAddNonNullAttr(fn_table_entry->fn_value, 1);2324 ZigLLVMAddNonNullAttr(fn_val, 1);
2272 }2325 }
22732326
22742327
...@@ -2286,7 +2339,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2286,7 +2339,7 @@ static void do_code_gen(CodeGen *g) {
2286 }2339 }
22872340
2288 TypeTableEntry *param_type = info->type;2341 TypeTableEntry *param_type = info->type;
2289 LLVMValueRef argument_val = LLVMGetParam(fn_table_entry->fn_value, gen_index);2342 LLVMValueRef argument_val = LLVMGetParam(fn_val, gen_index);
2290 bool param_is_noalias = param_node->data.param_decl.is_noalias;2343 bool param_is_noalias = param_node->data.param_decl.is_noalias;
2291 if (param_is_noalias) {2344 if (param_is_noalias) {
2292 LLVMAddAttribute(argument_val, LLVMNoAliasAttribute);2345 LLVMAddAttribute(argument_val, LLVMNoAliasAttribute);
...@@ -2295,7 +2348,7 @@ static void do_code_gen(CodeGen *g) {...@@ -2295,7 +2348,7 @@ static void do_code_gen(CodeGen *g) {
2295 LLVMAddAttribute(argument_val, LLVMReadOnlyAttribute);2348 LLVMAddAttribute(argument_val, LLVMReadOnlyAttribute);
2296 }2349 }
2297 if (param_type->id == TypeTableEntryIdPointer) {2350 if (param_type->id == TypeTableEntryIdPointer) {
2298 ZigLLVMAddNonNullAttr(fn_table_entry->fn_value, gen_index + 1);2351 ZigLLVMAddNonNullAttr(fn_val, gen_index + 1);
2299 }2352 }
2300 if (is_byval) {2353 if (is_byval) {
2301 // TODO2354 // TODO
...@@ -2345,14 +2398,13 @@ static void do_code_gen(CodeGen *g) {...@@ -2345,14 +2398,13 @@ static void do_code_gen(CodeGen *g) {
2345 // Generate function definitions.2398 // Generate function definitions.
2346 for (size_t fn_i = 0; fn_i < g->fn_defs.length; fn_i += 1) {2399 for (size_t fn_i = 0; fn_i < g->fn_defs.length; fn_i += 1) {
2347 FnTableEntry *fn_table_entry = g->fn_defs.at(fn_i);2400 FnTableEntry *fn_table_entry = g->fn_defs.at(fn_i);
2348 if (should_skip_fn_codegen(g, fn_table_entry)) {2401 if (should_skip_fn_codegen(g, fn_table_entry))
2349 // huge time saver
2350 continue;2402 continue;
2351 }
23522403
2353 ImportTableEntry *import = fn_table_entry->import_entry;2404 ImportTableEntry *import = fn_table_entry->import_entry;
2354 LLVMValueRef fn = fn_table_entry->fn_value;2405 LLVMValueRef fn = fn_llvm_value(g, fn_table_entry);
2355 g->cur_fn = fn_table_entry;2406 g->cur_fn = fn_table_entry;
2407 g->cur_fn_val = fn;
2356 if (handle_is_ptr(fn_table_entry->type_entry->data.fn.fn_type_id.return_type)) {2408 if (handle_is_ptr(fn_table_entry->type_entry->data.fn.fn_type_id.return_type)) {
2357 g->cur_ret_ptr = LLVMGetParam(fn, 0);2409 g->cur_ret_ptr = LLVMGetParam(fn, 0);
2358 } else {2410 } else {
...@@ -2401,7 +2453,18 @@ static void do_code_gen(CodeGen *g) {...@@ -2401,7 +2453,18 @@ static void do_code_gen(CodeGen *g) {
2401 if (var->is_inline)2453 if (var->is_inline)
2402 continue;2454 continue;
24032455
2404 if (var->parent_scope->node->type == NodeTypeFnDef) {2456 if (var->src_arg_index == SIZE_MAX) {
2457 var->value_ref = LLVMBuildAlloca(g->builder, var->type->type_ref, buf_ptr(&var->name));
2458
2459
2460 unsigned align_bytes = ZigLLVMGetPrefTypeAlignment(g->target_data_ref, var->type->type_ref);
2461 LLVMSetAlignment(var->value_ref, align_bytes);
2462
2463 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
2464 buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,
2465 var->type->di_type, !g->strip_debug_symbols, 0);
2466
2467 } else {
2405 assert(var->gen_arg_index != SIZE_MAX);2468 assert(var->gen_arg_index != SIZE_MAX);
2406 TypeTableEntry *gen_type;2469 TypeTableEntry *gen_type;
2407 if (handle_is_ptr(var->type)) {2470 if (handle_is_ptr(var->type)) {
...@@ -2417,31 +2480,21 @@ static void do_code_gen(CodeGen *g) {...@@ -2417,31 +2480,21 @@ static void do_code_gen(CodeGen *g) {
2417 buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,2480 buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,
2418 gen_type->di_type, !g->strip_debug_symbols, 0, var->gen_arg_index + 1);2481 gen_type->di_type, !g->strip_debug_symbols, 0, var->gen_arg_index + 1);
24192482
2420 } else {
2421 var->value_ref = LLVMBuildAlloca(g->builder, var->type->type_ref, buf_ptr(&var->name));
2422
2423
2424 unsigned align_bytes = ZigLLVMGetPrefTypeAlignment(g->target_data_ref, var->type->type_ref);
2425 LLVMSetAlignment(var->value_ref, align_bytes);
2426
2427 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
2428 buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,
2429 var->type->di_type, !g->strip_debug_symbols, 0);
2430 }2483 }
2431 }2484 }
24322485
2433 // create debug variable declarations for parameters2486 // create debug variable declarations for parameters
2487 // rely on the first variables in the variable_list being parameters.
2488 size_t next_var_i = 0;
2434 for (size_t param_i = 0; param_i < fn_proto->params.length; param_i += 1) {2489 for (size_t param_i = 0; param_i < fn_proto->params.length; param_i += 1) {
2435 AstNode *param_decl = fn_proto->params.at(param_i);
2436 assert(param_decl->type == NodeTypeParamDecl);
2437
2438 FnGenParamInfo *info = &fn_table_entry->type_entry->data.fn.gen_param_info[param_i];2490 FnGenParamInfo *info = &fn_table_entry->type_entry->data.fn.gen_param_info[param_i];
24392491 if (info->gen_index == SIZE_MAX)
2440 if (info->gen_index == SIZE_MAX) {
2441 continue;2492 continue;
2442 }
24432493
2444 VariableTableEntry *variable = param_decl->data.param_decl.variable;2494 VariableTableEntry *variable = fn_table_entry->variable_list.at(next_var_i);
2495 assert(variable->src_arg_index != SIZE_MAX);
2496 next_var_i += 1;
2497
2445 assert(variable);2498 assert(variable);
2446 assert(variable->value_ref);2499 assert(variable->value_ref);
24472500
...@@ -3308,7 +3361,6 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {...@@ -3308,7 +3361,6 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
3308 zig_panic("TODO");3361 zig_panic("TODO");
3309 case TypeTableEntryIdInvalid:3362 case TypeTableEntryIdInvalid:
3310 case TypeTableEntryIdMetaType:3363 case TypeTableEntryIdMetaType:
3311 case TypeTableEntryIdGenericFn:
3312 case TypeTableEntryIdBoundFn:3364 case TypeTableEntryIdBoundFn:
3313 case TypeTableEntryIdNamespace:3365 case TypeTableEntryIdNamespace:
3314 case TypeTableEntryIdBlock:3366 case TypeTableEntryIdBlock:
...@@ -3343,7 +3395,7 @@ void codegen_generate_h_file(CodeGen *g) {...@@ -3343,7 +3395,7 @@ void codegen_generate_h_file(CodeGen *g) {
3343 assert(proto_node->type == NodeTypeFnProto);3395 assert(proto_node->type == NodeTypeFnProto);
3344 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;3396 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
33453397
3346 if (fn_proto->top_level_decl.visib_mod != VisibModExport)3398 if (fn_proto->visib_mod != VisibModExport)
3347 continue;3399 continue;
33483400
3349 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;3401 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;
src/eval.cpp-1
...@@ -55,7 +55,6 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty...@@ -55,7 +55,6 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty
55 zig_panic("TODO");55 zig_panic("TODO");
56 case TypeTableEntryIdBlock:56 case TypeTableEntryIdBlock:
57 zig_panic("TODO");57 zig_panic("TODO");
58 case TypeTableEntryIdGenericFn:
59 case TypeTableEntryIdBoundFn:58 case TypeTableEntryIdBoundFn:
60 case TypeTableEntryIdInvalid:59 case TypeTableEntryIdInvalid:
61 case TypeTableEntryIdUnreachable:60 case TypeTableEntryIdUnreachable:
src/ir.cpp+686-668
...@@ -1,3 +1,10 @@...@@ -1,3 +1,10 @@
1/*
2 * Copyright (c) 2016 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
1#include "analyze.hpp"8#include "analyze.hpp"
2#include "error.hpp"9#include "error.hpp"
3#include "eval.hpp"10#include "eval.hpp"
...@@ -71,6 +78,10 @@ static size_t exec_next_mem_slot(IrExecutable *exec) {...@@ -71,6 +78,10 @@ static size_t exec_next_mem_slot(IrExecutable *exec) {
71 return result;78 return result;
72}79}
7380
81static FnTableEntry *exec_fn_entry(IrExecutable *exec) {
82 return exec->fn_entry;
83}
84
74static void ir_link_new_instruction(IrInstruction *new_instruction, IrInstruction *old_instruction) {85static void ir_link_new_instruction(IrInstruction *new_instruction, IrInstruction *old_instruction) {
75 new_instruction->other = old_instruction;86 new_instruction->other = old_instruction;
76 old_instruction->other = new_instruction;87 old_instruction->other = new_instruction;
...@@ -289,26 +300,27 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStructInit *) {...@@ -289,26 +300,27 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStructInit *) {
289}300}
290301
291template<typename T>302template<typename T>
292static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) {303static T *ir_create_instruction(IrExecutable *exec, Scope *scope, AstNode *source_node) {
293 T *special_instruction = allocate<T>(1);304 T *special_instruction = allocate<T>(1);
294 special_instruction->base.id = ir_instruction_id(special_instruction);305 special_instruction->base.id = ir_instruction_id(special_instruction);
306 special_instruction->base.scope = scope;
295 special_instruction->base.source_node = source_node;307 special_instruction->base.source_node = source_node;
296 special_instruction->base.debug_id = exec_next_debug_id(exec);308 special_instruction->base.debug_id = exec_next_debug_id(exec);
297 return special_instruction;309 return special_instruction;
298}310}
299311
300template<typename T>312template<typename T>
301static T *ir_build_instruction(IrBuilder *irb, AstNode *source_node) {313static T *ir_build_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
302 assert(source_node);314 assert(source_node);
303 T *special_instruction = ir_create_instruction<T>(irb->exec, source_node);315 T *special_instruction = ir_create_instruction<T>(irb->exec, scope, source_node);
304 ir_instruction_append(irb->current_basic_block, &special_instruction->base);316 ir_instruction_append(irb->current_basic_block, &special_instruction->base);
305 return special_instruction;317 return special_instruction;
306}318}
307319
308static IrInstruction *ir_build_cast(IrBuilder *irb, AstNode *source_node, TypeTableEntry *dest_type,320static IrInstruction *ir_build_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, TypeTableEntry *dest_type,
309 IrInstruction *value, CastOp cast_op)321 IrInstruction *value, CastOp cast_op)
310{322{
311 IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, source_node);323 IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, scope, source_node);
312 cast_instruction->dest_type = dest_type;324 cast_instruction->dest_type = dest_type;
313 cast_instruction->value = value;325 cast_instruction->value = value;
314 cast_instruction->cast_op = cast_op;326 cast_instruction->cast_op = cast_op;
...@@ -318,10 +330,10 @@ static IrInstruction *ir_build_cast(IrBuilder *irb, AstNode *source_node, TypeTa...@@ -318,10 +330,10 @@ static IrInstruction *ir_build_cast(IrBuilder *irb, AstNode *source_node, TypeTa
318 return &cast_instruction->base;330 return &cast_instruction->base;
319}331}
320332
321static IrInstruction *ir_build_cond_br(IrBuilder *irb, AstNode *source_node, IrInstruction *condition,333static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *condition,
322 IrBasicBlock *then_block, IrBasicBlock *else_block, bool is_inline)334 IrBasicBlock *then_block, IrBasicBlock *else_block, bool is_inline)
323{335{
324 IrInstructionCondBr *cond_br_instruction = ir_build_instruction<IrInstructionCondBr>(irb, source_node);336 IrInstructionCondBr *cond_br_instruction = ir_build_instruction<IrInstructionCondBr>(irb, scope, source_node);
325 cond_br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable;337 cond_br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable;
326 cond_br_instruction->base.static_value.special = ConstValSpecialStatic;338 cond_br_instruction->base.static_value.special = ConstValSpecialStatic;
327 cond_br_instruction->condition = condition;339 cond_br_instruction->condition = condition;
...@@ -339,14 +351,14 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, AstNode *source_node, IrI...@@ -339,14 +351,14 @@ static IrInstruction *ir_build_cond_br(IrBuilder *irb, AstNode *source_node, IrI
339static IrInstruction *ir_build_cond_br_from(IrBuilder *irb, IrInstruction *old_instruction,351static IrInstruction *ir_build_cond_br_from(IrBuilder *irb, IrInstruction *old_instruction,
340 IrInstruction *condition, IrBasicBlock *then_block, IrBasicBlock *else_block, bool is_inline)352 IrInstruction *condition, IrBasicBlock *then_block, IrBasicBlock *else_block, bool is_inline)
341{353{
342 IrInstruction *new_instruction = ir_build_cond_br(irb, old_instruction->source_node,354 IrInstruction *new_instruction = ir_build_cond_br(irb, old_instruction->scope, old_instruction->source_node,
343 condition, then_block, else_block, is_inline);355 condition, then_block, else_block, is_inline);
344 ir_link_new_instruction(new_instruction, old_instruction);356 ir_link_new_instruction(new_instruction, old_instruction);
345 return new_instruction;357 return new_instruction;
346}358}
347359
348static IrInstruction *ir_build_return(IrBuilder *irb, AstNode *source_node, IrInstruction *return_value) {360static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *return_value) {
349 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, source_node);361 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node);
350 return_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable;362 return_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable;
351 return_instruction->base.static_value.special = ConstValSpecialStatic;363 return_instruction->base.static_value.special = ConstValSpecialStatic;
352 return_instruction->value = return_value;364 return_instruction->value = return_value;
...@@ -359,38 +371,38 @@ static IrInstruction *ir_build_return(IrBuilder *irb, AstNode *source_node, IrIn...@@ -359,38 +371,38 @@ static IrInstruction *ir_build_return(IrBuilder *irb, AstNode *source_node, IrIn
359static IrInstruction *ir_build_return_from(IrBuilder *irb, IrInstruction *old_instruction,371static IrInstruction *ir_build_return_from(IrBuilder *irb, IrInstruction *old_instruction,
360 IrInstruction *return_value)372 IrInstruction *return_value)
361{373{
362 IrInstruction *new_instruction = ir_build_return(irb, old_instruction->source_node, return_value);374 IrInstruction *new_instruction = ir_build_return(irb, old_instruction->scope, old_instruction->source_node, return_value);
363 ir_link_new_instruction(new_instruction, old_instruction);375 ir_link_new_instruction(new_instruction, old_instruction);
364 return new_instruction;376 return new_instruction;
365}377}
366378
367static IrInstruction *ir_create_const(IrBuilder *irb, AstNode *source_node,379static IrInstruction *ir_create_const(IrBuilder *irb, Scope *scope, AstNode *source_node,
368 TypeTableEntry *type_entry, bool depends_on_compile_var)380 TypeTableEntry *type_entry, bool depends_on_compile_var)
369{381{
370 assert(type_entry);382 assert(type_entry);
371 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, source_node);383 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, scope, source_node);
372 const_instruction->base.type_entry = type_entry;384 const_instruction->base.type_entry = type_entry;
373 const_instruction->base.static_value.special = ConstValSpecialStatic;385 const_instruction->base.static_value.special = ConstValSpecialStatic;
374 const_instruction->base.static_value.depends_on_compile_var = depends_on_compile_var;386 const_instruction->base.static_value.depends_on_compile_var = depends_on_compile_var;
375 return &const_instruction->base;387 return &const_instruction->base;
376}388}
377389
378static IrInstruction *ir_build_const_void(IrBuilder *irb, AstNode *source_node) {390static IrInstruction *ir_build_const_void(IrBuilder *irb, Scope *scope, AstNode *source_node) {
379 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);391 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
380 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_void;392 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_void;
381 const_instruction->base.static_value.special = ConstValSpecialStatic;393 const_instruction->base.static_value.special = ConstValSpecialStatic;
382 return &const_instruction->base;394 return &const_instruction->base;
383}395}
384396
385static IrInstruction *ir_build_const_undefined(IrBuilder *irb, AstNode *source_node) {397static IrInstruction *ir_build_const_undefined(IrBuilder *irb, Scope *scope, AstNode *source_node) {
386 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);398 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
387 const_instruction->base.static_value.special = ConstValSpecialUndef;399 const_instruction->base.static_value.special = ConstValSpecialUndef;
388 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_undef;400 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_undef;
389 return &const_instruction->base;401 return &const_instruction->base;
390}402}
391403
392static IrInstruction *ir_build_const_bignum(IrBuilder *irb, AstNode *source_node, BigNum *bignum) {404static IrInstruction *ir_build_const_bignum(IrBuilder *irb, Scope *scope, AstNode *source_node, BigNum *bignum) {
393 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);405 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
394 const_instruction->base.type_entry = (bignum->kind == BigNumKindInt) ?406 const_instruction->base.type_entry = (bignum->kind == BigNumKindInt) ?
395 irb->codegen->builtin_types.entry_num_lit_int : irb->codegen->builtin_types.entry_num_lit_float;407 irb->codegen->builtin_types.entry_num_lit_int : irb->codegen->builtin_types.entry_num_lit_float;
396 const_instruction->base.static_value.special = ConstValSpecialStatic;408 const_instruction->base.static_value.special = ConstValSpecialStatic;
...@@ -398,79 +410,77 @@ static IrInstruction *ir_build_const_bignum(IrBuilder *irb, AstNode *source_node...@@ -398,79 +410,77 @@ static IrInstruction *ir_build_const_bignum(IrBuilder *irb, AstNode *source_node
398 return &const_instruction->base;410 return &const_instruction->base;
399}411}
400412
401static IrInstruction *ir_build_const_null(IrBuilder *irb, AstNode *source_node) {413static IrInstruction *ir_build_const_null(IrBuilder *irb, Scope *scope, AstNode *source_node) {
402 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);414 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
403 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_null;415 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_null;
404 const_instruction->base.static_value.special = ConstValSpecialStatic;416 const_instruction->base.static_value.special = ConstValSpecialStatic;
405 return &const_instruction->base;417 return &const_instruction->base;
406}418}
407419
408static IrInstruction *ir_build_const_usize(IrBuilder *irb, AstNode *source_node, uint64_t value) {420static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode *source_node, uint64_t value) {
409 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);421 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
410 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_usize;422 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_usize;
411 const_instruction->base.static_value.special = ConstValSpecialStatic;423 const_instruction->base.static_value.special = ConstValSpecialStatic;
412 bignum_init_unsigned(&const_instruction->base.static_value.data.x_bignum, value);424 bignum_init_unsigned(&const_instruction->base.static_value.data.x_bignum, value);
413 return &const_instruction->base;425 return &const_instruction->base;
414}426}
415427
416static IrInstruction *ir_create_const_type(IrBuilder *irb, AstNode *source_node, TypeTableEntry *type_entry) {428static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
417 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, source_node);429 TypeTableEntry *type_entry)
430{
431 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb->exec, scope, source_node);
418 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_type;432 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_type;
419 const_instruction->base.static_value.special = ConstValSpecialStatic;433 const_instruction->base.static_value.special = ConstValSpecialStatic;
420 const_instruction->base.static_value.data.x_type = type_entry;434 const_instruction->base.static_value.data.x_type = type_entry;
421 return &const_instruction->base;435 return &const_instruction->base;
422}436}
423437
424static IrInstruction *ir_build_const_type(IrBuilder *irb, AstNode *source_node, TypeTableEntry *type_entry) {438static IrInstruction *ir_build_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
425 IrInstruction *instruction = ir_create_const_type(irb, source_node, type_entry);439 TypeTableEntry *type_entry)
440{
441 IrInstruction *instruction = ir_create_const_type(irb, scope, source_node, type_entry);
426 ir_instruction_append(irb->current_basic_block, instruction);442 ir_instruction_append(irb->current_basic_block, instruction);
427 return instruction;443 return instruction;
428}444}
429445
430static IrInstruction *ir_build_const_fn(IrBuilder *irb, AstNode *source_node, FnTableEntry *fn_entry) {446static IrInstruction *ir_build_const_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, FnTableEntry *fn_entry) {
431 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);447 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
432 const_instruction->base.type_entry = fn_entry->type_entry;448 const_instruction->base.type_entry = fn_entry->type_entry;
433 const_instruction->base.static_value.special = ConstValSpecialStatic;449 const_instruction->base.static_value.special = ConstValSpecialStatic;
434 const_instruction->base.static_value.data.x_fn = fn_entry;450 const_instruction->base.static_value.data.x_fn = fn_entry;
435 return &const_instruction->base;451 return &const_instruction->base;
436}452}
437453
438static IrInstruction *ir_build_const_generic_fn(IrBuilder *irb, AstNode *source_node, TypeTableEntry *fn_type) {454static IrInstruction *ir_build_const_import(IrBuilder *irb, Scope *scope, AstNode *source_node, ImportTableEntry *import) {
439 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);455 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
440 const_instruction->base.type_entry = fn_type;
441 const_instruction->base.static_value.special = ConstValSpecialStatic;
442 const_instruction->base.static_value.data.x_type = fn_type;
443 return &const_instruction->base;
444}
445
446static IrInstruction *ir_build_const_import(IrBuilder *irb, AstNode *source_node, ImportTableEntry *import) {
447 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);
448 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_namespace;456 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_namespace;
449 const_instruction->base.static_value.special = ConstValSpecialStatic;457 const_instruction->base.static_value.special = ConstValSpecialStatic;
450 const_instruction->base.static_value.data.x_import = import;458 const_instruction->base.static_value.data.x_import = import;
451 return &const_instruction->base;459 return &const_instruction->base;
452}460}
453461
454static IrInstruction *ir_build_const_scope(IrBuilder *irb, AstNode *source_node, Scope *scope) {462static IrInstruction *ir_build_const_scope(IrBuilder *irb, Scope *parent_scope, AstNode *source_node,
455 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);463 Scope *target_scope)
464{
465 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, parent_scope, source_node);
456 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_block;466 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_block;
457 const_instruction->base.static_value.special = ConstValSpecialStatic;467 const_instruction->base.static_value.special = ConstValSpecialStatic;
458 const_instruction->base.static_value.data.x_block = scope;468 const_instruction->base.static_value.data.x_block = target_scope;
459 return &const_instruction->base;469 return &const_instruction->base;
460}470}
461471
462static IrInstruction *ir_build_const_bool(IrBuilder *irb, AstNode *source_node, bool value) {472static IrInstruction *ir_build_const_bool(IrBuilder *irb, Scope *scope, AstNode *source_node, bool value) {
463 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);473 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
464 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_bool;474 const_instruction->base.type_entry = irb->codegen->builtin_types.entry_bool;
465 const_instruction->base.static_value.special = ConstValSpecialStatic;475 const_instruction->base.static_value.special = ConstValSpecialStatic;
466 const_instruction->base.static_value.data.x_bool = value;476 const_instruction->base.static_value.data.x_bool = value;
467 return &const_instruction->base;477 return &const_instruction->base;
468}478}
469479
470static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, AstNode *source_node,480static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, Scope *scope, AstNode *source_node,
471 FnTableEntry *fn_entry, IrInstruction *first_arg, bool depends_on_compile_var)481 FnTableEntry *fn_entry, IrInstruction *first_arg, bool depends_on_compile_var)
472{482{
473 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);483 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
474 const_instruction->base.type_entry = get_bound_fn_type(irb->codegen, fn_entry);484 const_instruction->base.type_entry = get_bound_fn_type(irb->codegen, fn_entry);
475 const_instruction->base.static_value.special = ConstValSpecialStatic;485 const_instruction->base.static_value.special = ConstValSpecialStatic;
476 const_instruction->base.static_value.depends_on_compile_var = depends_on_compile_var;486 const_instruction->base.static_value.depends_on_compile_var = depends_on_compile_var;
...@@ -479,8 +489,8 @@ static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, AstNode *source_no...@@ -479,8 +489,8 @@ static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, AstNode *source_no
479 return &const_instruction->base;489 return &const_instruction->base;
480}490}
481491
482static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, AstNode *source_node, Buf *str) {492static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) {
483 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);493 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
484 TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8;494 TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8;
485 TypeTableEntry *type_entry = get_array_type(irb->codegen, u8_type, buf_len(str));495 TypeTableEntry *type_entry = get_array_type(irb->codegen, u8_type, buf_len(str));
486 const_instruction->base.type_entry = type_entry;496 const_instruction->base.type_entry = type_entry;
...@@ -498,7 +508,7 @@ static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, AstNode *source_nod...@@ -498,7 +508,7 @@ static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, AstNode *source_nod
498 return &const_instruction->base;508 return &const_instruction->base;
499}509}
500510
501static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, AstNode *source_node, Buf *str) {511static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) {
502 // first we build the underlying array512 // first we build the underlying array
503 size_t len_with_null = buf_len(str) + 1;513 size_t len_with_null = buf_len(str) + 1;
504 ConstExprValue *array_val = allocate<ConstExprValue>(1);514 ConstExprValue *array_val = allocate<ConstExprValue>(1);
...@@ -515,7 +525,7 @@ static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, AstNode *source_n...@@ -515,7 +525,7 @@ static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, AstNode *source_n
515 bignum_init_unsigned(&null_char->data.x_bignum, 0);525 bignum_init_unsigned(&null_char->data.x_bignum, 0);
516526
517 // then make the pointer point to it527 // then make the pointer point to it
518 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, source_node);528 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
519 TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8;529 TypeTableEntry *u8_type = irb->codegen->builtin_types.entry_u8;
520 TypeTableEntry *type_entry = get_pointer_to_type(irb->codegen, u8_type, true);530 TypeTableEntry *type_entry = get_pointer_to_type(irb->codegen, u8_type, true);
521 const_instruction->base.type_entry = type_entry;531 const_instruction->base.type_entry = type_entry;
...@@ -528,10 +538,10 @@ static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, AstNode *source_n...@@ -528,10 +538,10 @@ static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, AstNode *source_n
528 return &const_instruction->base;538 return &const_instruction->base;
529}539}
530540
531static IrInstruction *ir_build_bin_op(IrBuilder *irb, AstNode *source_node, IrBinOp op_id,541static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id,
532 IrInstruction *op1, IrInstruction *op2)542 IrInstruction *op1, IrInstruction *op2)
533{543{
534 IrInstructionBinOp *bin_op_instruction = ir_build_instruction<IrInstructionBinOp>(irb, source_node);544 IrInstructionBinOp *bin_op_instruction = ir_build_instruction<IrInstructionBinOp>(irb, scope, source_node);
535 bin_op_instruction->op_id = op_id;545 bin_op_instruction->op_id = op_id;
536 bin_op_instruction->op1 = op1;546 bin_op_instruction->op1 = op1;
537 bin_op_instruction->op2 = op2;547 bin_op_instruction->op2 = op2;
...@@ -545,13 +555,14 @@ static IrInstruction *ir_build_bin_op(IrBuilder *irb, AstNode *source_node, IrBi...@@ -545,13 +555,14 @@ static IrInstruction *ir_build_bin_op(IrBuilder *irb, AstNode *source_node, IrBi
545static IrInstruction *ir_build_bin_op_from(IrBuilder *irb, IrInstruction *old_instruction, IrBinOp op_id,555static IrInstruction *ir_build_bin_op_from(IrBuilder *irb, IrInstruction *old_instruction, IrBinOp op_id,
546 IrInstruction *op1, IrInstruction *op2)556 IrInstruction *op1, IrInstruction *op2)
547{557{
548 IrInstruction *new_instruction = ir_build_bin_op(irb, old_instruction->source_node, op_id, op1, op2);558 IrInstruction *new_instruction = ir_build_bin_op(irb, old_instruction->scope,
559 old_instruction->source_node, op_id, op1, op2);
549 ir_link_new_instruction(new_instruction, old_instruction);560 ir_link_new_instruction(new_instruction, old_instruction);
550 return new_instruction;561 return new_instruction;
551}562}
552563
553static IrInstruction *ir_build_var_ptr(IrBuilder *irb, AstNode *source_node, VariableTableEntry *var) {564static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, VariableTableEntry *var) {
554 IrInstructionVarPtr *instruction = ir_build_instruction<IrInstructionVarPtr>(irb, source_node);565 IrInstructionVarPtr *instruction = ir_build_instruction<IrInstructionVarPtr>(irb, scope, source_node);
555 instruction->var = var;566 instruction->var = var;
556567
557 ir_ref_var(var);568 ir_ref_var(var);
...@@ -560,16 +571,16 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, AstNode *source_node, Var...@@ -560,16 +571,16 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, AstNode *source_node, Var
560}571}
561572
562static IrInstruction *ir_build_var_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, VariableTableEntry *var) {573static IrInstruction *ir_build_var_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, VariableTableEntry *var) {
563 IrInstruction *new_instruction = ir_build_var_ptr(irb, old_instruction->source_node, var);574 IrInstruction *new_instruction = ir_build_var_ptr(irb, old_instruction->scope, old_instruction->source_node, var);
564 ir_link_new_instruction(new_instruction, old_instruction);575 ir_link_new_instruction(new_instruction, old_instruction);
565 return new_instruction;576 return new_instruction;
566577
567}578}
568579
569static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, AstNode *source_node, IrInstruction *array_ptr,580static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr,
570 IrInstruction *elem_index, bool safety_check_on)581 IrInstruction *elem_index, bool safety_check_on)
571{582{
572 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, source_node);583 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node);
573 instruction->array_ptr = array_ptr;584 instruction->array_ptr = array_ptr;
574 instruction->elem_index = elem_index;585 instruction->elem_index = elem_index;
575 instruction->safety_check_on = safety_check_on;586 instruction->safety_check_on = safety_check_on;
...@@ -583,16 +594,16 @@ static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, AstNode *source_node, Ir...@@ -583,16 +594,16 @@ static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, AstNode *source_node, Ir
583static IrInstruction *ir_build_elem_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,594static IrInstruction *ir_build_elem_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,
584 IrInstruction *array_ptr, IrInstruction *elem_index, bool safety_check_on)595 IrInstruction *array_ptr, IrInstruction *elem_index, bool safety_check_on)
585{596{
586 IrInstruction *new_instruction = ir_build_elem_ptr(irb, old_instruction->source_node, array_ptr, elem_index,597 IrInstruction *new_instruction = ir_build_elem_ptr(irb, old_instruction->scope,
587 safety_check_on);598 old_instruction->source_node, array_ptr, elem_index, safety_check_on);
588 ir_link_new_instruction(new_instruction, old_instruction);599 ir_link_new_instruction(new_instruction, old_instruction);
589 return new_instruction;600 return new_instruction;
590}601}
591602
592static IrInstruction *ir_build_field_ptr(IrBuilder *irb, AstNode *source_node,603static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
593 IrInstruction *container_ptr, Buf *field_name)604 IrInstruction *container_ptr, Buf *field_name)
594{605{
595 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, source_node);606 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node);
596 instruction->container_ptr = container_ptr;607 instruction->container_ptr = container_ptr;
597 instruction->field_name = field_name;608 instruction->field_name = field_name;
598609
...@@ -601,10 +612,10 @@ static IrInstruction *ir_build_field_ptr(IrBuilder *irb, AstNode *source_node,...@@ -601,10 +612,10 @@ static IrInstruction *ir_build_field_ptr(IrBuilder *irb, AstNode *source_node,
601 return &instruction->base;612 return &instruction->base;
602}613}
603614
604static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, AstNode *source_node,615static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
605 IrInstruction *struct_ptr, TypeStructField *field)616 IrInstruction *struct_ptr, TypeStructField *field)
606{617{
607 IrInstructionStructFieldPtr *instruction = ir_build_instruction<IrInstructionStructFieldPtr>(irb, source_node);618 IrInstructionStructFieldPtr *instruction = ir_build_instruction<IrInstructionStructFieldPtr>(irb, scope, source_node);
608 instruction->struct_ptr = struct_ptr;619 instruction->struct_ptr = struct_ptr;
609 instruction->field = field;620 instruction->field = field;
610621
...@@ -616,16 +627,16 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, AstNode *source_...@@ -616,16 +627,16 @@ static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, AstNode *source_
616static IrInstruction *ir_build_struct_field_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,627static IrInstruction *ir_build_struct_field_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,
617 IrInstruction *struct_ptr, TypeStructField *type_struct_field)628 IrInstruction *struct_ptr, TypeStructField *type_struct_field)
618{629{
619 IrInstruction *new_instruction = ir_build_struct_field_ptr(irb, old_instruction->source_node,630 IrInstruction *new_instruction = ir_build_struct_field_ptr(irb, old_instruction->scope,
620 struct_ptr, type_struct_field);631 old_instruction->source_node, struct_ptr, type_struct_field);
621 ir_link_new_instruction(new_instruction, old_instruction);632 ir_link_new_instruction(new_instruction, old_instruction);
622 return new_instruction;633 return new_instruction;
623}634}
624635
625static IrInstruction *ir_build_enum_field_ptr(IrBuilder *irb, AstNode *source_node,636static IrInstruction *ir_build_enum_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
626 IrInstruction *enum_ptr, TypeEnumField *field)637 IrInstruction *enum_ptr, TypeEnumField *field)
627{638{
628 IrInstructionEnumFieldPtr *instruction = ir_build_instruction<IrInstructionEnumFieldPtr>(irb, source_node);639 IrInstructionEnumFieldPtr *instruction = ir_build_instruction<IrInstructionEnumFieldPtr>(irb, scope, source_node);
629 instruction->enum_ptr = enum_ptr;640 instruction->enum_ptr = enum_ptr;
630 instruction->field = field;641 instruction->field = field;
631642
...@@ -637,16 +648,16 @@ static IrInstruction *ir_build_enum_field_ptr(IrBuilder *irb, AstNode *source_no...@@ -637,16 +648,16 @@ static IrInstruction *ir_build_enum_field_ptr(IrBuilder *irb, AstNode *source_no
637static IrInstruction *ir_build_enum_field_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,648static IrInstruction *ir_build_enum_field_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,
638 IrInstruction *enum_ptr, TypeEnumField *type_enum_field)649 IrInstruction *enum_ptr, TypeEnumField *type_enum_field)
639{650{
640 IrInstruction *new_instruction = ir_build_enum_field_ptr(irb, old_instruction->source_node,651 IrInstruction *new_instruction = ir_build_enum_field_ptr(irb, old_instruction->scope,
641 enum_ptr, type_enum_field);652 old_instruction->source_node, enum_ptr, type_enum_field);
642 ir_link_new_instruction(new_instruction, old_instruction);653 ir_link_new_instruction(new_instruction, old_instruction);
643 return new_instruction;654 return new_instruction;
644}655}
645656
646static IrInstruction *ir_build_call(IrBuilder *irb, AstNode *source_node,657static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node,
647 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args)658 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args)
648{659{
649 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, source_node);660 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node);
650 call_instruction->fn_entry = fn_entry;661 call_instruction->fn_entry = fn_entry;
651 call_instruction->fn_ref = fn_ref;662 call_instruction->fn_ref = fn_ref;
652 call_instruction->arg_count = arg_count;663 call_instruction->arg_count = arg_count;
...@@ -663,18 +674,19 @@ static IrInstruction *ir_build_call(IrBuilder *irb, AstNode *source_node,...@@ -663,18 +674,19 @@ static IrInstruction *ir_build_call(IrBuilder *irb, AstNode *source_node,
663static IrInstruction *ir_build_call_from(IrBuilder *irb, IrInstruction *old_instruction,674static IrInstruction *ir_build_call_from(IrBuilder *irb, IrInstruction *old_instruction,
664 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args)675 FnTableEntry *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args)
665{676{
666 IrInstruction *new_instruction = ir_build_call(irb, old_instruction->source_node, fn_entry, fn_ref, arg_count, args);677 IrInstruction *new_instruction = ir_build_call(irb, old_instruction->scope,
678 old_instruction->source_node, fn_entry, fn_ref, arg_count, args);
667 ir_link_new_instruction(new_instruction, old_instruction);679 ir_link_new_instruction(new_instruction, old_instruction);
668 return new_instruction;680 return new_instruction;
669}681}
670682
671static IrInstruction *ir_build_phi(IrBuilder *irb, AstNode *source_node,683static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node,
672 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values)684 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values)
673{685{
674 assert(incoming_count != 0);686 assert(incoming_count != 0);
675 assert(incoming_count != SIZE_MAX);687 assert(incoming_count != SIZE_MAX);
676688
677 IrInstructionPhi *phi_instruction = ir_build_instruction<IrInstructionPhi>(irb, source_node);689 IrInstructionPhi *phi_instruction = ir_build_instruction<IrInstructionPhi>(irb, scope, source_node);
678 phi_instruction->incoming_count = incoming_count;690 phi_instruction->incoming_count = incoming_count;
679 phi_instruction->incoming_blocks = incoming_blocks;691 phi_instruction->incoming_blocks = incoming_blocks;
680 phi_instruction->incoming_values = incoming_values;692 phi_instruction->incoming_values = incoming_values;
...@@ -690,14 +702,16 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, AstNode *source_node,...@@ -690,14 +702,16 @@ static IrInstruction *ir_build_phi(IrBuilder *irb, AstNode *source_node,
690static IrInstruction *ir_build_phi_from(IrBuilder *irb, IrInstruction *old_instruction,702static IrInstruction *ir_build_phi_from(IrBuilder *irb, IrInstruction *old_instruction,
691 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values)703 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values)
692{704{
693 IrInstruction *new_instruction = ir_build_phi(irb, old_instruction->source_node,705 IrInstruction *new_instruction = ir_build_phi(irb, old_instruction->scope, old_instruction->source_node,
694 incoming_count, incoming_blocks, incoming_values);706 incoming_count, incoming_blocks, incoming_values);
695 ir_link_new_instruction(new_instruction, old_instruction);707 ir_link_new_instruction(new_instruction, old_instruction);
696 return new_instruction;708 return new_instruction;
697}709}
698710
699static IrInstruction *ir_create_br(IrBuilder *irb, AstNode *source_node, IrBasicBlock *dest_block, bool is_inline) {711static IrInstruction *ir_create_br(IrBuilder *irb, Scope *scope, AstNode *source_node,
700 IrInstructionBr *br_instruction = ir_create_instruction<IrInstructionBr>(irb->exec, source_node);712 IrBasicBlock *dest_block, bool is_inline)
713{
714 IrInstructionBr *br_instruction = ir_create_instruction<IrInstructionBr>(irb->exec, scope, source_node);
701 br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable;715 br_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable;
702 br_instruction->base.static_value.special = ConstValSpecialStatic;716 br_instruction->base.static_value.special = ConstValSpecialStatic;
703 br_instruction->dest_block = dest_block;717 br_instruction->dest_block = dest_block;
...@@ -708,20 +722,23 @@ static IrInstruction *ir_create_br(IrBuilder *irb, AstNode *source_node, IrBasic...@@ -708,20 +722,23 @@ static IrInstruction *ir_create_br(IrBuilder *irb, AstNode *source_node, IrBasic
708 return &br_instruction->base;722 return &br_instruction->base;
709}723}
710724
711static IrInstruction *ir_build_br(IrBuilder *irb, AstNode *source_node, IrBasicBlock *dest_block, bool is_inline) {725static IrInstruction *ir_build_br(IrBuilder *irb, Scope *scope, AstNode *source_node,
712 IrInstruction *instruction = ir_create_br(irb, source_node, dest_block, is_inline);726 IrBasicBlock *dest_block, bool is_inline)
727{
728 IrInstruction *instruction = ir_create_br(irb, scope, source_node, dest_block, is_inline);
713 ir_instruction_append(irb->current_basic_block, instruction);729 ir_instruction_append(irb->current_basic_block, instruction);
714 return instruction;730 return instruction;
715}731}
716732
717static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instruction, IrBasicBlock *dest_block) {733static IrInstruction *ir_build_br_from(IrBuilder *irb, IrInstruction *old_instruction, IrBasicBlock *dest_block) {
718 IrInstruction *new_instruction = ir_build_br(irb, old_instruction->source_node, dest_block, false);734 IrInstruction *new_instruction = ir_build_br(irb, old_instruction->scope,
735 old_instruction->source_node, dest_block, false);
719 ir_link_new_instruction(new_instruction, old_instruction);736 ir_link_new_instruction(new_instruction, old_instruction);
720 return new_instruction;737 return new_instruction;
721}738}
722739
723static IrInstruction *ir_build_un_op(IrBuilder *irb, AstNode *source_node, IrUnOp op_id, IrInstruction *value) {740static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, IrInstruction *value) {
724 IrInstructionUnOp *br_instruction = ir_build_instruction<IrInstructionUnOp>(irb, source_node);741 IrInstructionUnOp *br_instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node);
725 br_instruction->op_id = op_id;742 br_instruction->op_id = op_id;
726 br_instruction->value = value;743 br_instruction->value = value;
727744
...@@ -733,16 +750,17 @@ static IrInstruction *ir_build_un_op(IrBuilder *irb, AstNode *source_node, IrUnO...@@ -733,16 +750,17 @@ static IrInstruction *ir_build_un_op(IrBuilder *irb, AstNode *source_node, IrUnO
733static IrInstruction *ir_build_un_op_from(IrBuilder *irb, IrInstruction *old_instruction,750static IrInstruction *ir_build_un_op_from(IrBuilder *irb, IrInstruction *old_instruction,
734 IrUnOp op_id, IrInstruction *value)751 IrUnOp op_id, IrInstruction *value)
735{752{
736 IrInstruction *new_instruction = ir_build_un_op(irb, old_instruction->source_node, op_id, value);753 IrInstruction *new_instruction = ir_build_un_op(irb, old_instruction->scope,
754 old_instruction->source_node, op_id, value);
737 ir_link_new_instruction(new_instruction, old_instruction);755 ir_link_new_instruction(new_instruction, old_instruction);
738 return new_instruction;756 return new_instruction;
739}757}
740758
741static IrInstruction *ir_build_container_init_list(IrBuilder *irb, AstNode *source_node,759static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node,
742 IrInstruction *container_type, size_t item_count, IrInstruction **items)760 IrInstruction *container_type, size_t item_count, IrInstruction **items)
743{761{
744 IrInstructionContainerInitList *container_init_list_instruction =762 IrInstructionContainerInitList *container_init_list_instruction =
745 ir_build_instruction<IrInstructionContainerInitList>(irb, source_node);763 ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node);
746 container_init_list_instruction->container_type = container_type;764 container_init_list_instruction->container_type = container_type;
747 container_init_list_instruction->item_count = item_count;765 container_init_list_instruction->item_count = item_count;
748 container_init_list_instruction->items = items;766 container_init_list_instruction->items = items;
...@@ -758,17 +776,17 @@ static IrInstruction *ir_build_container_init_list(IrBuilder *irb, AstNode *sour...@@ -758,17 +776,17 @@ static IrInstruction *ir_build_container_init_list(IrBuilder *irb, AstNode *sour
758static IrInstruction *ir_build_container_init_list_from(IrBuilder *irb, IrInstruction *old_instruction,776static IrInstruction *ir_build_container_init_list_from(IrBuilder *irb, IrInstruction *old_instruction,
759 IrInstruction *container_type, size_t item_count, IrInstruction **items)777 IrInstruction *container_type, size_t item_count, IrInstruction **items)
760{778{
761 IrInstruction *new_instruction = ir_build_container_init_list(irb, old_instruction->source_node,779 IrInstruction *new_instruction = ir_build_container_init_list(irb, old_instruction->scope,
762 container_type, item_count, items);780 old_instruction->source_node, container_type, item_count, items);
763 ir_link_new_instruction(new_instruction, old_instruction);781 ir_link_new_instruction(new_instruction, old_instruction);
764 return new_instruction;782 return new_instruction;
765}783}
766784
767static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, AstNode *source_node,785static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node,
768 IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields)786 IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields)
769{787{
770 IrInstructionContainerInitFields *container_init_fields_instruction =788 IrInstructionContainerInitFields *container_init_fields_instruction =
771 ir_build_instruction<IrInstructionContainerInitFields>(irb, source_node);789 ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node);
772 container_init_fields_instruction->container_type = container_type;790 container_init_fields_instruction->container_type = container_type;
773 container_init_fields_instruction->field_count = field_count;791 container_init_fields_instruction->field_count = field_count;
774 container_init_fields_instruction->fields = fields;792 container_init_fields_instruction->fields = fields;
...@@ -781,10 +799,10 @@ static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, AstNode *so...@@ -781,10 +799,10 @@ static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, AstNode *so
781 return &container_init_fields_instruction->base;799 return &container_init_fields_instruction->base;
782}800}
783801
784static IrInstruction *ir_build_struct_init(IrBuilder *irb, AstNode *source_node,802static IrInstruction *ir_build_struct_init(IrBuilder *irb, Scope *scope, AstNode *source_node,
785 TypeTableEntry *struct_type, size_t field_count, IrInstructionStructInitField *fields)803 TypeTableEntry *struct_type, size_t field_count, IrInstructionStructInitField *fields)
786{804{
787 IrInstructionStructInit *struct_init_instruction = ir_build_instruction<IrInstructionStructInit>(irb, source_node);805 IrInstructionStructInit *struct_init_instruction = ir_build_instruction<IrInstructionStructInit>(irb, scope, source_node);
788 struct_init_instruction->struct_type = struct_type;806 struct_init_instruction->struct_type = struct_type;
789 struct_init_instruction->field_count = field_count;807 struct_init_instruction->field_count = field_count;
790 struct_init_instruction->fields = fields;808 struct_init_instruction->fields = fields;
...@@ -798,30 +816,30 @@ static IrInstruction *ir_build_struct_init(IrBuilder *irb, AstNode *source_node,...@@ -798,30 +816,30 @@ static IrInstruction *ir_build_struct_init(IrBuilder *irb, AstNode *source_node,
798static IrInstruction *ir_build_struct_init_from(IrBuilder *irb, IrInstruction *old_instruction,816static IrInstruction *ir_build_struct_init_from(IrBuilder *irb, IrInstruction *old_instruction,
799 TypeTableEntry *struct_type, size_t field_count, IrInstructionStructInitField *fields)817 TypeTableEntry *struct_type, size_t field_count, IrInstructionStructInitField *fields)
800{818{
801 IrInstruction *new_instruction = ir_build_struct_init(irb, old_instruction->source_node,819 IrInstruction *new_instruction = ir_build_struct_init(irb, old_instruction->scope,
802 struct_type, field_count, fields);820 old_instruction->source_node, struct_type, field_count, fields);
803 ir_link_new_instruction(new_instruction, old_instruction);821 ir_link_new_instruction(new_instruction, old_instruction);
804 return new_instruction;822 return new_instruction;
805}823}
806824
807static IrInstruction *ir_build_unreachable(IrBuilder *irb, AstNode *source_node) {825static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) {
808 IrInstructionUnreachable *unreachable_instruction =826 IrInstructionUnreachable *unreachable_instruction =
809 ir_build_instruction<IrInstructionUnreachable>(irb, source_node);827 ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node);
810 unreachable_instruction->base.static_value.special = ConstValSpecialStatic;828 unreachable_instruction->base.static_value.special = ConstValSpecialStatic;
811 unreachable_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable;829 unreachable_instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable;
812 return &unreachable_instruction->base;830 return &unreachable_instruction->base;
813}831}
814832
815static IrInstruction *ir_build_unreachable_from(IrBuilder *irb, IrInstruction *old_instruction) {833static IrInstruction *ir_build_unreachable_from(IrBuilder *irb, IrInstruction *old_instruction) {
816 IrInstruction *new_instruction = ir_build_unreachable(irb, old_instruction->source_node);834 IrInstruction *new_instruction = ir_build_unreachable(irb, old_instruction->scope, old_instruction->source_node);
817 ir_link_new_instruction(new_instruction, old_instruction);835 ir_link_new_instruction(new_instruction, old_instruction);
818 return new_instruction;836 return new_instruction;
819}837}
820838
821static IrInstruction *ir_build_store_ptr(IrBuilder *irb, AstNode *source_node,839static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
822 IrInstruction *ptr, IrInstruction *value)840 IrInstruction *ptr, IrInstruction *value)
823{841{
824 IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, source_node);842 IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node);
825 instruction->base.static_value.special = ConstValSpecialStatic;843 instruction->base.static_value.special = ConstValSpecialStatic;
826 instruction->base.type_entry = irb->codegen->builtin_types.entry_void;844 instruction->base.type_entry = irb->codegen->builtin_types.entry_void;
827 instruction->ptr = ptr;845 instruction->ptr = ptr;
...@@ -836,15 +854,16 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, AstNode *source_node,...@@ -836,15 +854,16 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, AstNode *source_node,
836static IrInstruction *ir_build_store_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,854static IrInstruction *ir_build_store_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,
837 IrInstruction *ptr, IrInstruction *value)855 IrInstruction *ptr, IrInstruction *value)
838{856{
839 IrInstruction *new_instruction = ir_build_store_ptr(irb, old_instruction->source_node, ptr, value);857 IrInstruction *new_instruction = ir_build_store_ptr(irb, old_instruction->scope,
858 old_instruction->source_node, ptr, value);
840 ir_link_new_instruction(new_instruction, old_instruction);859 ir_link_new_instruction(new_instruction, old_instruction);
841 return new_instruction;860 return new_instruction;
842}861}
843862
844static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node,863static IrInstruction *ir_build_var_decl(IrBuilder *irb, Scope *scope, AstNode *source_node,
845 VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value)864 VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value)
846{865{
847 IrInstructionDeclVar *decl_var_instruction = ir_build_instruction<IrInstructionDeclVar>(irb, source_node);866 IrInstructionDeclVar *decl_var_instruction = ir_build_instruction<IrInstructionDeclVar>(irb, scope, source_node);
848 decl_var_instruction->base.static_value.special = ConstValSpecialStatic;867 decl_var_instruction->base.static_value.special = ConstValSpecialStatic;
849 decl_var_instruction->base.type_entry = irb->codegen->builtin_types.entry_void;868 decl_var_instruction->base.type_entry = irb->codegen->builtin_types.entry_void;
850 decl_var_instruction->var = var;869 decl_var_instruction->var = var;
...@@ -860,13 +879,14 @@ static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node,...@@ -860,13 +879,14 @@ static IrInstruction *ir_build_var_decl(IrBuilder *irb, AstNode *source_node,
860static IrInstruction *ir_build_var_decl_from(IrBuilder *irb, IrInstruction *old_instruction,879static IrInstruction *ir_build_var_decl_from(IrBuilder *irb, IrInstruction *old_instruction,
861 VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value)880 VariableTableEntry *var, IrInstruction *var_type, IrInstruction *init_value)
862{881{
863 IrInstruction *new_instruction = ir_build_var_decl(irb, old_instruction->source_node, var, var_type, init_value);882 IrInstruction *new_instruction = ir_build_var_decl(irb, old_instruction->scope,
883 old_instruction->source_node, var, var_type, init_value);
864 ir_link_new_instruction(new_instruction, old_instruction);884 ir_link_new_instruction(new_instruction, old_instruction);
865 return new_instruction;885 return new_instruction;
866}886}
867887
868static IrInstruction *ir_build_load_ptr(IrBuilder *irb, AstNode *source_node, IrInstruction *ptr) {888static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) {
869 IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, source_node);889 IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, scope, source_node);
870 instruction->ptr = ptr;890 instruction->ptr = ptr;
871891
872 ir_ref_instruction(ptr);892 ir_ref_instruction(ptr);
...@@ -875,13 +895,14 @@ static IrInstruction *ir_build_load_ptr(IrBuilder *irb, AstNode *source_node, Ir...@@ -875,13 +895,14 @@ static IrInstruction *ir_build_load_ptr(IrBuilder *irb, AstNode *source_node, Ir
875}895}
876896
877static IrInstruction *ir_build_load_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *ptr) {897static IrInstruction *ir_build_load_ptr_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *ptr) {
878 IrInstruction *new_instruction = ir_build_load_ptr(irb, old_instruction->source_node, ptr);898 IrInstruction *new_instruction = ir_build_load_ptr(irb, old_instruction->scope,
899 old_instruction->source_node, ptr);
879 ir_link_new_instruction(new_instruction, old_instruction);900 ir_link_new_instruction(new_instruction, old_instruction);
880 return new_instruction;901 return new_instruction;
881}902}
882903
883static IrInstruction *ir_build_typeof(IrBuilder *irb, AstNode *source_node, IrInstruction *value) {904static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
884 IrInstructionTypeOf *instruction = ir_build_instruction<IrInstructionTypeOf>(irb, source_node);905 IrInstructionTypeOf *instruction = ir_build_instruction<IrInstructionTypeOf>(irb, scope, source_node);
885 instruction->value = value;906 instruction->value = value;
886907
887 ir_ref_instruction(value);908 ir_ref_instruction(value);
...@@ -889,8 +910,8 @@ static IrInstruction *ir_build_typeof(IrBuilder *irb, AstNode *source_node, IrIn...@@ -889,8 +910,8 @@ static IrInstruction *ir_build_typeof(IrBuilder *irb, AstNode *source_node, IrIn
889 return &instruction->base;910 return &instruction->base;
890}911}
891912
892static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, AstNode *source_node, IrInstruction *value) {913static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
893 IrInstructionToPtrType *instruction = ir_build_instruction<IrInstructionToPtrType>(irb, source_node);914 IrInstructionToPtrType *instruction = ir_build_instruction<IrInstructionToPtrType>(irb, scope, source_node);
894 instruction->value = value;915 instruction->value = value;
895916
896 ir_ref_instruction(value);917 ir_ref_instruction(value);
...@@ -898,8 +919,8 @@ static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, AstNode *source_node,...@@ -898,8 +919,8 @@ static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, AstNode *source_node,
898 return &instruction->base;919 return &instruction->base;
899}920}
900921
901static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, AstNode *source_node, IrInstruction *value) {922static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
902 IrInstructionPtrTypeChild *instruction = ir_build_instruction<IrInstructionPtrTypeChild>(irb, source_node);923 IrInstructionPtrTypeChild *instruction = ir_build_instruction<IrInstructionPtrTypeChild>(irb, scope, source_node);
903 instruction->value = value;924 instruction->value = value;
904925
905 ir_ref_instruction(value);926 ir_ref_instruction(value);
...@@ -907,10 +928,10 @@ static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, AstNode *source_no...@@ -907,10 +928,10 @@ static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, AstNode *source_no
907 return &instruction->base;928 return &instruction->base;
908}929}
909930
910static IrInstruction *ir_build_set_fn_test(IrBuilder *irb, AstNode *source_node, IrInstruction *fn_value,931static IrInstruction *ir_build_set_fn_test(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn_value,
911 IrInstruction *is_test)932 IrInstruction *is_test)
912{933{
913 IrInstructionSetFnTest *instruction = ir_build_instruction<IrInstructionSetFnTest>(irb, source_node);934 IrInstructionSetFnTest *instruction = ir_build_instruction<IrInstructionSetFnTest>(irb, scope, source_node);
914 instruction->fn_value = fn_value;935 instruction->fn_value = fn_value;
915 instruction->is_test = is_test;936 instruction->is_test = is_test;
916937
...@@ -920,10 +941,10 @@ static IrInstruction *ir_build_set_fn_test(IrBuilder *irb, AstNode *source_node,...@@ -920,10 +941,10 @@ static IrInstruction *ir_build_set_fn_test(IrBuilder *irb, AstNode *source_node,
920 return &instruction->base;941 return &instruction->base;
921}942}
922943
923static IrInstruction *ir_build_set_fn_visible(IrBuilder *irb, AstNode *source_node, IrInstruction *fn_value,944static IrInstruction *ir_build_set_fn_visible(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *fn_value,
924 IrInstruction *is_visible)945 IrInstruction *is_visible)
925{946{
926 IrInstructionSetFnVisible *instruction = ir_build_instruction<IrInstructionSetFnVisible>(irb, source_node);947 IrInstructionSetFnVisible *instruction = ir_build_instruction<IrInstructionSetFnVisible>(irb, scope, source_node);
927 instruction->fn_value = fn_value;948 instruction->fn_value = fn_value;
928 instruction->is_visible = is_visible;949 instruction->is_visible = is_visible;
929950
...@@ -933,10 +954,10 @@ static IrInstruction *ir_build_set_fn_visible(IrBuilder *irb, AstNode *source_no...@@ -933,10 +954,10 @@ static IrInstruction *ir_build_set_fn_visible(IrBuilder *irb, AstNode *source_no
933 return &instruction->base;954 return &instruction->base;
934}955}
935956
936static IrInstruction *ir_build_set_debug_safety(IrBuilder *irb, AstNode *source_node,957static IrInstruction *ir_build_set_debug_safety(IrBuilder *irb, Scope *scope, AstNode *source_node,
937 IrInstruction *scope_value, IrInstruction *debug_safety_on)958 IrInstruction *scope_value, IrInstruction *debug_safety_on)
938{959{
939 IrInstructionSetDebugSafety *instruction = ir_build_instruction<IrInstructionSetDebugSafety>(irb, source_node);960 IrInstructionSetDebugSafety *instruction = ir_build_instruction<IrInstructionSetDebugSafety>(irb, scope, source_node);
940 instruction->scope_value = scope_value;961 instruction->scope_value = scope_value;
941 instruction->debug_safety_on = debug_safety_on;962 instruction->debug_safety_on = debug_safety_on;
942963
...@@ -946,10 +967,10 @@ static IrInstruction *ir_build_set_debug_safety(IrBuilder *irb, AstNode *source_...@@ -946,10 +967,10 @@ static IrInstruction *ir_build_set_debug_safety(IrBuilder *irb, AstNode *source_
946 return &instruction->base;967 return &instruction->base;
947}968}
948969
949static IrInstruction *ir_build_array_type(IrBuilder *irb, AstNode *source_node, IrInstruction *size,970static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *size,
950 IrInstruction *child_type)971 IrInstruction *child_type)
951{972{
952 IrInstructionArrayType *instruction = ir_build_instruction<IrInstructionArrayType>(irb, source_node);973 IrInstructionArrayType *instruction = ir_build_instruction<IrInstructionArrayType>(irb, scope, source_node);
953 instruction->size = size;974 instruction->size = size;
954 instruction->child_type = child_type;975 instruction->child_type = child_type;
955976
...@@ -959,10 +980,10 @@ static IrInstruction *ir_build_array_type(IrBuilder *irb, AstNode *source_node,...@@ -959,10 +980,10 @@ static IrInstruction *ir_build_array_type(IrBuilder *irb, AstNode *source_node,
959 return &instruction->base;980 return &instruction->base;
960}981}
961982
962static IrInstruction *ir_build_slice_type(IrBuilder *irb, AstNode *source_node, bool is_const,983static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node, bool is_const,
963 IrInstruction *child_type)984 IrInstruction *child_type)
964{985{
965 IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, source_node);986 IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, scope, source_node);
966 instruction->is_const = is_const;987 instruction->is_const = is_const;
967 instruction->child_type = child_type;988 instruction->child_type = child_type;
968989
...@@ -971,12 +992,13 @@ static IrInstruction *ir_build_slice_type(IrBuilder *irb, AstNode *source_node,...@@ -971,12 +992,13 @@ static IrInstruction *ir_build_slice_type(IrBuilder *irb, AstNode *source_node,
971 return &instruction->base;992 return &instruction->base;
972}993}
973994
974static IrInstruction *ir_build_asm(IrBuilder *irb, AstNode *source_node, IrInstruction **input_list,995static IrInstruction *ir_build_asm(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction **input_list,
975 IrInstruction **output_types, size_t return_count, bool has_side_effects)996 IrInstruction **output_types, VariableTableEntry **output_vars, size_t return_count, bool has_side_effects)
976{997{
977 IrInstructionAsm *instruction = ir_build_instruction<IrInstructionAsm>(irb, source_node);998 IrInstructionAsm *instruction = ir_build_instruction<IrInstructionAsm>(irb, scope, source_node);
978 instruction->input_list = input_list;999 instruction->input_list = input_list;
979 instruction->output_types = output_types;1000 instruction->output_types = output_types;
1001 instruction->output_vars = output_vars;
980 instruction->return_count = return_count;1002 instruction->return_count = return_count;
981 instruction->has_side_effects = has_side_effects;1003 instruction->has_side_effects = has_side_effects;
9821004
...@@ -995,16 +1017,16 @@ static IrInstruction *ir_build_asm(IrBuilder *irb, AstNode *source_node, IrInstr...@@ -995,16 +1017,16 @@ static IrInstruction *ir_build_asm(IrBuilder *irb, AstNode *source_node, IrInstr
995}1017}
9961018
997static IrInstruction *ir_build_asm_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction **input_list,1019static IrInstruction *ir_build_asm_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction **input_list,
998 IrInstruction **output_types, size_t return_count, bool has_side_effects)1020 IrInstruction **output_types, VariableTableEntry **output_vars, size_t return_count, bool has_side_effects)
999{1021{
1000 IrInstruction *new_instruction = ir_build_asm(irb, old_instruction->source_node, input_list, output_types,1022 IrInstruction *new_instruction = ir_build_asm(irb, old_instruction->scope,
1001 return_count, has_side_effects);1023 old_instruction->source_node, input_list, output_types, output_vars, return_count, has_side_effects);
1002 ir_link_new_instruction(new_instruction, old_instruction);1024 ir_link_new_instruction(new_instruction, old_instruction);
1003 return new_instruction;1025 return new_instruction;
1004}1026}
10051027
1006static IrInstruction *ir_build_compile_var(IrBuilder *irb, AstNode *source_node, IrInstruction *name) {1028static IrInstruction *ir_build_compile_var(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) {
1007 IrInstructionCompileVar *instruction = ir_build_instruction<IrInstructionCompileVar>(irb, source_node);1029 IrInstructionCompileVar *instruction = ir_build_instruction<IrInstructionCompileVar>(irb, scope, source_node);
1008 instruction->name = name;1030 instruction->name = name;
10091031
1010 ir_ref_instruction(name);1032 ir_ref_instruction(name);
...@@ -1012,8 +1034,8 @@ static IrInstruction *ir_build_compile_var(IrBuilder *irb, AstNode *source_node,...@@ -1012,8 +1034,8 @@ static IrInstruction *ir_build_compile_var(IrBuilder *irb, AstNode *source_node,
1012 return &instruction->base;1034 return &instruction->base;
1013}1035}
10141036
1015static IrInstruction *ir_build_size_of(IrBuilder *irb, AstNode *source_node, IrInstruction *type_value) {1037static IrInstruction *ir_build_size_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) {
1016 IrInstructionSizeOf *instruction = ir_build_instruction<IrInstructionSizeOf>(irb, source_node);1038 IrInstructionSizeOf *instruction = ir_build_instruction<IrInstructionSizeOf>(irb, scope, source_node);
1017 instruction->type_value = type_value;1039 instruction->type_value = type_value;
10181040
1019 ir_ref_instruction(type_value);1041 ir_ref_instruction(type_value);
...@@ -1021,8 +1043,8 @@ static IrInstruction *ir_build_size_of(IrBuilder *irb, AstNode *source_node, IrI...@@ -1021,8 +1043,8 @@ static IrInstruction *ir_build_size_of(IrBuilder *irb, AstNode *source_node, IrI
1021 return &instruction->base;1043 return &instruction->base;
1022}1044}
10231045
1024static IrInstruction *ir_build_test_null(IrBuilder *irb, AstNode *source_node, IrInstruction *value) {1046static IrInstruction *ir_build_test_null(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1025 IrInstructionTestNull *instruction = ir_build_instruction<IrInstructionTestNull>(irb, source_node);1047 IrInstructionTestNull *instruction = ir_build_instruction<IrInstructionTestNull>(irb, scope, source_node);
1026 instruction->value = value;1048 instruction->value = value;
10271049
1028 ir_ref_instruction(value);1050 ir_ref_instruction(value);
...@@ -1033,15 +1055,16 @@ static IrInstruction *ir_build_test_null(IrBuilder *irb, AstNode *source_node, I...@@ -1033,15 +1055,16 @@ static IrInstruction *ir_build_test_null(IrBuilder *irb, AstNode *source_node, I
1033static IrInstruction *ir_build_test_null_from(IrBuilder *irb, IrInstruction *old_instruction,1055static IrInstruction *ir_build_test_null_from(IrBuilder *irb, IrInstruction *old_instruction,
1034 IrInstruction *value)1056 IrInstruction *value)
1035{1057{
1036 IrInstruction *new_instruction = ir_build_test_null(irb, old_instruction->source_node, value);1058 IrInstruction *new_instruction = ir_build_test_null(irb, old_instruction->scope,
1059 old_instruction->source_node, value);
1037 ir_link_new_instruction(new_instruction, old_instruction);1060 ir_link_new_instruction(new_instruction, old_instruction);
1038 return new_instruction;1061 return new_instruction;
1039}1062}
10401063
1041static IrInstruction *ir_build_unwrap_maybe(IrBuilder *irb, AstNode *source_node, IrInstruction *value,1064static IrInstruction *ir_build_unwrap_maybe(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value,
1042 bool safety_check_on)1065 bool safety_check_on)
1043{1066{
1044 IrInstructionUnwrapMaybe *instruction = ir_build_instruction<IrInstructionUnwrapMaybe>(irb, source_node);1067 IrInstructionUnwrapMaybe *instruction = ir_build_instruction<IrInstructionUnwrapMaybe>(irb, scope, source_node);
1045 instruction->value = value;1068 instruction->value = value;
1046 instruction->safety_check_on = safety_check_on;1069 instruction->safety_check_on = safety_check_on;
10471070
...@@ -1053,14 +1076,14 @@ static IrInstruction *ir_build_unwrap_maybe(IrBuilder *irb, AstNode *source_node...@@ -1053,14 +1076,14 @@ static IrInstruction *ir_build_unwrap_maybe(IrBuilder *irb, AstNode *source_node
1053static IrInstruction *ir_build_unwrap_maybe_from(IrBuilder *irb, IrInstruction *old_instruction,1076static IrInstruction *ir_build_unwrap_maybe_from(IrBuilder *irb, IrInstruction *old_instruction,
1054 IrInstruction *value, bool safety_check_on)1077 IrInstruction *value, bool safety_check_on)
1055{1078{
1056 IrInstruction *new_instruction = ir_build_unwrap_maybe(irb, old_instruction->source_node,1079 IrInstruction *new_instruction = ir_build_unwrap_maybe(irb, old_instruction->scope, old_instruction->source_node,
1057 value, safety_check_on);1080 value, safety_check_on);
1058 ir_link_new_instruction(new_instruction, old_instruction);1081 ir_link_new_instruction(new_instruction, old_instruction);
1059 return new_instruction;1082 return new_instruction;
1060}1083}
10611084
1062static IrInstruction *ir_build_clz(IrBuilder *irb, AstNode *source_node, IrInstruction *value) {1085static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1063 IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, source_node);1086 IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, scope, source_node);
1064 instruction->value = value;1087 instruction->value = value;
10651088
1066 ir_ref_instruction(value);1089 ir_ref_instruction(value);
...@@ -1069,13 +1092,13 @@ static IrInstruction *ir_build_clz(IrBuilder *irb, AstNode *source_node, IrInstr...@@ -1069,13 +1092,13 @@ static IrInstruction *ir_build_clz(IrBuilder *irb, AstNode *source_node, IrInstr
1069}1092}
10701093
1071static IrInstruction *ir_build_clz_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) {1094static IrInstruction *ir_build_clz_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) {
1072 IrInstruction *new_instruction = ir_build_clz(irb, old_instruction->source_node, value);1095 IrInstruction *new_instruction = ir_build_clz(irb, old_instruction->scope, old_instruction->source_node, value);
1073 ir_link_new_instruction(new_instruction, old_instruction);1096 ir_link_new_instruction(new_instruction, old_instruction);
1074 return new_instruction;1097 return new_instruction;
1075}1098}
10761099
1077static IrInstruction *ir_build_ctz(IrBuilder *irb, AstNode *source_node, IrInstruction *value) {1100static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1078 IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, source_node);1101 IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, scope, source_node);
1079 instruction->value = value;1102 instruction->value = value;
10801103
1081 ir_ref_instruction(value);1104 ir_ref_instruction(value);
...@@ -1084,15 +1107,15 @@ static IrInstruction *ir_build_ctz(IrBuilder *irb, AstNode *source_node, IrInstr...@@ -1084,15 +1107,15 @@ static IrInstruction *ir_build_ctz(IrBuilder *irb, AstNode *source_node, IrInstr
1084}1107}
10851108
1086static IrInstruction *ir_build_ctz_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) {1109static IrInstruction *ir_build_ctz_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) {
1087 IrInstruction *new_instruction = ir_build_ctz(irb, old_instruction->source_node, value);1110 IrInstruction *new_instruction = ir_build_ctz(irb, old_instruction->scope, old_instruction->source_node, value);
1088 ir_link_new_instruction(new_instruction, old_instruction);1111 ir_link_new_instruction(new_instruction, old_instruction);
1089 return new_instruction;1112 return new_instruction;
1090}1113}
10911114
1092static IrInstruction *ir_build_switch_br(IrBuilder *irb, AstNode *source_node, IrInstruction *target_value,1115static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value,
1093 IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, bool is_inline)1116 IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, bool is_inline)
1094{1117{
1095 IrInstructionSwitchBr *instruction = ir_build_instruction<IrInstructionSwitchBr>(irb, source_node);1118 IrInstructionSwitchBr *instruction = ir_build_instruction<IrInstructionSwitchBr>(irb, scope, source_node);
1096 instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable;1119 instruction->base.type_entry = irb->codegen->builtin_types.entry_unreachable;
1097 instruction->base.static_value.special = ConstValSpecialStatic;1120 instruction->base.static_value.special = ConstValSpecialStatic;
1098 instruction->target_value = target_value;1121 instruction->target_value = target_value;
...@@ -1116,16 +1139,16 @@ static IrInstruction *ir_build_switch_br_from(IrBuilder *irb, IrInstruction *old...@@ -1116,16 +1139,16 @@ static IrInstruction *ir_build_switch_br_from(IrBuilder *irb, IrInstruction *old
1116 IrInstruction *target_value, IrBasicBlock *else_block, size_t case_count,1139 IrInstruction *target_value, IrBasicBlock *else_block, size_t case_count,
1117 IrInstructionSwitchBrCase *cases, bool is_inline)1140 IrInstructionSwitchBrCase *cases, bool is_inline)
1118{1141{
1119 IrInstruction *new_instruction = ir_build_switch_br(irb, old_instruction->source_node,1142 IrInstruction *new_instruction = ir_build_switch_br(irb, old_instruction->scope, old_instruction->source_node,
1120 target_value, else_block, case_count, cases, is_inline);1143 target_value, else_block, case_count, cases, is_inline);
1121 ir_link_new_instruction(new_instruction, old_instruction);1144 ir_link_new_instruction(new_instruction, old_instruction);
1122 return new_instruction;1145 return new_instruction;
1123}1146}
11241147
1125static IrInstruction *ir_build_switch_target(IrBuilder *irb, AstNode *source_node,1148static IrInstruction *ir_build_switch_target(IrBuilder *irb, Scope *scope, AstNode *source_node,
1126 IrInstruction *target_value_ptr)1149 IrInstruction *target_value_ptr)
1127{1150{
1128 IrInstructionSwitchTarget *instruction = ir_build_instruction<IrInstructionSwitchTarget>(irb, source_node);1151 IrInstructionSwitchTarget *instruction = ir_build_instruction<IrInstructionSwitchTarget>(irb, scope, source_node);
1129 instruction->target_value_ptr = target_value_ptr;1152 instruction->target_value_ptr = target_value_ptr;
11301153
1131 ir_ref_instruction(target_value_ptr);1154 ir_ref_instruction(target_value_ptr);
...@@ -1133,10 +1156,10 @@ static IrInstruction *ir_build_switch_target(IrBuilder *irb, AstNode *source_nod...@@ -1133,10 +1156,10 @@ static IrInstruction *ir_build_switch_target(IrBuilder *irb, AstNode *source_nod
1133 return &instruction->base;1156 return &instruction->base;
1134}1157}
11351158
1136static IrInstruction *ir_build_switch_var(IrBuilder *irb, AstNode *source_node,1159static IrInstruction *ir_build_switch_var(IrBuilder *irb, Scope *scope, AstNode *source_node,
1137 IrInstruction *target_value_ptr, IrInstruction *prong_value)1160 IrInstruction *target_value_ptr, IrInstruction *prong_value)
1138{1161{
1139 IrInstructionSwitchVar *instruction = ir_build_instruction<IrInstructionSwitchVar>(irb, source_node);1162 IrInstructionSwitchVar *instruction = ir_build_instruction<IrInstructionSwitchVar>(irb, scope, source_node);
1140 instruction->target_value_ptr = target_value_ptr;1163 instruction->target_value_ptr = target_value_ptr;
1141 instruction->prong_value = prong_value;1164 instruction->prong_value = prong_value;
11421165
...@@ -1146,8 +1169,8 @@ static IrInstruction *ir_build_switch_var(IrBuilder *irb, AstNode *source_node,...@@ -1146,8 +1169,8 @@ static IrInstruction *ir_build_switch_var(IrBuilder *irb, AstNode *source_node,
1146 return &instruction->base;1169 return &instruction->base;
1147}1170}
11481171
1149static IrInstruction *ir_build_enum_tag(IrBuilder *irb, AstNode *source_node, IrInstruction *value) {1172static IrInstruction *ir_build_enum_tag(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1150 IrInstructionEnumTag *instruction = ir_build_instruction<IrInstructionEnumTag>(irb, source_node);1173 IrInstructionEnumTag *instruction = ir_build_instruction<IrInstructionEnumTag>(irb, scope, source_node);
1151 instruction->value = value;1174 instruction->value = value;
11521175
1153 ir_ref_instruction(value);1176 ir_ref_instruction(value);
...@@ -1156,13 +1179,14 @@ static IrInstruction *ir_build_enum_tag(IrBuilder *irb, AstNode *source_node, Ir...@@ -1156,13 +1179,14 @@ static IrInstruction *ir_build_enum_tag(IrBuilder *irb, AstNode *source_node, Ir
1156}1179}
11571180
1158static IrInstruction *ir_build_enum_tag_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) {1181static IrInstruction *ir_build_enum_tag_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) {
1159 IrInstruction *new_instruction = ir_build_enum_tag(irb, old_instruction->source_node, value);1182 IrInstruction *new_instruction = ir_build_enum_tag(irb, old_instruction->scope,
1183 old_instruction->source_node, value);
1160 ir_link_new_instruction(new_instruction, old_instruction);1184 ir_link_new_instruction(new_instruction, old_instruction);
1161 return new_instruction;1185 return new_instruction;
1162}1186}
11631187
1164static IrInstruction *ir_build_static_eval(IrBuilder *irb, AstNode *source_node, IrInstruction *value) {1188static IrInstruction *ir_build_static_eval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1165 IrInstructionStaticEval *instruction = ir_build_instruction<IrInstructionStaticEval>(irb, source_node);1189 IrInstructionStaticEval *instruction = ir_build_instruction<IrInstructionStaticEval>(irb, scope, source_node);
1166 instruction->value = value;1190 instruction->value = value;
11671191
1168 ir_ref_instruction(value);1192 ir_ref_instruction(value);
...@@ -1170,8 +1194,8 @@ static IrInstruction *ir_build_static_eval(IrBuilder *irb, AstNode *source_node,...@@ -1170,8 +1194,8 @@ static IrInstruction *ir_build_static_eval(IrBuilder *irb, AstNode *source_node,
1170 return &instruction->base;1194 return &instruction->base;
1171}1195}
11721196
1173static IrInstruction *ir_build_import(IrBuilder *irb, AstNode *source_node, IrInstruction *name) {1197static IrInstruction *ir_build_import(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) {
1174 IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, source_node);1198 IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, scope, source_node);
1175 instruction->name = name;1199 instruction->name = name;
11761200
1177 ir_ref_instruction(name);1201 ir_ref_instruction(name);
...@@ -1179,8 +1203,8 @@ static IrInstruction *ir_build_import(IrBuilder *irb, AstNode *source_node, IrIn...@@ -1179,8 +1203,8 @@ static IrInstruction *ir_build_import(IrBuilder *irb, AstNode *source_node, IrIn
1179 return &instruction->base;1203 return &instruction->base;
1180}1204}
11811205
1182static IrInstruction *ir_build_array_len(IrBuilder *irb, AstNode *source_node, IrInstruction *array_value) {1206static IrInstruction *ir_build_array_len(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_value) {
1183 IrInstructionArrayLen *instruction = ir_build_instruction<IrInstructionArrayLen>(irb, source_node);1207 IrInstructionArrayLen *instruction = ir_build_instruction<IrInstructionArrayLen>(irb, scope, source_node);
1184 instruction->array_value = array_value;1208 instruction->array_value = array_value;
11851209
1186 ir_ref_instruction(array_value);1210 ir_ref_instruction(array_value);
...@@ -1191,13 +1215,14 @@ static IrInstruction *ir_build_array_len(IrBuilder *irb, AstNode *source_node, I...@@ -1191,13 +1215,14 @@ static IrInstruction *ir_build_array_len(IrBuilder *irb, AstNode *source_node, I
1191static IrInstruction *ir_build_array_len_from(IrBuilder *irb, IrInstruction *old_instruction,1215static IrInstruction *ir_build_array_len_from(IrBuilder *irb, IrInstruction *old_instruction,
1192 IrInstruction *array_value)1216 IrInstruction *array_value)
1193{1217{
1194 IrInstruction *new_instruction = ir_build_array_len(irb, old_instruction->source_node, array_value);1218 IrInstruction *new_instruction = ir_build_array_len(irb, old_instruction->scope,
1219 old_instruction->source_node, array_value);
1195 ir_link_new_instruction(new_instruction, old_instruction);1220 ir_link_new_instruction(new_instruction, old_instruction);
1196 return new_instruction;1221 return new_instruction;
1197}1222}
11981223
1199static IrInstruction *ir_build_ref(IrBuilder *irb, AstNode *source_node, IrInstruction *value) {1224static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
1200 IrInstructionRef *instruction = ir_build_instruction<IrInstructionRef>(irb, source_node);1225 IrInstructionRef *instruction = ir_build_instruction<IrInstructionRef>(irb, scope, source_node);
1201 instruction->value = value;1226 instruction->value = value;
12021227
1203 ir_ref_instruction(value);1228 ir_ref_instruction(value);
...@@ -1206,12 +1231,12 @@ static IrInstruction *ir_build_ref(IrBuilder *irb, AstNode *source_node, IrInstr...@@ -1206,12 +1231,12 @@ static IrInstruction *ir_build_ref(IrBuilder *irb, AstNode *source_node, IrInstr
1206}1231}
12071232
1208static IrInstruction *ir_build_ref_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) {1233static IrInstruction *ir_build_ref_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) {
1209 IrInstruction *new_instruction = ir_build_ref(irb, old_instruction->source_node, value);1234 IrInstruction *new_instruction = ir_build_ref(irb, old_instruction->scope, old_instruction->source_node, value);
1210 ir_link_new_instruction(new_instruction, old_instruction);1235 ir_link_new_instruction(new_instruction, old_instruction);
1211 return new_instruction;1236 return new_instruction;
1212}1237}
12131238
1214static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope,1239static void ir_gen_defers_for_block(IrBuilder *irb, Scope *parent_scope, Scope *inner_scope, Scope *outer_scope,
1215 bool gen_error_defers, bool gen_maybe_defers)1240 bool gen_error_defers, bool gen_maybe_defers)
1216{1241{
1217 while (inner_scope != outer_scope) {1242 while (inner_scope != outer_scope) {
...@@ -1221,29 +1246,16 @@ static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o...@@ -1221,29 +1246,16 @@ static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o
1221 (gen_maybe_defers && inner_scope->node->data.defer.kind == ReturnKindMaybe)))1246 (gen_maybe_defers && inner_scope->node->data.defer.kind == ReturnKindMaybe)))
1222 {1247 {
1223 AstNode *defer_expr_node = inner_scope->node->data.defer.expr;1248 AstNode *defer_expr_node = inner_scope->node->data.defer.expr;
1224 ir_gen_node(irb, defer_expr_node, defer_expr_node->scope);1249 ir_gen_node(irb, defer_expr_node, parent_scope);
1225 }1250 }
1226 inner_scope = inner_scope->parent;1251 inner_scope = inner_scope->parent;
1227 }1252 }
1228}1253}
12291254
1230static FnTableEntry *scope_fn_entry(Scope *scope) {1255static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node) {
1231 while (scope) {
1232 if (scope->node->type == NodeTypeFnDef) {
1233 ScopeFnBody *fn_scope = (ScopeFnBody *)scope;
1234 return fn_scope->fn_entry;
1235 }
1236 scope = scope->parent;
1237 }
1238 return nullptr;
1239}
1240
1241static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) {
1242 assert(node->type == NodeTypeReturnExpr);1256 assert(node->type == NodeTypeReturnExpr);
12431257
1244 Scope *scope = node->scope;1258 if (!exec_fn_entry(irb->exec)) {
1245
1246 if (!scope_fn_entry(scope)) {
1247 add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition"));1259 add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition"));
1248 return irb->codegen->invalid_instruction;1260 return irb->codegen->invalid_instruction;
1249 }1261 }
...@@ -1254,12 +1266,12 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) {...@@ -1254,12 +1266,12 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, AstNode *node) {
1254 {1266 {
1255 IrInstruction *return_value;1267 IrInstruction *return_value;
1256 if (expr_node) {1268 if (expr_node) {
1257 return_value = ir_gen_node(irb, expr_node, node->scope);1269 return_value = ir_gen_node(irb, expr_node, scope);
1258 } else {1270 } else {
1259 return_value = ir_build_const_void(irb, node);1271 return_value = ir_build_const_void(irb, scope, node);
1260 }1272 }
12611273
1262 return ir_build_return(irb, node, return_value);1274 return ir_build_return(irb, scope, node, return_value);
1263 }1275 }
1264 case ReturnKindError:1276 case ReturnKindError:
1265 zig_panic("TODO gen IR for %%return");1277 zig_panic("TODO gen IR for %%return");
...@@ -1275,15 +1287,15 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) {...@@ -1275,15 +1287,15 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) {
1275 irb->current_basic_block = basic_block;1287 irb->current_basic_block = basic_block;
1276}1288}
12771289
1278static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,1290static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
1279 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline)1291 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline)
1280{1292{
1281 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);1293 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);
1282 variable_entry->parent_scope = parent_scope;1294 variable_entry->parent_scope = parent_scope;
1283 variable_entry->import = node->owner;
1284 variable_entry->shadowable = is_shadowable;1295 variable_entry->shadowable = is_shadowable;
1285 variable_entry->mem_slot_index = SIZE_MAX;1296 variable_entry->mem_slot_index = SIZE_MAX;
1286 variable_entry->is_inline = is_inline;1297 variable_entry->is_inline = is_inline;
1298 variable_entry->src_arg_index = SIZE_MAX;
12871299
1288 if (name) {1300 if (name) {
1289 buf_init_from_buf(&variable_entry->name, name);1301 buf_init_from_buf(&variable_entry->name, name);
...@@ -1302,11 +1314,11 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope...@@ -1302,11 +1314,11 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope
1302 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));1314 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));
1303 variable_entry->type = codegen->builtin_types.entry_invalid;1315 variable_entry->type = codegen->builtin_types.entry_invalid;
1304 } else {1316 } else {
1305 AstNode *decl_node = find_decl(parent_scope, name);1317 Tld *tld = find_decl(parent_scope, name);
1306 if (decl_node && decl_node->type != NodeTypeVariableDeclaration) {1318 if (tld && tld->id != TldIdVar) {
1307 ErrorMsg *msg = add_node_error(codegen, node,1319 ErrorMsg *msg = add_node_error(codegen, node,
1308 buf_sprintf("redefinition of '%s'", buf_ptr(name)));1320 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
1309 add_error_note(codegen, msg, decl_node, buf_sprintf("previous definition is here"));1321 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here"));
1310 variable_entry->type = codegen->builtin_types.entry_invalid;1322 variable_entry->type = codegen->builtin_types.entry_invalid;
1311 }1323 }
1312 }1324 }
...@@ -1333,7 +1345,7 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope...@@ -1333,7 +1345,7 @@ static VariableTableEntry *add_local_var(CodeGen *codegen, AstNode *node, Scope
1333static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name,1345static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name,
1334 bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline)1346 bool src_is_const, bool gen_is_const, bool is_shadowable, bool is_inline)
1335{1347{
1336 VariableTableEntry *var = add_local_var(irb->codegen, node, scope, name,1348 VariableTableEntry *var = create_local_var(irb->codegen, node, scope, name,
1337 src_is_const, gen_is_const, is_shadowable, is_inline);1349 src_is_const, gen_is_const, is_shadowable, is_inline);
1338 if (is_inline || gen_is_const)1350 if (is_inline || gen_is_const)
1339 var->mem_slot_index = exec_next_mem_slot(irb->exec);1351 var->mem_slot_index = exec_next_mem_slot(irb->exec);
...@@ -1341,10 +1353,9 @@ static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *s...@@ -1341,10 +1353,9 @@ static VariableTableEntry *ir_create_var(IrBuilder *irb, AstNode *node, Scope *s
1341 return var;1353 return var;
1342}1354}
13431355
1344static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) {1356static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) {
1345 assert(block_node->type == NodeTypeBlock);1357 assert(block_node->type == NodeTypeBlock);
13461358
1347 Scope *parent_scope = block_node->scope;
1348 Scope *outer_block_scope = create_block_scope(block_node, parent_scope);1359 Scope *outer_block_scope = create_block_scope(block_node, parent_scope);
1349 Scope *child_scope = outer_block_scope;1360 Scope *child_scope = outer_block_scope;
13501361
...@@ -1353,56 +1364,57 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) {...@@ -1353,56 +1364,57 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, AstNode *block_node) {
1353 AstNode *statement_node = block_node->data.block.statements.at(i);1364 AstNode *statement_node = block_node->data.block.statements.at(i);
1354 return_value = ir_gen_node(irb, statement_node, child_scope);1365 return_value = ir_gen_node(irb, statement_node, child_scope);
1355 if (statement_node->type == NodeTypeDefer && return_value != irb->codegen->invalid_instruction) {1366 if (statement_node->type == NodeTypeDefer && return_value != irb->codegen->invalid_instruction) {
1356 // defer starts a new block context1367 // defer starts a new scope
1357 child_scope = statement_node->data.defer.child_block;1368 child_scope = statement_node->data.defer.child_scope;
1358 assert(child_scope);1369 assert(child_scope);
1359 } else if (return_value->id == IrInstructionIdDeclVar) {1370 } else if (return_value->id == IrInstructionIdDeclVar) {
1371 // variable declarations start a new scope
1360 IrInstructionDeclVar *decl_var_instruction = (IrInstructionDeclVar *)return_value;1372 IrInstructionDeclVar *decl_var_instruction = (IrInstructionDeclVar *)return_value;
1361 child_scope = decl_var_instruction->var->child_scope;1373 child_scope = decl_var_instruction->var->child_scope;
1362 }1374 }
1363 }1375 }
13641376
1365 if (!return_value)1377 if (!return_value)
1366 return_value = ir_build_const_void(irb, block_node);1378 return_value = ir_build_const_void(irb, child_scope, block_node);
13671379
1368 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false, false);1380 ir_gen_defers_for_block(irb, parent_scope, child_scope, outer_block_scope, false, false);
13691381
1370 return return_value;1382 return return_value;
1371}1383}
13721384
1373static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, AstNode *node, IrBinOp op_id) {1385static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) {
1374 IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, node->scope);1386 IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope);
1375 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, node->scope);1387 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
1376 return ir_build_bin_op(irb, node, op_id, op1, op2);1388 return ir_build_bin_op(irb, scope, node, op_id, op1, op2);
1377}1389}
13781390
1379static IrInstruction *ir_gen_assign(IrBuilder *irb, AstNode *node) {1391static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) {
1380 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, node->scope, LValPurposeAssign);1392 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPurposeAssign);
1381 if (lvalue == irb->codegen->invalid_instruction)1393 if (lvalue == irb->codegen->invalid_instruction)
1382 return lvalue;1394 return lvalue;
13831395
1384 IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, node->scope);1396 IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
1385 if (rvalue == irb->codegen->invalid_instruction)1397 if (rvalue == irb->codegen->invalid_instruction)
1386 return rvalue;1398 return rvalue;
13871399
1388 ir_build_store_ptr(irb, node, lvalue, rvalue);1400 ir_build_store_ptr(irb, scope, node, lvalue, rvalue);
1389 return ir_build_const_void(irb, node);1401 return ir_build_const_void(irb, scope, node);
1390}1402}
13911403
1392static IrInstruction *ir_gen_assign_op(IrBuilder *irb, AstNode *node, IrBinOp op_id) {1404static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) {
1393 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, node->scope, LValPurposeAssign);1405 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPurposeAssign);
1394 if (lvalue == irb->codegen->invalid_instruction)1406 if (lvalue == irb->codegen->invalid_instruction)
1395 return lvalue;1407 return lvalue;
1396 IrInstruction *op1 = ir_build_load_ptr(irb, node->data.bin_op_expr.op1, lvalue);1408 IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue);
1397 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, node->scope);1409 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
1398 if (op2 == irb->codegen->invalid_instruction)1410 if (op2 == irb->codegen->invalid_instruction)
1399 return op2;1411 return op2;
1400 IrInstruction *result = ir_build_bin_op(irb, node, op_id, op1, op2);1412 IrInstruction *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2);
1401 ir_build_store_ptr(irb, node, lvalue, result);1413 ir_build_store_ptr(irb, scope, node, lvalue, result);
1402 return ir_build_const_void(irb, node);1414 return ir_build_const_void(irb, scope, node);
1403}1415}
14041416
1405static IrInstruction *ir_gen_bin_op(IrBuilder *irb, AstNode *node) {1417static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) {
1406 assert(node->type == NodeTypeBinOpExpr);1418 assert(node->type == NodeTypeBinOpExpr);
14071419
1408 BinOpType bin_op_type = node->data.bin_op_expr.bin_op;1420 BinOpType bin_op_type = node->data.bin_op_expr.bin_op;
...@@ -1410,95 +1422,95 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, AstNode *node) {...@@ -1410,95 +1422,95 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, AstNode *node) {
1410 case BinOpTypeInvalid:1422 case BinOpTypeInvalid:
1411 zig_unreachable();1423 zig_unreachable();
1412 case BinOpTypeAssign:1424 case BinOpTypeAssign:
1413 return ir_gen_assign(irb, node);1425 return ir_gen_assign(irb, scope, node);
1414 case BinOpTypeAssignTimes:1426 case BinOpTypeAssignTimes:
1415 return ir_gen_assign_op(irb, node, IrBinOpMult);1427 return ir_gen_assign_op(irb, scope, node, IrBinOpMult);
1416 case BinOpTypeAssignTimesWrap:1428 case BinOpTypeAssignTimesWrap:
1417 return ir_gen_assign_op(irb, node, IrBinOpMultWrap);1429 return ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap);
1418 case BinOpTypeAssignDiv:1430 case BinOpTypeAssignDiv:
1419 return ir_gen_assign_op(irb, node, IrBinOpDiv);1431 return ir_gen_assign_op(irb, scope, node, IrBinOpDiv);
1420 case BinOpTypeAssignMod:1432 case BinOpTypeAssignMod:
1421 return ir_gen_assign_op(irb, node, IrBinOpMod);1433 return ir_gen_assign_op(irb, scope, node, IrBinOpMod);
1422 case BinOpTypeAssignPlus:1434 case BinOpTypeAssignPlus:
1423 return ir_gen_assign_op(irb, node, IrBinOpAdd);1435 return ir_gen_assign_op(irb, scope, node, IrBinOpAdd);
1424 case BinOpTypeAssignPlusWrap:1436 case BinOpTypeAssignPlusWrap:
1425 return ir_gen_assign_op(irb, node, IrBinOpAddWrap);1437 return ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap);
1426 case BinOpTypeAssignMinus:1438 case BinOpTypeAssignMinus:
1427 return ir_gen_assign_op(irb, node, IrBinOpSub);1439 return ir_gen_assign_op(irb, scope, node, IrBinOpSub);
1428 case BinOpTypeAssignMinusWrap:1440 case BinOpTypeAssignMinusWrap:
1429 return ir_gen_assign_op(irb, node, IrBinOpSubWrap);1441 return ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap);
1430 case BinOpTypeAssignBitShiftLeft:1442 case BinOpTypeAssignBitShiftLeft:
1431 return ir_gen_assign_op(irb, node, IrBinOpBitShiftLeft);1443 return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeft);
1432 case BinOpTypeAssignBitShiftLeftWrap:1444 case BinOpTypeAssignBitShiftLeftWrap:
1433 return ir_gen_assign_op(irb, node, IrBinOpBitShiftLeftWrap);1445 return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftWrap);
1434 case BinOpTypeAssignBitShiftRight:1446 case BinOpTypeAssignBitShiftRight:
1435 return ir_gen_assign_op(irb, node, IrBinOpBitShiftRight);1447 return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRight);
1436 case BinOpTypeAssignBitAnd:1448 case BinOpTypeAssignBitAnd:
1437 return ir_gen_assign_op(irb, node, IrBinOpBinAnd);1449 return ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd);
1438 case BinOpTypeAssignBitXor:1450 case BinOpTypeAssignBitXor:
1439 return ir_gen_assign_op(irb, node, IrBinOpBinXor);1451 return ir_gen_assign_op(irb, scope, node, IrBinOpBinXor);
1440 case BinOpTypeAssignBitOr:1452 case BinOpTypeAssignBitOr:
1441 return ir_gen_assign_op(irb, node, IrBinOpBinOr);1453 return ir_gen_assign_op(irb, scope, node, IrBinOpBinOr);
1442 case BinOpTypeAssignBoolAnd:1454 case BinOpTypeAssignBoolAnd:
1443 return ir_gen_assign_op(irb, node, IrBinOpBoolAnd);1455 return ir_gen_assign_op(irb, scope, node, IrBinOpBoolAnd);
1444 case BinOpTypeAssignBoolOr:1456 case BinOpTypeAssignBoolOr:
1445 return ir_gen_assign_op(irb, node, IrBinOpBoolOr);1457 return ir_gen_assign_op(irb, scope, node, IrBinOpBoolOr);
1446 case BinOpTypeBoolOr:1458 case BinOpTypeBoolOr:
1447 case BinOpTypeBoolAnd:1459 case BinOpTypeBoolAnd:
1448 // note: this is not a direct mapping to IrBinOpBoolOr/And1460 // note: this is not a direct mapping to IrBinOpBoolOr/And
1449 // because of the control flow1461 // because of the control flow
1450 zig_panic("TODO gen IR for bool or/and");1462 zig_panic("TODO gen IR for bool or/and");
1451 case BinOpTypeCmpEq:1463 case BinOpTypeCmpEq:
1452 return ir_gen_bin_op_id(irb, node, IrBinOpCmpEq);1464 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq);
1453 case BinOpTypeCmpNotEq:1465 case BinOpTypeCmpNotEq:
1454 return ir_gen_bin_op_id(irb, node, IrBinOpCmpNotEq);1466 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq);
1455 case BinOpTypeCmpLessThan:1467 case BinOpTypeCmpLessThan:
1456 return ir_gen_bin_op_id(irb, node, IrBinOpCmpLessThan);1468 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan);
1457 case BinOpTypeCmpGreaterThan:1469 case BinOpTypeCmpGreaterThan:
1458 return ir_gen_bin_op_id(irb, node, IrBinOpCmpGreaterThan);1470 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan);
1459 case BinOpTypeCmpLessOrEq:1471 case BinOpTypeCmpLessOrEq:
1460 return ir_gen_bin_op_id(irb, node, IrBinOpCmpLessOrEq);1472 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq);
1461 case BinOpTypeCmpGreaterOrEq:1473 case BinOpTypeCmpGreaterOrEq:
1462 return ir_gen_bin_op_id(irb, node, IrBinOpCmpGreaterOrEq);1474 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq);
1463 case BinOpTypeBinOr:1475 case BinOpTypeBinOr:
1464 return ir_gen_bin_op_id(irb, node, IrBinOpBinOr);1476 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr);
1465 case BinOpTypeBinXor:1477 case BinOpTypeBinXor:
1466 return ir_gen_bin_op_id(irb, node, IrBinOpBinXor);1478 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor);
1467 case BinOpTypeBinAnd:1479 case BinOpTypeBinAnd:
1468 return ir_gen_bin_op_id(irb, node, IrBinOpBinAnd);1480 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd);
1469 case BinOpTypeBitShiftLeft:1481 case BinOpTypeBitShiftLeft:
1470 return ir_gen_bin_op_id(irb, node, IrBinOpBitShiftLeft);1482 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeft);
1471 case BinOpTypeBitShiftLeftWrap:1483 case BinOpTypeBitShiftLeftWrap:
1472 return ir_gen_bin_op_id(irb, node, IrBinOpBitShiftLeftWrap);1484 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftWrap);
1473 case BinOpTypeBitShiftRight:1485 case BinOpTypeBitShiftRight:
1474 return ir_gen_bin_op_id(irb, node, IrBinOpBitShiftRight);1486 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRight);
1475 case BinOpTypeAdd:1487 case BinOpTypeAdd:
1476 return ir_gen_bin_op_id(irb, node, IrBinOpAdd);1488 return ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd);
1477 case BinOpTypeAddWrap:1489 case BinOpTypeAddWrap:
1478 return ir_gen_bin_op_id(irb, node, IrBinOpAddWrap);1490 return ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap);
1479 case BinOpTypeSub:1491 case BinOpTypeSub:
1480 return ir_gen_bin_op_id(irb, node, IrBinOpSub);1492 return ir_gen_bin_op_id(irb, scope, node, IrBinOpSub);
1481 case BinOpTypeSubWrap:1493 case BinOpTypeSubWrap:
1482 return ir_gen_bin_op_id(irb, node, IrBinOpSubWrap);1494 return ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap);
1483 case BinOpTypeMult:1495 case BinOpTypeMult:
1484 return ir_gen_bin_op_id(irb, node, IrBinOpMult);1496 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMult);
1485 case BinOpTypeMultWrap:1497 case BinOpTypeMultWrap:
1486 return ir_gen_bin_op_id(irb, node, IrBinOpMultWrap);1498 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap);
1487 case BinOpTypeDiv:1499 case BinOpTypeDiv:
1488 return ir_gen_bin_op_id(irb, node, IrBinOpDiv);1500 return ir_gen_bin_op_id(irb, scope, node, IrBinOpDiv);
1489 case BinOpTypeMod:1501 case BinOpTypeMod:
1490 return ir_gen_bin_op_id(irb, node, IrBinOpMod);1502 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMod);
1491 case BinOpTypeArrayCat:1503 case BinOpTypeArrayCat:
1492 return ir_gen_bin_op_id(irb, node, IrBinOpArrayCat);1504 return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat);
1493 case BinOpTypeArrayMult:1505 case BinOpTypeArrayMult:
1494 return ir_gen_bin_op_id(irb, node, IrBinOpArrayMult);1506 return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult);
1495 case BinOpTypeUnwrapMaybe:1507 case BinOpTypeUnwrapMaybe:
1496 zig_panic("TODO gen IR for unwrap maybe binary operation");1508 zig_panic("TODO gen IR for unwrap maybe binary operation");
1497 }1509 }
1498 zig_unreachable();1510 zig_unreachable();
1499}1511}
15001512
1501static IrInstruction *ir_gen_num_lit(IrBuilder *irb, AstNode *node) {1513static IrInstruction *ir_gen_num_lit(IrBuilder *irb, Scope *scope, AstNode *node) {
1502 assert(node->type == NodeTypeNumberLiteral);1514 assert(node->type == NodeTypeNumberLiteral);
15031515
1504 if (node->data.number_literal.overflow) {1516 if (node->data.number_literal.overflow) {
...@@ -1506,95 +1518,95 @@ static IrInstruction *ir_gen_num_lit(IrBuilder *irb, AstNode *node) {...@@ -1506,95 +1518,95 @@ static IrInstruction *ir_gen_num_lit(IrBuilder *irb, AstNode *node) {
1506 return irb->codegen->invalid_instruction;1518 return irb->codegen->invalid_instruction;
1507 }1519 }
15081520
1509 return ir_build_const_bignum(irb, node, node->data.number_literal.bignum);1521 return ir_build_const_bignum(irb, scope, node, node->data.number_literal.bignum);
1510}1522}
15111523
1512static IrInstruction *ir_gen_null_literal(IrBuilder *irb, AstNode *node) {1524static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
1513 assert(node->type == NodeTypeNullLiteral);1525 assert(node->type == NodeTypeNullLiteral);
15141526
1515 return ir_build_const_null(irb, node);1527 return ir_build_const_null(irb, scope, node);
1516}1528}
15171529
1518static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, AstNode *decl_node,1530static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld *tld,
1519 LValPurpose lval, Scope *scope)1531 LValPurpose lval, Scope *scope)
1520{1532{
1521 resolve_top_level_decl(irb->codegen, decl_node, lval != LValPurposeNone);1533 resolve_top_level_decl(irb->codegen, tld, lval != LValPurposeNone);
1522 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
1523 if (tld->resolution == TldResolutionInvalid)1534 if (tld->resolution == TldResolutionInvalid)
1524 return irb->codegen->invalid_instruction;1535 return irb->codegen->invalid_instruction;
15251536
1526 if (decl_node->type == NodeTypeVariableDeclaration) {1537 switch (tld->id) {
1527 VariableTableEntry *var = decl_node->data.variable_declaration.variable;1538 case TldIdVar:
1528 IrInstruction *var_ptr = ir_build_var_ptr(irb, source_node, var);1539 {
1529 if (lval != LValPurposeNone)1540 TldVar *tld_var = (TldVar *)tld;
1530 return var_ptr;1541 VariableTableEntry *var = tld_var->var;
1531 else1542 IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, source_node, var);
1532 return ir_build_load_ptr(irb, source_node, var_ptr);1543 if (lval != LValPurposeNone)
1533 } else if (decl_node->type == NodeTypeFnProto) {1544 return var_ptr;
1534 FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry;1545 else
1535 assert(fn_entry->type_entry);1546 return ir_build_load_ptr(irb, scope, source_node, var_ptr);
1536 IrInstruction *ref_instruction;
1537 if (fn_entry->type_entry->id == TypeTableEntryIdGenericFn) {
1538 ref_instruction = ir_build_const_generic_fn(irb, source_node, fn_entry->type_entry);
1539 } else {
1540 ref_instruction = ir_build_const_fn(irb, source_node, fn_entry);
1541 }1547 }
1542 if (lval != LValPurposeNone)1548 case TldIdFn:
1543 return ir_build_ref(irb, source_node, ref_instruction);1549 {
1544 else1550 TldFn *tld_fn = (TldFn *)tld;
1545 return ref_instruction;1551 FnTableEntry *fn_entry = tld_fn->fn_entry;
1546 } else if (decl_node->type == NodeTypeContainerDecl) {1552 assert(fn_entry->type_entry);
1547 IrInstruction *ref_instruction;1553 IrInstruction *ref_instruction = ir_build_const_fn(irb, scope, source_node, fn_entry);
1548 if (decl_node->data.struct_decl.generic_params.length > 0) {1554 if (lval != LValPurposeNone)
1549 TypeTableEntry *type_entry = decl_node->data.struct_decl.generic_fn_type;1555 return ir_build_ref(irb, scope, source_node, ref_instruction);
1550 assert(type_entry);1556 else
1551 ref_instruction = ir_build_const_generic_fn(irb, source_node, type_entry);1557 return ref_instruction;
1552 } else {1558 }
1553 ref_instruction = ir_build_const_type(irb, source_node, decl_node->data.struct_decl.type_entry);1559 case TldIdContainer:
1560 {
1561 TldContainer *tld_container = (TldContainer *)tld;
1562
1563 IrInstruction *ref_instruction = ir_build_const_type(irb, scope, source_node, tld_container->type_entry);
1564 if (lval != LValPurposeNone)
1565 return ir_build_ref(irb, scope, source_node, ref_instruction);
1566 else
1567 return ref_instruction;
1568 }
1569 case TldIdTypeDef:
1570 {
1571 TldTypeDef *tld_typedef = (TldTypeDef *)tld;
1572 TypeTableEntry *typedef_type = tld_typedef->type_entry;
1573 IrInstruction *ref_instruction = ir_build_const_type(irb, scope, source_node, typedef_type);
1574 if (lval != LValPurposeNone)
1575 return ir_build_ref(irb, scope, source_node, ref_instruction);
1576 else
1577 return ref_instruction;
1554 }1578 }
1555 if (lval != LValPurposeNone)
1556 return ir_build_ref(irb, source_node, ref_instruction);
1557 else
1558 return ref_instruction;
1559 } else if (decl_node->type == NodeTypeTypeDecl) {
1560 TypeTableEntry *child_type = decl_node->data.type_decl.child_type_entry;
1561 IrInstruction *ref_instruction = ir_build_const_type(irb, source_node, child_type);
1562 if (lval != LValPurposeNone)
1563 return ir_build_ref(irb, source_node, ref_instruction);
1564 else
1565 return ref_instruction;
1566 } else {
1567 zig_unreachable();
1568 }1579 }
1580 zig_unreachable();
1569}1581}
15701582
1571static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose lval) {1583static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LValPurpose lval) {
1572 assert(node->type == NodeTypeSymbol);1584 assert(node->type == NodeTypeSymbol);
15731585
1574 Buf *variable_name = node->data.symbol_expr.symbol;1586 Buf *variable_name = node->data.symbol_expr.symbol;
15751587
1576 auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);1588 auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);
1577 if (primitive_table_entry) {1589 if (primitive_table_entry) {
1578 IrInstruction *value = ir_build_const_type(irb, node, primitive_table_entry->value);1590 IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_table_entry->value);
1579 if (lval == LValPurposeAddressOf) {1591 if (lval == LValPurposeAddressOf) {
1580 return ir_build_un_op(irb, node, IrUnOpAddressOf, value);1592 return ir_build_un_op(irb, scope, node, IrUnOpAddressOf, value);
1581 } else {1593 } else {
1582 return value;1594 return value;
1583 }1595 }
1584 }1596 }
15851597
1586 VariableTableEntry *var = find_variable(irb->codegen, node->scope, variable_name);1598 VariableTableEntry *var = find_variable(irb->codegen, scope, variable_name);
1587 if (var) {1599 if (var) {
1588 IrInstruction *var_ptr = ir_build_var_ptr(irb, node, var);1600 IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, node, var);
1589 if (lval != LValPurposeNone)1601 if (lval != LValPurposeNone)
1590 return var_ptr;1602 return var_ptr;
1591 else1603 else
1592 return ir_build_load_ptr(irb, node, var_ptr);1604 return ir_build_load_ptr(irb, scope, node, var_ptr);
1593 }1605 }
15941606
1595 AstNode *decl_node = find_decl(node->scope, variable_name);1607 Tld *tld = find_decl(scope, variable_name);
1596 if (decl_node)1608 if (tld)
1597 return ir_gen_decl_ref(irb, node, decl_node, lval, node->scope);1609 return ir_gen_decl_ref(irb, node, tld, lval, scope);
15981610
1599 if (node->owner->any_imports_failed) {1611 if (node->owner->any_imports_failed) {
1600 // skip the error message since we had a failing import in this file1612 // skip the error message since we had a failing import in this file
...@@ -1606,47 +1618,47 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l...@@ -1606,47 +1618,47 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, AstNode *node, LValPurpose l
1606 return irb->codegen->invalid_instruction;1618 return irb->codegen->invalid_instruction;
1607}1619}
16081620
1609static IrInstruction *ir_gen_array_access(IrBuilder *irb, AstNode *node, LValPurpose lval) {1621static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LValPurpose lval) {
1610 assert(node->type == NodeTypeArrayAccessExpr);1622 assert(node->type == NodeTypeArrayAccessExpr);
16111623
1612 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;1624 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;
1613 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, node->scope,1625 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope,
1614 LValPurposeAddressOf);1626 LValPurposeAddressOf);
1615 if (array_ref_instruction == irb->codegen->invalid_instruction)1627 if (array_ref_instruction == irb->codegen->invalid_instruction)
1616 return array_ref_instruction;1628 return array_ref_instruction;
16171629
1618 AstNode *subscript_node = node->data.array_access_expr.subscript;1630 AstNode *subscript_node = node->data.array_access_expr.subscript;
1619 IrInstruction *subscript_instruction = ir_gen_node(irb, subscript_node, node->scope);1631 IrInstruction *subscript_instruction = ir_gen_node(irb, subscript_node, scope);
1620 if (subscript_instruction == irb->codegen->invalid_instruction)1632 if (subscript_instruction == irb->codegen->invalid_instruction)
1621 return subscript_instruction;1633 return subscript_instruction;
16221634
1623 IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, node, array_ref_instruction,1635 IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction,
1624 subscript_instruction, true);1636 subscript_instruction, true);
1625 if (lval != LValPurposeNone)1637 if (lval != LValPurposeNone)
1626 return ptr_instruction;1638 return ptr_instruction;
16271639
1628 return ir_build_load_ptr(irb, node, ptr_instruction);1640 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
1629}1641}
16301642
1631static IrInstruction *ir_gen_field_access(IrBuilder *irb, AstNode *node, LValPurpose lval) {1643static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node, LValPurpose lval) {
1632 assert(node->type == NodeTypeFieldAccessExpr);1644 assert(node->type == NodeTypeFieldAccessExpr);
16331645
1634 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;1646 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
1635 Buf *field_name = node->data.field_access_expr.field_name;1647 Buf *field_name = node->data.field_access_expr.field_name;
16361648
1637 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, node->scope,1649 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope,
1638 LValPurposeAddressOf);1650 LValPurposeAddressOf);
1639 if (container_ref_instruction == irb->codegen->invalid_instruction)1651 if (container_ref_instruction == irb->codegen->invalid_instruction)
1640 return container_ref_instruction;1652 return container_ref_instruction;
16411653
1642 IrInstruction *ptr_instruction = ir_build_field_ptr(irb, node, container_ref_instruction, field_name);1654 IrInstruction *ptr_instruction = ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name);
1643 if (lval != LValPurposeNone)1655 if (lval != LValPurposeNone)
1644 return ptr_instruction;1656 return ptr_instruction;
16451657
1646 return ir_build_load_ptr(irb, node, ptr_instruction);1658 return ir_build_load_ptr(irb, scope, node, ptr_instruction);
1647}1659}
16481660
1649static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {1661static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node) {
1650 assert(node->type == NodeTypeFnCallExpr);1662 assert(node->type == NodeTypeFnCallExpr);
16511663
1652 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;1664 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
...@@ -1675,115 +1687,115 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {...@@ -1675,115 +1687,115 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
1675 case BuiltinFnIdInvalid:1687 case BuiltinFnIdInvalid:
1676 zig_unreachable();1688 zig_unreachable();
1677 case BuiltinFnIdUnreachable:1689 case BuiltinFnIdUnreachable:
1678 return ir_build_unreachable(irb, node);1690 return ir_build_unreachable(irb, scope, node);
1679 case BuiltinFnIdTypeof:1691 case BuiltinFnIdTypeof:
1680 {1692 {
1681 AstNode *arg_node = node->data.fn_call_expr.params.at(0);1693 AstNode *arg_node = node->data.fn_call_expr.params.at(0);
1682 IrInstruction *arg = ir_gen_node(irb, arg_node, node->scope);1694 IrInstruction *arg = ir_gen_node(irb, arg_node, scope);
1683 if (arg == irb->codegen->invalid_instruction)1695 if (arg == irb->codegen->invalid_instruction)
1684 return arg;1696 return arg;
1685 return ir_build_typeof(irb, node, arg);1697 return ir_build_typeof(irb, scope, node, arg);
1686 }1698 }
1687 case BuiltinFnIdSetFnTest:1699 case BuiltinFnIdSetFnTest:
1688 {1700 {
1689 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);1701 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
1690 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);1702 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
1691 if (arg0_value == irb->codegen->invalid_instruction)1703 if (arg0_value == irb->codegen->invalid_instruction)
1692 return arg0_value;1704 return arg0_value;
16931705
1694 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);1706 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
1695 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->scope);1707 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
1696 if (arg1_value == irb->codegen->invalid_instruction)1708 if (arg1_value == irb->codegen->invalid_instruction)
1697 return arg1_value;1709 return arg1_value;
16981710
1699 return ir_build_set_fn_test(irb, node, arg0_value, arg1_value);1711 return ir_build_set_fn_test(irb, scope, node, arg0_value, arg1_value);
1700 }1712 }
1701 case BuiltinFnIdSetFnVisible:1713 case BuiltinFnIdSetFnVisible:
1702 {1714 {
1703 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);1715 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
1704 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);1716 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
1705 if (arg0_value == irb->codegen->invalid_instruction)1717 if (arg0_value == irb->codegen->invalid_instruction)
1706 return arg0_value;1718 return arg0_value;
17071719
1708 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);1720 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
1709 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->scope);1721 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
1710 if (arg1_value == irb->codegen->invalid_instruction)1722 if (arg1_value == irb->codegen->invalid_instruction)
1711 return arg1_value;1723 return arg1_value;
17121724
1713 return ir_build_set_fn_visible(irb, node, arg0_value, arg1_value);1725 return ir_build_set_fn_visible(irb, scope, node, arg0_value, arg1_value);
1714 }1726 }
1715 case BuiltinFnIdSetDebugSafety:1727 case BuiltinFnIdSetDebugSafety:
1716 {1728 {
1717 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);1729 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
1718 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);1730 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
1719 if (arg0_value == irb->codegen->invalid_instruction)1731 if (arg0_value == irb->codegen->invalid_instruction)
1720 return arg0_value;1732 return arg0_value;
17211733
1722 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);1734 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
1723 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, node->scope);1735 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
1724 if (arg1_value == irb->codegen->invalid_instruction)1736 if (arg1_value == irb->codegen->invalid_instruction)
1725 return arg1_value;1737 return arg1_value;
17261738
1727 return ir_build_set_debug_safety(irb, node, arg0_value, arg1_value);1739 return ir_build_set_debug_safety(irb, scope, node, arg0_value, arg1_value);
1728 }1740 }
1729 case BuiltinFnIdCompileVar:1741 case BuiltinFnIdCompileVar:
1730 {1742 {
1731 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);1743 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
1732 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);1744 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
1733 if (arg0_value == irb->codegen->invalid_instruction)1745 if (arg0_value == irb->codegen->invalid_instruction)
1734 return arg0_value;1746 return arg0_value;
17351747
1736 return ir_build_compile_var(irb, node, arg0_value);1748 return ir_build_compile_var(irb, scope, node, arg0_value);
1737 }1749 }
1738 case BuiltinFnIdSizeof:1750 case BuiltinFnIdSizeof:
1739 {1751 {
1740 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);1752 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
1741 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);1753 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
1742 if (arg0_value == irb->codegen->invalid_instruction)1754 if (arg0_value == irb->codegen->invalid_instruction)
1743 return arg0_value;1755 return arg0_value;
17441756
1745 return ir_build_size_of(irb, node, arg0_value);1757 return ir_build_size_of(irb, scope, node, arg0_value);
1746 }1758 }
1747 case BuiltinFnIdCtz:1759 case BuiltinFnIdCtz:
1748 {1760 {
1749 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);1761 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
1750 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);1762 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
1751 if (arg0_value == irb->codegen->invalid_instruction)1763 if (arg0_value == irb->codegen->invalid_instruction)
1752 return arg0_value;1764 return arg0_value;
17531765
1754 return ir_build_ctz(irb, node, arg0_value);1766 return ir_build_ctz(irb, scope, node, arg0_value);
1755 }1767 }
1756 case BuiltinFnIdClz:1768 case BuiltinFnIdClz:
1757 {1769 {
1758 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);1770 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
1759 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);1771 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
1760 if (arg0_value == irb->codegen->invalid_instruction)1772 if (arg0_value == irb->codegen->invalid_instruction)
1761 return arg0_value;1773 return arg0_value;
17621774
1763 return ir_build_clz(irb, node, arg0_value);1775 return ir_build_clz(irb, scope, node, arg0_value);
1764 }1776 }
1765 case BuiltinFnIdStaticEval:1777 case BuiltinFnIdStaticEval:
1766 {1778 {
1767 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);1779 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
1768 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);1780 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
1769 if (arg0_value == irb->codegen->invalid_instruction)1781 if (arg0_value == irb->codegen->invalid_instruction)
1770 return arg0_value;1782 return arg0_value;
17711783
1772 return ir_build_static_eval(irb, node, arg0_value);1784 return ir_build_static_eval(irb, scope, node, arg0_value);
1773 }1785 }
1774 case BuiltinFnIdImport:1786 case BuiltinFnIdImport:
1775 {1787 {
1776 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);1788 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
1777 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->scope);1789 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
1778 if (arg0_value == irb->codegen->invalid_instruction)1790 if (arg0_value == irb->codegen->invalid_instruction)
1779 return arg0_value;1791 return arg0_value;
17801792
1781 if (scope_fn_entry(node->scope)) {1793 if (exec_fn_entry(irb->exec)) {
1782 add_node_error(irb->codegen, node, buf_sprintf("import valid only at top level scope"));1794 add_node_error(irb->codegen, node, buf_sprintf("import valid only at top level scope"));
1783 return irb->codegen->invalid_instruction;1795 return irb->codegen->invalid_instruction;
1784 }1796 }
17851797
1786 return ir_build_import(irb, node, arg0_value);1798 return ir_build_import(irb, scope, node, arg0_value);
1787 }1799 }
1788 case BuiltinFnIdMemcpy:1800 case BuiltinFnIdMemcpy:
1789 case BuiltinFnIdMemset:1801 case BuiltinFnIdMemset:
...@@ -1816,14 +1828,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {...@@ -1816,14 +1828,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
1816 zig_unreachable();1828 zig_unreachable();
1817}1829}
18181830
1819static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) {1831static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node) {
1820 assert(node->type == NodeTypeFnCallExpr);1832 assert(node->type == NodeTypeFnCallExpr);
18211833
1822 if (node->data.fn_call_expr.is_builtin)1834 if (node->data.fn_call_expr.is_builtin)
1823 return ir_gen_builtin_fn_call(irb, node);1835 return ir_gen_builtin_fn_call(irb, scope, node);
18241836
1825 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;1837 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
1826 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, node->scope);1838 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope);
1827 if (fn_ref == irb->codegen->invalid_instruction)1839 if (fn_ref == irb->codegen->invalid_instruction)
1828 return fn_ref;1840 return fn_ref;
18291841
...@@ -1831,16 +1843,16 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) {...@@ -1831,16 +1843,16 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, AstNode *node) {
1831 IrInstruction **args = allocate<IrInstruction*>(arg_count);1843 IrInstruction **args = allocate<IrInstruction*>(arg_count);
1832 for (size_t i = 0; i < arg_count; i += 1) {1844 for (size_t i = 0; i < arg_count; i += 1) {
1833 AstNode *arg_node = node->data.fn_call_expr.params.at(i);1845 AstNode *arg_node = node->data.fn_call_expr.params.at(i);
1834 args[i] = ir_gen_node(irb, arg_node, node->scope);1846 args[i] = ir_gen_node(irb, arg_node, scope);
1835 }1847 }
18361848
1837 return ir_build_call(irb, node, nullptr, fn_ref, arg_count, args);1849 return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args);
1838}1850}
18391851
1840static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) {1852static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
1841 assert(node->type == NodeTypeIfBoolExpr);1853 assert(node->type == NodeTypeIfBoolExpr);
18421854
1843 IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, node->scope);1855 IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope);
1844 if (condition == irb->codegen->invalid_instruction)1856 if (condition == irb->codegen->invalid_instruction)
1845 return condition;1857 return condition;
18461858
...@@ -1852,26 +1864,26 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) {...@@ -1852,26 +1864,26 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) {
1852 IrBasicBlock *endif_block = ir_build_basic_block(irb, "EndIf");1864 IrBasicBlock *endif_block = ir_build_basic_block(irb, "EndIf");
18531865
1854 bool is_inline = ir_should_inline(irb) || node->data.if_bool_expr.is_inline;1866 bool is_inline = ir_should_inline(irb) || node->data.if_bool_expr.is_inline;
1855 ir_build_cond_br(irb, condition->source_node, condition, then_block, else_block, is_inline);1867 ir_build_cond_br(irb, scope, condition->source_node, condition, then_block, else_block, is_inline);
18561868
1857 ir_set_cursor_at_end(irb, then_block);1869 ir_set_cursor_at_end(irb, then_block);
1858 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, node->scope);1870 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, scope);
1859 if (then_expr_result == irb->codegen->invalid_instruction)1871 if (then_expr_result == irb->codegen->invalid_instruction)
1860 return then_expr_result;1872 return then_expr_result;
1861 IrBasicBlock *after_then_block = irb->current_basic_block;1873 IrBasicBlock *after_then_block = irb->current_basic_block;
1862 ir_build_br(irb, node, endif_block, is_inline);1874 ir_build_br(irb, scope, node, endif_block, is_inline);
18631875
1864 ir_set_cursor_at_end(irb, else_block);1876 ir_set_cursor_at_end(irb, else_block);
1865 IrInstruction *else_expr_result;1877 IrInstruction *else_expr_result;
1866 if (else_node) {1878 if (else_node) {
1867 else_expr_result = ir_gen_node(irb, else_node, node->scope);1879 else_expr_result = ir_gen_node(irb, else_node, scope);
1868 if (else_expr_result == irb->codegen->invalid_instruction)1880 if (else_expr_result == irb->codegen->invalid_instruction)
1869 return else_expr_result;1881 return else_expr_result;
1870 } else {1882 } else {
1871 else_expr_result = ir_build_const_void(irb, node);1883 else_expr_result = ir_build_const_void(irb, scope, node);
1872 }1884 }
1873 IrBasicBlock *after_else_block = irb->current_basic_block;1885 IrBasicBlock *after_else_block = irb->current_basic_block;
1874 ir_build_br(irb, node, endif_block, is_inline);1886 ir_build_br(irb, scope, node, endif_block, is_inline);
18751887
1876 ir_set_cursor_at_end(irb, endif_block);1888 ir_set_cursor_at_end(irb, endif_block);
1877 IrInstruction **incoming_values = allocate<IrInstruction *>(2);1889 IrInstruction **incoming_values = allocate<IrInstruction *>(2);
...@@ -1881,14 +1893,14 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) {...@@ -1881,14 +1893,14 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, AstNode *node) {
1881 incoming_blocks[0] = after_then_block;1893 incoming_blocks[0] = after_then_block;
1882 incoming_blocks[1] = after_else_block;1894 incoming_blocks[1] = after_else_block;
18831895
1884 return ir_build_phi(irb, node, 2, incoming_blocks, incoming_values);1896 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
1885}1897}
18861898
1887static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, AstNode *node, IrUnOp op_id, LValPurpose lval) {1899static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LValPurpose lval) {
1888 assert(node->type == NodeTypePrefixOpExpr);1900 assert(node->type == NodeTypePrefixOpExpr);
1889 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;1901 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
18901902
1891 IrInstruction *value = ir_gen_node_extra(irb, expr_node, node->scope, lval);1903 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);
1892 if (value == irb->codegen->invalid_instruction)1904 if (value == irb->codegen->invalid_instruction)
1893 return value;1905 return value;
18941906
...@@ -1896,27 +1908,27 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, AstNode *node, Ir...@@ -1896,27 +1908,27 @@ static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, AstNode *node, Ir
1896 return value;1908 return value;
1897 }1909 }
18981910
1899 return ir_build_un_op(irb, node, op_id, value);1911 return ir_build_un_op(irb, scope, node, op_id, value);
1900}1912}
19011913
1902static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, AstNode *node, IrUnOp op_id) {1914static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id) {
1903 return ir_gen_prefix_op_id_lval(irb, node, op_id, LValPurposeNone);1915 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValPurposeNone);
1904}1916}
19051917
1906static IrInstruction *ir_gen_prefix_op_unwrap_maybe(IrBuilder *irb, AstNode *node, LValPurpose lval) {1918static IrInstruction *ir_gen_prefix_op_unwrap_maybe(IrBuilder *irb, Scope *scope, AstNode *node, LValPurpose lval) {
1907 AstNode *expr = node->data.prefix_op_expr.primary_expr;1919 AstNode *expr = node->data.prefix_op_expr.primary_expr;
1908 IrInstruction *value = ir_gen_node_extra(irb, expr, node->scope, LValPurposeAddressOf);1920 IrInstruction *value = ir_gen_node_extra(irb, expr, scope, LValPurposeAddressOf);
1909 if (value == irb->codegen->invalid_instruction)1921 if (value == irb->codegen->invalid_instruction)
1910 return value;1922 return value;
19111923
1912 IrInstruction *unwrapped_ptr = ir_build_unwrap_maybe(irb, node, value, true);1924 IrInstruction *unwrapped_ptr = ir_build_unwrap_maybe(irb, scope, node, value, true);
1913 if (lval == LValPurposeNone)1925 if (lval == LValPurposeNone)
1914 return ir_build_load_ptr(irb, node, unwrapped_ptr);1926 return ir_build_load_ptr(irb, scope, node, unwrapped_ptr);
1915 else1927 else
1916 return unwrapped_ptr;1928 return unwrapped_ptr;
1917}1929}
19181930
1919static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, AstNode *node, LValPurpose lval) {1931static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LValPurpose lval) {
1920 assert(node->type == NodeTypePrefixOpExpr);1932 assert(node->type == NodeTypePrefixOpExpr);
19211933
1922 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op;1934 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op;
...@@ -1925,38 +1937,38 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, AstNode *node, LValP...@@ -1925,38 +1937,38 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, AstNode *node, LValP
1925 case PrefixOpInvalid:1937 case PrefixOpInvalid:
1926 zig_unreachable();1938 zig_unreachable();
1927 case PrefixOpBoolNot:1939 case PrefixOpBoolNot:
1928 return ir_gen_prefix_op_id(irb, node, IrUnOpBoolNot);1940 return ir_gen_prefix_op_id(irb, scope, node, IrUnOpBoolNot);
1929 case PrefixOpBinNot:1941 case PrefixOpBinNot:
1930 return ir_gen_prefix_op_id(irb, node, IrUnOpBinNot);1942 return ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot);
1931 case PrefixOpNegation:1943 case PrefixOpNegation:
1932 return ir_gen_prefix_op_id(irb, node, IrUnOpNegation);1944 return ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation);
1933 case PrefixOpNegationWrap:1945 case PrefixOpNegationWrap:
1934 return ir_gen_prefix_op_id(irb, node, IrUnOpNegationWrap);1946 return ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap);
1935 case PrefixOpAddressOf:1947 case PrefixOpAddressOf:
1936 return ir_gen_prefix_op_id_lval(irb, node, IrUnOpAddressOf, LValPurposeAddressOf);1948 return ir_gen_prefix_op_id_lval(irb, scope, node, IrUnOpAddressOf, LValPurposeAddressOf);
1937 case PrefixOpConstAddressOf:1949 case PrefixOpConstAddressOf:
1938 return ir_gen_prefix_op_id_lval(irb, node, IrUnOpConstAddressOf, LValPurposeAddressOf);1950 return ir_gen_prefix_op_id_lval(irb, scope, node, IrUnOpConstAddressOf, LValPurposeAddressOf);
1939 case PrefixOpDereference:1951 case PrefixOpDereference:
1940 return ir_gen_prefix_op_id_lval(irb, node, IrUnOpDereference, lval);1952 return ir_gen_prefix_op_id_lval(irb, scope, node, IrUnOpDereference, lval);
1941 case PrefixOpMaybe:1953 case PrefixOpMaybe:
1942 return ir_gen_prefix_op_id(irb, node, IrUnOpMaybe);1954 return ir_gen_prefix_op_id(irb, scope, node, IrUnOpMaybe);
1943 case PrefixOpError:1955 case PrefixOpError:
1944 return ir_gen_prefix_op_id(irb, node, IrUnOpError);1956 return ir_gen_prefix_op_id(irb, scope, node, IrUnOpError);
1945 case PrefixOpUnwrapError:1957 case PrefixOpUnwrapError:
1946 return ir_gen_prefix_op_id(irb, node, IrUnOpUnwrapError);1958 return ir_gen_prefix_op_id(irb, scope, node, IrUnOpUnwrapError);
1947 case PrefixOpUnwrapMaybe:1959 case PrefixOpUnwrapMaybe:
1948 return ir_gen_prefix_op_unwrap_maybe(irb, node, lval);1960 return ir_gen_prefix_op_unwrap_maybe(irb, scope, node, lval);
1949 }1961 }
1950 zig_unreachable();1962 zig_unreachable();
1951}1963}
19521964
1953static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node) {1965static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
1954 assert(node->type == NodeTypeContainerInitExpr);1966 assert(node->type == NodeTypeContainerInitExpr);
19551967
1956 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;1968 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
1957 ContainerInitKind kind = container_init_expr->kind;1969 ContainerInitKind kind = container_init_expr->kind;
19581970
1959 IrInstruction *container_type = ir_gen_node(irb, container_init_expr->type, node->scope);1971 IrInstruction *container_type = ir_gen_node(irb, container_init_expr->type, scope);
1960 if (container_type == irb->codegen->invalid_instruction)1972 if (container_type == irb->codegen->invalid_instruction)
1961 return container_type;1973 return container_type;
19621974
...@@ -1969,7 +1981,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node)...@@ -1969,7 +1981,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node)
19691981
1970 Buf *name = entry_node->data.struct_val_field.name;1982 Buf *name = entry_node->data.struct_val_field.name;
1971 AstNode *expr_node = entry_node->data.struct_val_field.expr;1983 AstNode *expr_node = entry_node->data.struct_val_field.expr;
1972 IrInstruction *expr_value = ir_gen_node(irb, expr_node, node->scope);1984 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope);
1973 if (expr_value == irb->codegen->invalid_instruction)1985 if (expr_value == irb->codegen->invalid_instruction)
1974 return expr_value;1986 return expr_value;
19751987
...@@ -1977,39 +1989,39 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node)...@@ -1977,39 +1989,39 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, AstNode *node)
1977 fields[i].value = expr_value;1989 fields[i].value = expr_value;
1978 fields[i].source_node = entry_node;1990 fields[i].source_node = entry_node;
1979 }1991 }
1980 return ir_build_container_init_fields(irb, node, container_type, field_count, fields);1992 return ir_build_container_init_fields(irb, scope, node, container_type, field_count, fields);
1981 } else if (kind == ContainerInitKindArray) {1993 } else if (kind == ContainerInitKindArray) {
1982 size_t item_count = container_init_expr->entries.length;1994 size_t item_count = container_init_expr->entries.length;
1983 IrInstruction **values = allocate<IrInstruction *>(item_count);1995 IrInstruction **values = allocate<IrInstruction *>(item_count);
1984 for (size_t i = 0; i < item_count; i += 1) {1996 for (size_t i = 0; i < item_count; i += 1) {
1985 AstNode *expr_node = container_init_expr->entries.at(i);1997 AstNode *expr_node = container_init_expr->entries.at(i);
1986 IrInstruction *expr_value = ir_gen_node(irb, expr_node, node->scope);1998 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope);
1987 if (expr_value == irb->codegen->invalid_instruction)1999 if (expr_value == irb->codegen->invalid_instruction)
1988 return expr_value;2000 return expr_value;
19892001
1990 values[i] = expr_value;2002 values[i] = expr_value;
1991 }2003 }
1992 return ir_build_container_init_list(irb, node, container_type, item_count, values);2004 return ir_build_container_init_list(irb, scope, node, container_type, item_count, values);
1993 } else {2005 } else {
1994 zig_unreachable();2006 zig_unreachable();
1995 }2007 }
1996}2008}
19972009
1998static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) {2010static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) {
1999 assert(node->type == NodeTypeVariableDeclaration);2011 assert(node->type == NodeTypeVariableDeclaration);
20002012
2001 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration;2013 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration;
20022014
2003 IrInstruction *type_instruction;2015 IrInstruction *type_instruction;
2004 if (variable_declaration->type != nullptr) {2016 if (variable_declaration->type != nullptr) {
2005 type_instruction = ir_gen_node(irb, variable_declaration->type, node->scope);2017 type_instruction = ir_gen_node(irb, variable_declaration->type, scope);
2006 if (type_instruction == irb->codegen->invalid_instruction)2018 if (type_instruction == irb->codegen->invalid_instruction)
2007 return type_instruction;2019 return type_instruction;
2008 } else {2020 } else {
2009 type_instruction = nullptr;2021 type_instruction = nullptr;
2010 }2022 }
20112023
2012 IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, node->scope);2024 IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope);
2013 if (init_value == irb->codegen->invalid_instruction)2025 if (init_value == irb->codegen->invalid_instruction)
2014 return init_value;2026 return init_value;
20152027
...@@ -2017,7 +2029,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) {...@@ -2017,7 +2029,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) {
2017 bool is_const = variable_declaration->is_const;2029 bool is_const = variable_declaration->is_const;
2018 bool is_extern = variable_declaration->is_extern;2030 bool is_extern = variable_declaration->is_extern;
2019 bool is_inline = ir_should_inline(irb) || variable_declaration->is_inline;2031 bool is_inline = ir_should_inline(irb) || variable_declaration->is_inline;
2020 VariableTableEntry *var = ir_create_var(irb, node, node->scope,2032 VariableTableEntry *var = ir_create_var(irb, node, scope,
2021 variable_declaration->symbol, is_const, is_const, is_shadowable, is_inline);2033 variable_declaration->symbol, is_const, is_const, is_shadowable, is_inline);
2022 // we detect IrInstructionIdDeclVar in gen_block to make sure the next node2034 // we detect IrInstructionIdDeclVar in gen_block to make sure the next node
2023 // is inside var->child_scope2035 // is inside var->child_scope
...@@ -2028,10 +2040,10 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) {...@@ -2028,10 +2040,10 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, AstNode *node) {
2028 return irb->codegen->invalid_instruction;2040 return irb->codegen->invalid_instruction;
2029 }2041 }
20302042
2031 return ir_build_var_decl(irb, node, var, type_instruction, init_value);2043 return ir_build_var_decl(irb, scope, node, var, type_instruction, init_value);
2032}2044}
20332045
2034static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) {2046static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
2035 assert(node->type == NodeTypeWhileExpr);2047 assert(node->type == NodeTypeWhileExpr);
20362048
2037 AstNode *continue_expr_node = node->data.while_expr.continue_expr;2049 AstNode *continue_expr_node = node->data.while_expr.continue_expr;
...@@ -2043,37 +2055,35 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) {...@@ -2043,37 +2055,35 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, AstNode *node) {
2043 IrBasicBlock *end_block = ir_build_basic_block(irb, "WhileEnd");2055 IrBasicBlock *end_block = ir_build_basic_block(irb, "WhileEnd");
20442056
2045 bool is_inline = ir_should_inline(irb) || node->data.while_expr.is_inline;2057 bool is_inline = ir_should_inline(irb) || node->data.while_expr.is_inline;
2046 ir_build_br(irb, node, cond_block, is_inline);2058 ir_build_br(irb, scope, node, cond_block, is_inline);
20472059
2048 if (continue_expr_node) {2060 if (continue_expr_node) {
2049 ir_set_cursor_at_end(irb, continue_block);2061 ir_set_cursor_at_end(irb, continue_block);
2050 ir_gen_node(irb, continue_expr_node, node->scope);2062 ir_gen_node(irb, continue_expr_node, scope);
2051 ir_build_br(irb, node, cond_block, is_inline);2063 ir_build_br(irb, scope, node, cond_block, is_inline);
2052 }2064 }
20532065
2054 ir_set_cursor_at_end(irb, cond_block);2066 ir_set_cursor_at_end(irb, cond_block);
2055 IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, node->scope);2067 IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope);
2056 ir_build_cond_br(irb, node->data.while_expr.condition, cond_val, body_block, end_block, is_inline);2068 ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, body_block, end_block, is_inline);
20572069
2058 ir_set_cursor_at_end(irb, body_block);2070 ir_set_cursor_at_end(irb, body_block);
20592071
2060 irb->break_block_stack.append(end_block);2072 irb->break_block_stack.append(end_block);
2061 irb->continue_block_stack.append(continue_block);2073 irb->continue_block_stack.append(continue_block);
2062 ir_gen_node(irb, node->data.while_expr.body, node->scope);2074 ir_gen_node(irb, node->data.while_expr.body, scope);
2063 irb->break_block_stack.pop();2075 irb->break_block_stack.pop();
2064 irb->continue_block_stack.pop();2076 irb->continue_block_stack.pop();
20652077
2066 ir_build_br(irb, node, continue_block, is_inline);2078 ir_build_br(irb, scope, node, continue_block, is_inline);
2067 ir_set_cursor_at_end(irb, end_block);2079 ir_set_cursor_at_end(irb, end_block);
20682080
2069 return ir_build_const_void(irb, node);2081 return ir_build_const_void(irb, scope, node);
2070}2082}
20712083
2072static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {2084static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
2073 assert(node->type == NodeTypeForExpr);2085 assert(node->type == NodeTypeForExpr);
20742086
2075 Scope *parent_scope = node->scope;
2076
2077 AstNode *array_node = node->data.for_expr.array_expr;2087 AstNode *array_node = node->data.for_expr.array_expr;
2078 AstNode *elem_node = node->data.for_expr.elem_node;2088 AstNode *elem_node = node->data.for_expr.elem_node;
2079 AstNode *index_node = node->data.for_expr.index_node;2089 AstNode *index_node = node->data.for_expr.index_node;
...@@ -2089,48 +2099,45 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {...@@ -2089,48 +2099,45 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {
2089 if (array_val == irb->codegen->invalid_instruction)2099 if (array_val == irb->codegen->invalid_instruction)
2090 return array_val;2100 return array_val;
20912101
2092 IrInstruction *array_type = ir_build_typeof(irb, array_node, array_val);2102 IrInstruction *array_type = ir_build_typeof(irb, parent_scope, array_node, array_val);
2093 IrInstruction *pointer_type = ir_build_to_ptr_type(irb, array_node, array_type);2103 IrInstruction *pointer_type = ir_build_to_ptr_type(irb, parent_scope, array_node, array_type);
2094 IrInstruction *elem_var_type;2104 IrInstruction *elem_var_type;
2095 if (node->data.for_expr.elem_is_ptr) {2105 if (node->data.for_expr.elem_is_ptr) {
2096 elem_var_type = pointer_type;2106 elem_var_type = pointer_type;
2097 } else {2107 } else {
2098 elem_var_type = ir_build_ptr_type_child(irb, elem_node, pointer_type);2108 elem_var_type = ir_build_ptr_type_child(irb, parent_scope, elem_node, pointer_type);
2099 }2109 }
2100 bool is_inline = ir_should_inline(irb) || node->data.for_expr.is_inline;2110 bool is_inline = ir_should_inline(irb) || node->data.for_expr.is_inline;
21012111
2102 Scope *child_scope = create_loop_scope(node, parent_scope);2112 Scope *child_scope = create_loop_scope(node, parent_scope);
2103 elem_node->scope = child_scope;
21042113
2105 // TODO make it an error to write to element variable or i variable.2114 // TODO make it an error to write to element variable or i variable.
2106 Buf *elem_var_name = elem_node->data.symbol_expr.symbol;2115 Buf *elem_var_name = elem_node->data.symbol_expr.symbol;
2107 node->data.for_expr.elem_var = ir_create_var(irb, elem_node, child_scope, elem_var_name,2116 VariableTableEntry *elem_var = ir_create_var(irb, elem_node, child_scope, elem_var_name,
2108 true, false, false, is_inline);2117 true, false, false, is_inline);
2109 child_scope = node->data.for_expr.elem_var->child_scope;2118 child_scope = elem_var->child_scope;
21102119
2111 IrInstruction *undefined_value = ir_build_const_undefined(irb, elem_node);2120 IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node);
2112 ir_build_var_decl(irb, elem_node, node->data.for_expr.elem_var, elem_var_type, undefined_value); 2121 ir_build_var_decl(irb, child_scope, elem_node, elem_var, elem_var_type, undefined_value);
2113 IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, node, node->data.for_expr.elem_var);2122 IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var);
21142123
2115 AstNode *index_var_source_node;2124 AstNode *index_var_source_node;
2125 VariableTableEntry *index_var;
2116 if (index_node) {2126 if (index_node) {
2117 index_var_source_node = index_node;2127 index_var_source_node = index_node;
2118 Buf *index_var_name = index_node->data.symbol_expr.symbol;2128 Buf *index_var_name = index_node->data.symbol_expr.symbol;
2119 index_node->scope = child_scope;2129 index_var = ir_create_var(irb, index_node, child_scope, index_var_name, true, false, false, is_inline);
2120 node->data.for_expr.index_var = ir_create_var(irb, index_node, child_scope, index_var_name,
2121 true, false, false, is_inline);
2122 } else {2130 } else {
2123 index_var_source_node = node;2131 index_var_source_node = node;
2124 node->data.for_expr.index_var = ir_create_var(irb, node, child_scope, nullptr,2132 index_var = ir_create_var(irb, node, child_scope, nullptr, true, false, true, is_inline);
2125 true, false, true, is_inline);
2126 }2133 }
2127 child_scope = node->data.for_expr.index_var->child_scope;2134 child_scope = index_var->child_scope;
21282135
2129 IrInstruction *usize = ir_build_const_type(irb, node, irb->codegen->builtin_types.entry_usize);2136 IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize);
2130 IrInstruction *zero = ir_build_const_usize(irb, node, 0);2137 IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0);
2131 IrInstruction *one = ir_build_const_usize(irb, node, 1);2138 IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1);
2132 ir_build_var_decl(irb, index_var_source_node, node->data.for_expr.index_var, usize, zero); 2139 ir_build_var_decl(irb, child_scope, index_var_source_node, index_var, usize, zero);
2133 IrInstruction *index_ptr = ir_build_var_ptr(irb, node, node->data.for_expr.index_var);2140 IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var);
21342141
21352142
2136 IrBasicBlock *cond_block = ir_build_basic_block(irb, "ForCond");2143 IrBasicBlock *cond_block = ir_build_basic_block(irb, "ForCond");
...@@ -2138,23 +2145,23 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {...@@ -2138,23 +2145,23 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {
2138 IrBasicBlock *end_block = ir_build_basic_block(irb, "ForEnd");2145 IrBasicBlock *end_block = ir_build_basic_block(irb, "ForEnd");
2139 IrBasicBlock *continue_block = ir_build_basic_block(irb, "ForContinue");2146 IrBasicBlock *continue_block = ir_build_basic_block(irb, "ForContinue");
21402147
2141 IrInstruction *len_val = ir_build_array_len(irb, node, array_val);2148 IrInstruction *len_val = ir_build_array_len(irb, child_scope, node, array_val);
2142 ir_build_br(irb, node, cond_block, is_inline);2149 ir_build_br(irb, child_scope, node, cond_block, is_inline);
21432150
2144 ir_set_cursor_at_end(irb, cond_block);2151 ir_set_cursor_at_end(irb, cond_block);
2145 IrInstruction *index_val = ir_build_load_ptr(irb, node, index_ptr);2152 IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr);
2146 IrInstruction *cond = ir_build_bin_op(irb, node, IrBinOpCmpLessThan, index_val, len_val);2153 IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val);
2147 ir_build_cond_br(irb, node, cond, body_block, end_block, is_inline);2154 ir_build_cond_br(irb, child_scope, node, cond, body_block, end_block, is_inline);
21482155
2149 ir_set_cursor_at_end(irb, body_block);2156 ir_set_cursor_at_end(irb, body_block);
2150 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, node, array_val, index_val, true);2157 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val, index_val, true);
2151 IrInstruction *elem_val;2158 IrInstruction *elem_val;
2152 if (node->data.for_expr.elem_is_ptr) {2159 if (node->data.for_expr.elem_is_ptr) {
2153 elem_val = elem_ptr;2160 elem_val = elem_ptr;
2154 } else {2161 } else {
2155 elem_val = ir_build_load_ptr(irb, node, elem_ptr);2162 elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr);
2156 }2163 }
2157 ir_build_store_ptr(irb, node, elem_var_ptr, elem_val);2164 ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val);
21582165
2159 irb->break_block_stack.append(end_block);2166 irb->break_block_stack.append(end_block);
2160 irb->continue_block_stack.append(continue_block);2167 irb->continue_block_stack.append(continue_block);
...@@ -2162,61 +2169,60 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {...@@ -2162,61 +2169,60 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, AstNode *node) {
2162 irb->break_block_stack.pop();2169 irb->break_block_stack.pop();
2163 irb->continue_block_stack.pop();2170 irb->continue_block_stack.pop();
21642171
2165 ir_build_br(irb, node, continue_block, is_inline);2172 ir_build_br(irb, child_scope, node, continue_block, is_inline);
21662173
2167 ir_set_cursor_at_end(irb, continue_block);2174 ir_set_cursor_at_end(irb, continue_block);
2168 IrInstruction *new_index_val = ir_build_bin_op(irb, node, IrBinOpAdd, index_val, one);2175 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one);
2169 ir_build_store_ptr(irb, node, index_ptr, new_index_val);2176 ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val);
2170 ir_build_br(irb, node, cond_block, is_inline);2177 ir_build_br(irb, child_scope, node, cond_block, is_inline);
21712178
2172 ir_set_cursor_at_end(irb, end_block);2179 ir_set_cursor_at_end(irb, end_block);
2173 return ir_build_const_void(irb, node);2180 return ir_build_const_void(irb, child_scope, node);
21742181
2175}2182}
21762183
2177static IrInstruction *ir_gen_this_literal(IrBuilder *irb, AstNode *node) {2184static IrInstruction *ir_gen_this_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
2178 assert(node->type == NodeTypeThisLiteral);2185 assert(node->type == NodeTypeThisLiteral);
21792186
2180 Scope *scope = node->scope;
2181
2182 if (!scope->parent)2187 if (!scope->parent)
2183 return ir_build_const_import(irb, node, node->owner);2188 return ir_build_const_import(irb, scope, node, node->owner);
21842189
2185 FnTableEntry *fn_entry = scope_fn_entry(scope);2190 FnTableEntry *fn_entry = exec_fn_entry(irb->exec);
2186 if (fn_entry && scope->parent && scope->parent->parent &&2191 if (fn_entry && scope->parent && scope->parent->parent &&
2187 !scope_fn_entry(scope->parent->parent))2192 !scope_fn_entry(scope->parent->parent))
2188 {2193 {
2189 return ir_build_const_fn(irb, node, fn_entry);2194 return ir_build_const_fn(irb, scope, node, fn_entry);
2190 }2195 }
21912196
2192 if (scope->node->type == NodeTypeContainerDecl) {2197 if (scope->node->type == NodeTypeContainerDecl) {
2193 TypeTableEntry *container_type = scope->node->data.struct_decl.type_entry;2198 ScopeDecls *decls_scope = (ScopeDecls *)scope;
2199 TypeTableEntry *container_type = decls_scope->container_type;
2194 assert(container_type);2200 assert(container_type);
2195 return ir_build_const_type(irb, node, container_type);2201 return ir_build_const_type(irb, scope, node, container_type);
2196 }2202 }
21972203
2198 if (scope->node->type == NodeTypeBlock)2204 if (scope->node->type == NodeTypeBlock)
2199 return ir_build_const_scope(irb, node, scope);2205 return ir_build_const_scope(irb, scope, node, scope);
22002206
2201 zig_unreachable();2207 zig_unreachable();
2202}2208}
22032209
2204static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, AstNode *node) {2210static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
2205 assert(node->type == NodeTypeBoolLiteral);2211 assert(node->type == NodeTypeBoolLiteral);
2206 return ir_build_const_bool(irb, node, node->data.bool_literal.value);2212 return ir_build_const_bool(irb, scope, node, node->data.bool_literal.value);
2207}2213}
22082214
2209static IrInstruction *ir_gen_string_literal(IrBuilder *irb, AstNode *node) {2215static IrInstruction *ir_gen_string_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
2210 assert(node->type == NodeTypeStringLiteral);2216 assert(node->type == NodeTypeStringLiteral);
22112217
2212 if (node->data.string_literal.c) {2218 if (node->data.string_literal.c) {
2213 return ir_build_const_c_str_lit(irb, node, node->data.string_literal.buf);2219 return ir_build_const_c_str_lit(irb, scope, node, node->data.string_literal.buf);
2214 } else {2220 } else {
2215 return ir_build_const_str_lit(irb, node, node->data.string_literal.buf);2221 return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf);
2216 }2222 }
2217}2223}
22182224
2219static IrInstruction *ir_gen_array_type(IrBuilder *irb, AstNode *node) {2225static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *node) {
2220 assert(node->type == NodeTypeArrayType);2226 assert(node->type == NodeTypeArrayType);
22212227
2222 AstNode *size_node = node->data.array_type.size;2228 AstNode *size_node = node->data.array_type.size;
...@@ -2229,35 +2235,36 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, AstNode *node) {...@@ -2229,35 +2235,36 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, AstNode *node) {
2229 return irb->codegen->invalid_instruction;2235 return irb->codegen->invalid_instruction;
2230 }2236 }
22312237
2232 IrInstruction *size_value = ir_gen_node(irb, size_node, node->scope);2238 IrInstruction *size_value = ir_gen_node(irb, size_node, scope);
2233 if (size_value == irb->codegen->invalid_instruction)2239 if (size_value == irb->codegen->invalid_instruction)
2234 return size_value;2240 return size_value;
22352241
2236 IrInstruction *child_type = ir_gen_node(irb, child_type_node, node->scope);2242 IrInstruction *child_type = ir_gen_node(irb, child_type_node, scope);
2237 if (child_type == irb->codegen->invalid_instruction)2243 if (child_type == irb->codegen->invalid_instruction)
2238 return child_type;2244 return child_type;
22392245
2240 return ir_build_array_type(irb, node, size_value, child_type);2246 return ir_build_array_type(irb, scope, node, size_value, child_type);
2241 } else {2247 } else {
2242 IrInstruction *child_type = ir_gen_node_extra(irb, child_type_node,2248 IrInstruction *child_type = ir_gen_node_extra(irb, child_type_node,
2243 node->scope, LValPurposeAddressOf);2249 scope, LValPurposeAddressOf);
2244 if (child_type == irb->codegen->invalid_instruction)2250 if (child_type == irb->codegen->invalid_instruction)
2245 return child_type;2251 return child_type;
22462252
2247 return ir_build_slice_type(irb, node, is_const, child_type);2253 return ir_build_slice_type(irb, scope, node, is_const, child_type);
2248 }2254 }
2249}2255}
22502256
2251static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, AstNode *node) {2257static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
2252 assert(node->type == NodeTypeUndefinedLiteral);2258 assert(node->type == NodeTypeUndefinedLiteral);
2253 return ir_build_const_undefined(irb, node);2259 return ir_build_const_undefined(irb, scope, node);
2254}2260}
22552261
2256static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) {2262static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
2257 assert(node->type == NodeTypeAsmExpr);2263 assert(node->type == NodeTypeAsmExpr);
22582264
2259 IrInstruction **input_list = allocate<IrInstruction *>(node->data.asm_expr.input_list.length);2265 IrInstruction **input_list = allocate<IrInstruction *>(node->data.asm_expr.input_list.length);
2260 IrInstruction **output_types = allocate<IrInstruction *>(node->data.asm_expr.output_list.length);2266 IrInstruction **output_types = allocate<IrInstruction *>(node->data.asm_expr.output_list.length);
2267 VariableTableEntry **output_vars = allocate<VariableTableEntry *>(node->data.asm_expr.output_list.length);
2261 size_t return_count = 0;2268 size_t return_count = 0;
2262 bool is_volatile = node->data.asm_expr.is_volatile;2269 bool is_volatile = node->data.asm_expr.is_volatile;
2263 if (!is_volatile && node->data.asm_expr.output_list.length == 0) {2270 if (!is_volatile && node->data.asm_expr.output_list.length == 0) {
...@@ -2270,7 +2277,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) {...@@ -2270,7 +2277,7 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) {
2270 if (asm_output->return_type) {2277 if (asm_output->return_type) {
2271 return_count += 1;2278 return_count += 1;
22722279
2273 IrInstruction *return_type = ir_gen_node(irb, asm_output->return_type, node->scope);2280 IrInstruction *return_type = ir_gen_node(irb, asm_output->return_type, scope);
2274 if (return_type == irb->codegen->invalid_instruction)2281 if (return_type == irb->codegen->invalid_instruction)
2275 return irb->codegen->invalid_instruction;2282 return irb->codegen->invalid_instruction;
2276 if (return_count > 1) {2283 if (return_count > 1) {
...@@ -2281,9 +2288,9 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) {...@@ -2281,9 +2288,9 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) {
2281 output_types[i] = return_type;2288 output_types[i] = return_type;
2282 } else {2289 } else {
2283 Buf *variable_name = asm_output->variable_name;2290 Buf *variable_name = asm_output->variable_name;
2284 VariableTableEntry *var = find_variable(irb->codegen, node->scope, variable_name);2291 VariableTableEntry *var = find_variable(irb->codegen, scope, variable_name);
2285 if (var) {2292 if (var) {
2286 asm_output->variable = var;2293 output_vars[i] = var;
2287 } else {2294 } else {
2288 add_node_error(irb->codegen, node,2295 add_node_error(irb->codegen, node,
2289 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));2296 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
...@@ -2293,17 +2300,17 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) {...@@ -2293,17 +2300,17 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, AstNode *node) {
2293 }2300 }
2294 for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1) {2301 for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1) {
2295 AsmInput *asm_input = node->data.asm_expr.input_list.at(i);2302 AsmInput *asm_input = node->data.asm_expr.input_list.at(i);
2296 IrInstruction *input_value = ir_gen_node(irb, asm_input->expr, node->scope);2303 IrInstruction *input_value = ir_gen_node(irb, asm_input->expr, scope);
2297 if (input_value == irb->codegen->invalid_instruction)2304 if (input_value == irb->codegen->invalid_instruction)
2298 return irb->codegen->invalid_instruction;2305 return irb->codegen->invalid_instruction;
22992306
2300 input_list[i] = input_value;2307 input_list[i] = input_value;
2301 }2308 }
23022309
2303 return ir_build_asm(irb, node, input_list, output_types, return_count, is_volatile);2310 return ir_build_asm(irb, scope, node, input_list, output_types, output_vars, return_count, is_volatile);
2304}2311}
23052312
2306static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) {2313static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
2307 assert(node->type == NodeTypeIfVarExpr);2314 assert(node->type == NodeTypeIfVarExpr);
23082315
2309 AstNodeVariableDeclaration *var_decl = &node->data.if_var_expr.var_decl;2316 AstNodeVariableDeclaration *var_decl = &node->data.if_var_expr.var_decl;
...@@ -2312,51 +2319,51 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) {...@@ -2312,51 +2319,51 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) {
2312 AstNode *else_node = node->data.if_var_expr.else_node;2319 AstNode *else_node = node->data.if_var_expr.else_node;
2313 bool var_is_ptr = node->data.if_var_expr.var_is_ptr;2320 bool var_is_ptr = node->data.if_var_expr.var_is_ptr;
23142321
2315 IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, node->scope, LValPurposeAddressOf);2322 IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValPurposeAddressOf);
2316 if (expr_value == irb->codegen->invalid_instruction)2323 if (expr_value == irb->codegen->invalid_instruction)
2317 return expr_value;2324 return expr_value;
23182325
2319 IrInstruction *is_nonnull_value = ir_build_test_null(irb, node, expr_value);2326 IrInstruction *is_nonnull_value = ir_build_test_null(irb, scope, node, expr_value);
23202327
2321 IrBasicBlock *then_block = ir_build_basic_block(irb, "MaybeThen");2328 IrBasicBlock *then_block = ir_build_basic_block(irb, "MaybeThen");
2322 IrBasicBlock *else_block = ir_build_basic_block(irb, "MaybeElse");2329 IrBasicBlock *else_block = ir_build_basic_block(irb, "MaybeElse");
2323 IrBasicBlock *endif_block = ir_build_basic_block(irb, "MaybeEndIf");2330 IrBasicBlock *endif_block = ir_build_basic_block(irb, "MaybeEndIf");
23242331
2325 bool is_inline = ir_should_inline(irb) || node->data.if_var_expr.is_inline;2332 bool is_inline = ir_should_inline(irb) || node->data.if_var_expr.is_inline;
2326 ir_build_cond_br(irb, node, is_nonnull_value, then_block, else_block, is_inline);2333 ir_build_cond_br(irb, scope, node, is_nonnull_value, then_block, else_block, is_inline);
23272334
2328 ir_set_cursor_at_end(irb, then_block);2335 ir_set_cursor_at_end(irb, then_block);
2329 IrInstruction *var_type = nullptr;2336 IrInstruction *var_type = nullptr;
2330 if (var_decl->type) {2337 if (var_decl->type) {
2331 var_type = ir_gen_node(irb, var_decl->type, node->scope);2338 var_type = ir_gen_node(irb, var_decl->type, scope);
2332 if (var_type == irb->codegen->invalid_instruction)2339 if (var_type == irb->codegen->invalid_instruction)
2333 return irb->codegen->invalid_instruction;2340 return irb->codegen->invalid_instruction;
2334 }2341 }
2335 bool is_shadowable = false;2342 bool is_shadowable = false;
2336 bool is_const = var_decl->is_const;2343 bool is_const = var_decl->is_const;
2337 VariableTableEntry *var = ir_create_var(irb, node, node->scope,2344 VariableTableEntry *var = ir_create_var(irb, node, scope,
2338 var_decl->symbol, is_const, is_const, is_shadowable, is_inline);2345 var_decl->symbol, is_const, is_const, is_shadowable, is_inline);
23392346
2340 IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, node, expr_value, false);2347 IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, scope, node, expr_value, false);
2341 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, node, var_ptr_value);2348 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, node, var_ptr_value);
2342 ir_build_var_decl(irb, node, var, var_type, var_value); 2349 ir_build_var_decl(irb, scope, node, var, var_type, var_value);
2343 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var->child_scope);2350 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var->child_scope);
2344 if (then_expr_result == irb->codegen->invalid_instruction)2351 if (then_expr_result == irb->codegen->invalid_instruction)
2345 return then_expr_result;2352 return then_expr_result;
2346 IrBasicBlock *after_then_block = irb->current_basic_block;2353 IrBasicBlock *after_then_block = irb->current_basic_block;
2347 ir_build_br(irb, node, endif_block, is_inline);2354 ir_build_br(irb, scope, node, endif_block, is_inline);
23482355
2349 ir_set_cursor_at_end(irb, else_block);2356 ir_set_cursor_at_end(irb, else_block);
2350 IrInstruction *else_expr_result;2357 IrInstruction *else_expr_result;
2351 if (else_node) {2358 if (else_node) {
2352 else_expr_result = ir_gen_node(irb, else_node, node->scope);2359 else_expr_result = ir_gen_node(irb, else_node, scope);
2353 if (else_expr_result == irb->codegen->invalid_instruction)2360 if (else_expr_result == irb->codegen->invalid_instruction)
2354 return else_expr_result;2361 return else_expr_result;
2355 } else {2362 } else {
2356 else_expr_result = ir_build_const_void(irb, node);2363 else_expr_result = ir_build_const_void(irb, scope, node);
2357 }2364 }
2358 IrBasicBlock *after_else_block = irb->current_basic_block;2365 IrBasicBlock *after_else_block = irb->current_basic_block;
2359 ir_build_br(irb, node, endif_block, is_inline);2366 ir_build_br(irb, scope, node, endif_block, is_inline);
23602367
2361 ir_set_cursor_at_end(irb, endif_block);2368 ir_set_cursor_at_end(irb, endif_block);
2362 IrInstruction **incoming_values = allocate<IrInstruction *>(2);2369 IrInstruction **incoming_values = allocate<IrInstruction *>(2);
...@@ -2366,10 +2373,10 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) {...@@ -2366,10 +2373,10 @@ static IrInstruction *ir_gen_if_var_expr(IrBuilder *irb, AstNode *node) {
2366 incoming_blocks[0] = after_then_block;2373 incoming_blocks[0] = after_then_block;
2367 incoming_blocks[1] = after_else_block;2374 incoming_blocks[1] = after_else_block;
23682375
2369 return ir_build_phi(irb, node, 2, incoming_blocks, incoming_values);2376 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
2370}2377}
23712378
2372static bool ir_gen_switch_prong_expr(IrBuilder *irb, AstNode *switch_node, AstNode *prong_node,2379static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node,
2373 IrBasicBlock *end_block, bool is_inline, IrInstruction *target_value_ptr, IrInstruction *prong_value,2380 IrBasicBlock *end_block, bool is_inline, IrInstruction *target_value_ptr, IrInstruction *prong_value,
2374 ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values)2381 ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values)
2375{2382{
...@@ -2386,39 +2393,39 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, AstNode *switch_node, AstNo...@@ -2386,39 +2393,39 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, AstNode *switch_node, AstNo
23862393
2387 bool is_shadowable = false;2394 bool is_shadowable = false;
2388 bool is_const = true;2395 bool is_const = true;
2389 VariableTableEntry *var = ir_create_var(irb, var_symbol_node, switch_node->scope,2396 VariableTableEntry *var = ir_create_var(irb, var_symbol_node, scope,
2390 var_name, is_const, is_const, is_shadowable, is_inline);2397 var_name, is_const, is_const, is_shadowable, is_inline);
2391 child_scope = var->child_scope;2398 child_scope = var->child_scope;
2392 IrInstruction *var_value;2399 IrInstruction *var_value;
2393 if (prong_value) {2400 if (prong_value) {
2394 IrInstruction *var_ptr_value = ir_build_switch_var(irb, var_symbol_node, target_value_ptr, prong_value);2401 IrInstruction *var_ptr_value = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, prong_value);
2395 var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, var_symbol_node, var_ptr_value);2402 var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value);
2396 } else {2403 } else {
2397 var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, var_symbol_node, target_value_ptr);2404 var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr);
2398 }2405 }
2399 IrInstruction *var_type = nullptr; // infer the type2406 IrInstruction *var_type = nullptr; // infer the type
2400 ir_build_var_decl(irb, var_symbol_node, var, var_type, var_value); 2407 ir_build_var_decl(irb, scope, var_symbol_node, var, var_type, var_value);
2401 } else {2408 } else {
2402 child_scope = switch_node->scope;2409 child_scope = scope;
2403 }2410 }
24042411
2405 IrInstruction *expr_result = ir_gen_node(irb, expr_node, child_scope);2412 IrInstruction *expr_result = ir_gen_node(irb, expr_node, child_scope);
2406 if (expr_result == irb->codegen->invalid_instruction)2413 if (expr_result == irb->codegen->invalid_instruction)
2407 return false;2414 return false;
2408 ir_build_br(irb, switch_node, end_block, is_inline);2415 ir_build_br(irb, scope, switch_node, end_block, is_inline);
2409 incoming_blocks->append(irb->current_basic_block);2416 incoming_blocks->append(irb->current_basic_block);
2410 incoming_values->append(expr_result);2417 incoming_values->append(expr_result);
2411 return true;2418 return true;
2412}2419}
24132420
2414static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {2421static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
2415 assert(node->type == NodeTypeSwitchExpr);2422 assert(node->type == NodeTypeSwitchExpr);
24162423
2417 AstNode *target_node = node->data.switch_expr.expr;2424 AstNode *target_node = node->data.switch_expr.expr;
2418 IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, node->scope, LValPurposeAddressOf);2425 IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPurposeAddressOf);
2419 if (target_value_ptr == irb->codegen->invalid_instruction)2426 if (target_value_ptr == irb->codegen->invalid_instruction)
2420 return target_value_ptr;2427 return target_value_ptr;
2421 IrInstruction *target_value = ir_build_switch_target(irb, node, target_value_ptr);2428 IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr);
24222429
2423 IrBasicBlock *else_block = ir_build_basic_block(irb, "SwitchElse");2430 IrBasicBlock *else_block = ir_build_basic_block(irb, "SwitchElse");
2424 IrBasicBlock *end_block = ir_build_basic_block(irb, "SwitchEnd");2431 IrBasicBlock *end_block = ir_build_basic_block(irb, "SwitchEnd");
...@@ -2446,7 +2453,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {...@@ -2446,7 +2453,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
24462453
2447 IrBasicBlock *prev_block = irb->current_basic_block;2454 IrBasicBlock *prev_block = irb->current_basic_block;
2448 ir_set_cursor_at_end(irb, else_block);2455 ir_set_cursor_at_end(irb, else_block);
2449 if (!ir_gen_switch_prong_expr(irb, node, prong_node, end_block,2456 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
2450 is_inline, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))2457 is_inline, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))
2451 {2458 {
2452 return irb->codegen->invalid_instruction;2459 return irb->codegen->invalid_instruction;
...@@ -2460,41 +2467,40 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {...@@ -2460,41 +2467,40 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
2460 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);2467 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
2461 last_item_node = item_node;2468 last_item_node = item_node;
2462 if (item_node->type == NodeTypeSwitchRange) {2469 if (item_node->type == NodeTypeSwitchRange) {
2463 item_node->scope = node->scope;
2464 AstNode *start_node = item_node->data.switch_range.start;2470 AstNode *start_node = item_node->data.switch_range.start;
2465 AstNode *end_node = item_node->data.switch_range.end;2471 AstNode *end_node = item_node->data.switch_range.end;
24662472
2467 IrInstruction *start_value = ir_gen_node(irb, start_node, node->scope);2473 IrInstruction *start_value = ir_gen_node(irb, start_node, scope);
2468 if (start_value == irb->codegen->invalid_instruction)2474 if (start_value == irb->codegen->invalid_instruction)
2469 return irb->codegen->invalid_instruction;2475 return irb->codegen->invalid_instruction;
24702476
2471 IrInstruction *end_value = ir_gen_node(irb, end_node, node->scope);2477 IrInstruction *end_value = ir_gen_node(irb, end_node, scope);
2472 if (end_value == irb->codegen->invalid_instruction)2478 if (end_value == irb->codegen->invalid_instruction)
2473 return irb->codegen->invalid_instruction;2479 return irb->codegen->invalid_instruction;
24742480
2475 IrInstruction *start_value_const = ir_build_static_eval(irb, start_node, start_value);2481 IrInstruction *start_value_const = ir_build_static_eval(irb, scope, start_node, start_value);
2476 IrInstruction *end_value_const = ir_build_static_eval(irb, start_node, end_value);2482 IrInstruction *end_value_const = ir_build_static_eval(irb, scope, start_node, end_value);
24772483
2478 IrInstruction *lower_range_ok = ir_build_bin_op(irb, item_node, IrBinOpCmpGreaterOrEq,2484 IrInstruction *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq,
2479 target_value, start_value_const);2485 target_value, start_value_const);
2480 IrInstruction *upper_range_ok = ir_build_bin_op(irb, item_node, IrBinOpCmpLessOrEq,2486 IrInstruction *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq,
2481 target_value, end_value_const);2487 target_value, end_value_const);
2482 IrInstruction *both_ok = ir_build_bin_op(irb, item_node, IrBinOpBoolAnd,2488 IrInstruction *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd,
2483 lower_range_ok, upper_range_ok);2489 lower_range_ok, upper_range_ok);
2484 if (ok_bit) {2490 if (ok_bit) {
2485 ok_bit = ir_build_bin_op(irb, item_node, IrBinOpBoolOr, both_ok, ok_bit);2491 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit);
2486 } else {2492 } else {
2487 ok_bit = both_ok;2493 ok_bit = both_ok;
2488 }2494 }
2489 } else {2495 } else {
2490 IrInstruction *item_value = ir_gen_node(irb, item_node, node->scope);2496 IrInstruction *item_value = ir_gen_node(irb, item_node, scope);
2491 if (item_value == irb->codegen->invalid_instruction)2497 if (item_value == irb->codegen->invalid_instruction)
2492 return irb->codegen->invalid_instruction;2498 return irb->codegen->invalid_instruction;
24932499
2494 IrInstruction *cmp_ok = ir_build_bin_op(irb, item_node, IrBinOpCmpEq,2500 IrInstruction *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq,
2495 item_value, target_value);2501 item_value, target_value);
2496 if (ok_bit) {2502 if (ok_bit) {
2497 ok_bit = ir_build_bin_op(irb, item_node, IrBinOpBoolOr, cmp_ok, ok_bit);2503 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit);
2498 } else {2504 } else {
2499 ok_bit = cmp_ok;2505 ok_bit = cmp_ok;
2500 }2506 }
...@@ -2506,10 +2512,10 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {...@@ -2506,10 +2512,10 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
25062512
2507 assert(ok_bit);2513 assert(ok_bit);
2508 assert(last_item_node);2514 assert(last_item_node);
2509 ir_build_cond_br(irb, last_item_node, ok_bit, range_block_yes, range_block_no, is_inline);2515 ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, range_block_no, is_inline);
25102516
2511 ir_set_cursor_at_end(irb, range_block_yes);2517 ir_set_cursor_at_end(irb, range_block_yes);
2512 if (!ir_gen_switch_prong_expr(irb, node, prong_node, end_block,2518 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
2513 is_inline, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))2519 is_inline, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))
2514 {2520 {
2515 return irb->codegen->invalid_instruction;2521 return irb->codegen->invalid_instruction;
...@@ -2524,7 +2530,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {...@@ -2524,7 +2530,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
2524 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);2530 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
2525 assert(item_node->type != NodeTypeSwitchRange);2531 assert(item_node->type != NodeTypeSwitchRange);
25262532
2527 IrInstruction *item_value = ir_gen_node(irb, item_node, node->scope);2533 IrInstruction *item_value = ir_gen_node(irb, item_node, scope);
2528 if (item_value == irb->codegen->invalid_instruction)2534 if (item_value == irb->codegen->invalid_instruction)
2529 return irb->codegen->invalid_instruction;2535 return irb->codegen->invalid_instruction;
25302536
...@@ -2538,7 +2544,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {...@@ -2538,7 +2544,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
25382544
2539 IrBasicBlock *prev_block = irb->current_basic_block;2545 IrBasicBlock *prev_block = irb->current_basic_block;
2540 ir_set_cursor_at_end(irb, prong_block);2546 ir_set_cursor_at_end(irb, prong_block);
2541 if (!ir_gen_switch_prong_expr(irb, node, prong_node, end_block,2547 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
2542 is_inline, target_value_ptr, only_item_value, &incoming_blocks, &incoming_values))2548 is_inline, target_value_ptr, only_item_value, &incoming_blocks, &incoming_values))
2543 {2549 {
2544 return irb->codegen->invalid_instruction;2550 return irb->codegen->invalid_instruction;
...@@ -2551,19 +2557,19 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {...@@ -2551,19 +2557,19 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, AstNode *node) {
2551 }2557 }
25522558
2553 if (cases.length == 0) {2559 if (cases.length == 0) {
2554 ir_build_br(irb, node, else_block, is_inline);2560 ir_build_br(irb, scope, node, else_block, is_inline);
2555 } else {2561 } else {
2556 ir_build_switch_br(irb, node, target_value, else_block, cases.length, cases.items, is_inline);2562 ir_build_switch_br(irb, scope, node, target_value, else_block, cases.length, cases.items, is_inline);
2557 }2563 }
25582564
2559 if (!else_prong) {2565 if (!else_prong) {
2560 ir_set_cursor_at_end(irb, else_block);2566 ir_set_cursor_at_end(irb, else_block);
2561 ir_build_unreachable(irb, node);2567 ir_build_unreachable(irb, scope, node);
2562 }2568 }
25632569
2564 ir_set_cursor_at_end(irb, end_block);2570 ir_set_cursor_at_end(irb, end_block);
2565 assert(incoming_blocks.length == incoming_values.length);2571 assert(incoming_blocks.length == incoming_values.length);
2566 return ir_build_phi(irb, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);2572 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
2567}2573}
25682574
2569static LabelTableEntry *find_label(IrExecutable *exec, Scope *scope, Buf *name) {2575static LabelTableEntry *find_label(IrExecutable *exec, Scope *scope, Buf *name) {
...@@ -2589,7 +2595,7 @@ static ScopeBlock *find_block_scope(IrExecutable *exec, Scope *scope) {...@@ -2589,7 +2595,7 @@ static ScopeBlock *find_block_scope(IrExecutable *exec, Scope *scope) {
2589 return nullptr;2595 return nullptr;
2590}2596}
25912597
2592static IrInstruction *ir_gen_label(IrBuilder *irb, AstNode *node) {2598static IrInstruction *ir_gen_label(IrBuilder *irb, Scope *scope, AstNode *node) {
2593 assert(node->type == NodeTypeLabel);2599 assert(node->type == NodeTypeLabel);
25942600
2595 Buf *label_name = node->data.label.name;2601 Buf *label_name = node->data.label.name;
...@@ -2599,35 +2605,38 @@ static IrInstruction *ir_gen_label(IrBuilder *irb, AstNode *node) {...@@ -2599,35 +2605,38 @@ static IrInstruction *ir_gen_label(IrBuilder *irb, AstNode *node) {
2599 label->bb = label_block;2605 label->bb = label_block;
2600 irb->exec->all_labels.append(label);2606 irb->exec->all_labels.append(label);
26012607
2602 LabelTableEntry *existing_label = find_label(irb->exec, node->scope, label_name);2608 LabelTableEntry *existing_label = find_label(irb->exec, scope, label_name);
2603 if (existing_label) {2609 if (existing_label) {
2604 ErrorMsg *msg = add_node_error(irb->codegen, node,2610 ErrorMsg *msg = add_node_error(irb->codegen, node,
2605 buf_sprintf("duplicate label name '%s'", buf_ptr(label_name)));2611 buf_sprintf("duplicate label name '%s'", buf_ptr(label_name)));
2606 add_error_note(irb->codegen, msg, existing_label->decl_node, buf_sprintf("other label here"));2612 add_error_note(irb->codegen, msg, existing_label->decl_node, buf_sprintf("other label here"));
2607 return irb->codegen->invalid_instruction;2613 return irb->codegen->invalid_instruction;
2608 } else {2614 } else {
2609 ScopeBlock *scope_block = find_block_scope(irb->exec, node->scope);2615 ScopeBlock *scope_block = find_block_scope(irb->exec, scope);
2610 scope_block->label_table.put(label_name, label);2616 scope_block->label_table.put(label_name, label);
2611 }2617 }
26122618
2613 bool is_inline = ir_should_inline(irb);2619 bool is_inline = ir_should_inline(irb);
2614 ir_build_br(irb, node, label_block, is_inline);2620 ir_build_br(irb, scope, node, label_block, is_inline);
2615 ir_set_cursor_at_end(irb, label_block);2621 ir_set_cursor_at_end(irb, label_block);
2616 return ir_build_const_void(irb, node);2622 return ir_build_const_void(irb, scope, node);
2617}2623}
26182624
2619static IrInstruction *ir_gen_goto(IrBuilder *irb, AstNode *node) {2625static IrInstruction *ir_gen_goto(IrBuilder *irb, Scope *scope, AstNode *node) {
2620 assert(node->type == NodeTypeGoto);2626 assert(node->type == NodeTypeGoto);
26212627
2622 // make a placeholder unreachable statement and a note to come back and2628 // make a placeholder unreachable statement and a note to come back and
2623 // replace the instruction with a branch instruction2629 // replace the instruction with a branch instruction
2624 node->data.goto_expr.bb = irb->current_basic_block;2630 IrGotoItem *goto_item = irb->exec->goto_list.add_one();
2625 node->data.goto_expr.instruction_index = irb->current_basic_block->instruction_list.length;2631 goto_item->bb = irb->current_basic_block;
2626 irb->exec->goto_list.append(node);2632 goto_item->instruction_index = irb->current_basic_block->instruction_list.length;
2627 return ir_build_unreachable(irb, node);2633 goto_item->source_node = node;
2634 goto_item->scope = scope;
2635
2636 return ir_build_unreachable(irb, scope, node);
2628}2637}
26292638
2630static IrInstruction *ir_lval_wrap(IrBuilder *irb, IrInstruction *value, LValPurpose lval) {2639static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LValPurpose lval) {
2631 if (lval == LValPurposeNone)2640 if (lval == LValPurposeNone)
2632 return value;2641 return value;
2633 if (value == irb->codegen->invalid_instruction)2642 if (value == irb->codegen->invalid_instruction)
...@@ -2635,75 +2644,73 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, IrInstruction *value, LValPur...@@ -2635,75 +2644,73 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, IrInstruction *value, LValPur
26352644
2636 // We needed a pointer to a value, but we got a value. So we create2645 // We needed a pointer to a value, but we got a value. So we create
2637 // an instruction which just makes a const pointer of it.2646 // an instruction which just makes a const pointer of it.
2638 return ir_build_ref(irb, value->source_node, value);2647 return ir_build_ref(irb, scope, value->source_node, value);
2639}2648}
26402649
2641static IrInstruction *ir_gen_type_literal(IrBuilder *irb, AstNode *node) {2650static IrInstruction *ir_gen_type_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
2642 assert(node->type == NodeTypeTypeLiteral);2651 assert(node->type == NodeTypeTypeLiteral);
2643 return ir_build_const_type(irb, node, irb->codegen->builtin_types.entry_type);2652 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_type);
2644}2653}
26452654
2646static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,2655static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,
2647 LValPurpose lval)2656 LValPurpose lval)
2648{2657{
2649 assert(scope);2658 assert(scope);
2650 node->scope = scope;
2651
2652 switch (node->type) {2659 switch (node->type) {
2653 case NodeTypeStructValueField:2660 case NodeTypeStructValueField:
2654 zig_unreachable();2661 zig_unreachable();
2655 case NodeTypeBlock:2662 case NodeTypeBlock:
2656 return ir_lval_wrap(irb, ir_gen_block(irb, node), lval);2663 return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval);
2657 case NodeTypeBinOpExpr:2664 case NodeTypeBinOpExpr:
2658 return ir_lval_wrap(irb, ir_gen_bin_op(irb, node), lval);2665 return ir_lval_wrap(irb, scope, ir_gen_bin_op(irb, scope, node), lval);
2659 case NodeTypeNumberLiteral:2666 case NodeTypeNumberLiteral:
2660 return ir_lval_wrap(irb, ir_gen_num_lit(irb, node), lval);2667 return ir_lval_wrap(irb, scope, ir_gen_num_lit(irb, scope, node), lval);
2661 case NodeTypeSymbol:2668 case NodeTypeSymbol:
2662 return ir_gen_symbol(irb, node, lval);2669 return ir_gen_symbol(irb, scope, node, lval);
2663 case NodeTypeFnCallExpr:2670 case NodeTypeFnCallExpr:
2664 return ir_lval_wrap(irb, ir_gen_fn_call(irb, node), lval);2671 return ir_lval_wrap(irb, scope, ir_gen_fn_call(irb, scope, node), lval);
2665 case NodeTypeIfBoolExpr:2672 case NodeTypeIfBoolExpr:
2666 return ir_lval_wrap(irb, ir_gen_if_bool_expr(irb, node), lval);2673 return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval);
2667 case NodeTypePrefixOpExpr:2674 case NodeTypePrefixOpExpr:
2668 return ir_gen_prefix_op_expr(irb, node, lval);2675 return ir_gen_prefix_op_expr(irb, scope, node, lval);
2669 case NodeTypeContainerInitExpr:2676 case NodeTypeContainerInitExpr:
2670 return ir_lval_wrap(irb, ir_gen_container_init_expr(irb, node), lval);2677 return ir_lval_wrap(irb, scope, ir_gen_container_init_expr(irb, scope, node), lval);
2671 case NodeTypeVariableDeclaration:2678 case NodeTypeVariableDeclaration:
2672 return ir_lval_wrap(irb, ir_gen_var_decl(irb, node), lval);2679 return ir_lval_wrap(irb, scope, ir_gen_var_decl(irb, scope, node), lval);
2673 case NodeTypeWhileExpr:2680 case NodeTypeWhileExpr:
2674 return ir_lval_wrap(irb, ir_gen_while_expr(irb, node), lval);2681 return ir_lval_wrap(irb, scope, ir_gen_while_expr(irb, scope, node), lval);
2675 case NodeTypeForExpr:2682 case NodeTypeForExpr:
2676 return ir_lval_wrap(irb, ir_gen_for_expr(irb, node), lval);2683 return ir_lval_wrap(irb, scope, ir_gen_for_expr(irb, scope, node), lval);
2677 case NodeTypeArrayAccessExpr:2684 case NodeTypeArrayAccessExpr:
2678 return ir_gen_array_access(irb, node, lval);2685 return ir_gen_array_access(irb, scope, node, lval);
2679 case NodeTypeReturnExpr:2686 case NodeTypeReturnExpr:
2680 return ir_lval_wrap(irb, ir_gen_return(irb, node), lval);2687 return ir_lval_wrap(irb, scope, ir_gen_return(irb, scope, node), lval);
2681 case NodeTypeFieldAccessExpr:2688 case NodeTypeFieldAccessExpr:
2682 return ir_gen_field_access(irb, node, lval);2689 return ir_gen_field_access(irb, scope, node, lval);
2683 case NodeTypeThisLiteral:2690 case NodeTypeThisLiteral:
2684 return ir_lval_wrap(irb, ir_gen_this_literal(irb, node), lval);2691 return ir_lval_wrap(irb, scope, ir_gen_this_literal(irb, scope, node), lval);
2685 case NodeTypeBoolLiteral:2692 case NodeTypeBoolLiteral:
2686 return ir_lval_wrap(irb, ir_gen_bool_literal(irb, node), lval);2693 return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval);
2687 case NodeTypeArrayType:2694 case NodeTypeArrayType:
2688 return ir_lval_wrap(irb, ir_gen_array_type(irb, node), lval);2695 return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval);
2689 case NodeTypeStringLiteral:2696 case NodeTypeStringLiteral:
2690 return ir_lval_wrap(irb, ir_gen_string_literal(irb, node), lval);2697 return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval);
2691 case NodeTypeUndefinedLiteral:2698 case NodeTypeUndefinedLiteral:
2692 return ir_lval_wrap(irb, ir_gen_undefined_literal(irb, node), lval);2699 return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval);
2693 case NodeTypeAsmExpr:2700 case NodeTypeAsmExpr:
2694 return ir_lval_wrap(irb, ir_gen_asm_expr(irb, node), lval);2701 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval);
2695 case NodeTypeNullLiteral:2702 case NodeTypeNullLiteral:
2696 return ir_lval_wrap(irb, ir_gen_null_literal(irb, node), lval);2703 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval);
2697 case NodeTypeIfVarExpr:2704 case NodeTypeIfVarExpr:
2698 return ir_lval_wrap(irb, ir_gen_if_var_expr(irb, node), lval);2705 return ir_lval_wrap(irb, scope, ir_gen_if_var_expr(irb, scope, node), lval);
2699 case NodeTypeSwitchExpr:2706 case NodeTypeSwitchExpr:
2700 return ir_lval_wrap(irb, ir_gen_switch_expr(irb, node), lval);2707 return ir_lval_wrap(irb, scope, ir_gen_switch_expr(irb, scope, node), lval);
2701 case NodeTypeLabel:2708 case NodeTypeLabel:
2702 return ir_lval_wrap(irb, ir_gen_label(irb, node), lval);2709 return ir_lval_wrap(irb, scope, ir_gen_label(irb, scope, node), lval);
2703 case NodeTypeGoto:2710 case NodeTypeGoto:
2704 return ir_lval_wrap(irb, ir_gen_goto(irb, node), lval);2711 return ir_lval_wrap(irb, scope, ir_gen_goto(irb, scope, node), lval);
2705 case NodeTypeTypeLiteral:2712 case NodeTypeTypeLiteral:
2706 return ir_lval_wrap(irb, ir_gen_type_literal(irb, node), lval);2713 return ir_lval_wrap(irb, scope, ir_gen_type_literal(irb, scope, node), lval);
2707 case NodeTypeUnwrapErrorExpr:2714 case NodeTypeUnwrapErrorExpr:
2708 case NodeTypeDefer:2715 case NodeTypeDefer:
2709 case NodeTypeSliceExpr:2716 case NodeTypeSliceExpr:
...@@ -2744,22 +2751,23 @@ static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) {...@@ -2744,22 +2751,23 @@ static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) {
27442751
2745static bool ir_goto_pass2(IrBuilder *irb) {2752static bool ir_goto_pass2(IrBuilder *irb) {
2746 for (size_t i = 0; i < irb->exec->goto_list.length; i += 1) {2753 for (size_t i = 0; i < irb->exec->goto_list.length; i += 1) {
2747 AstNode *goto_node = irb->exec->goto_list.at(i);2754 IrGotoItem *goto_item = &irb->exec->goto_list.at(i);
2748 size_t instruction_index = goto_node->data.goto_expr.instruction_index;2755 AstNode *source_node = goto_item->source_node;
2749 IrInstruction **slot = &goto_node->data.goto_expr.bb->instruction_list.at(instruction_index);2756 size_t instruction_index = goto_item->instruction_index;
2757 IrInstruction **slot = &goto_item->bb->instruction_list.at(instruction_index);
2750 IrInstruction *old_instruction = *slot;2758 IrInstruction *old_instruction = *slot;
27512759
2752 Buf *label_name = goto_node->data.goto_expr.name;2760 Buf *label_name = source_node->data.goto_expr.name;
2753 LabelTableEntry *label = find_label(irb->exec, goto_node->scope, label_name);2761 LabelTableEntry *label = find_label(irb->exec, goto_item->scope, label_name);
2754 if (!label) {2762 if (!label) {
2755 add_node_error(irb->codegen, goto_node,2763 add_node_error(irb->codegen, source_node,
2756 buf_sprintf("no label in scope named '%s'", buf_ptr(label_name)));2764 buf_sprintf("no label in scope named '%s'", buf_ptr(label_name)));
2757 return false;2765 return false;
2758 }2766 }
2759 label->used = true;2767 label->used = true;
27602768
2761 bool is_inline = ir_should_inline(irb) || goto_node->data.goto_expr.is_inline;2769 bool is_inline = ir_should_inline(irb) || source_node->data.goto_expr.is_inline;
2762 IrInstruction *new_instruction = ir_create_br(irb, goto_node, label->bb, is_inline);2770 IrInstruction *new_instruction = ir_create_br(irb, goto_item->scope, source_node, label->bb, is_inline);
2763 new_instruction->ref_count = old_instruction->ref_count;2771 new_instruction->ref_count = old_instruction->ref_count;
2764 *slot = new_instruction;2772 *slot = new_instruction;
2765 }2773 }
...@@ -2795,7 +2803,7 @@ IrInstruction *ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutabl...@@ -2795,7 +2803,7 @@ IrInstruction *ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutabl
2795 if (irb->exec->invalid)2803 if (irb->exec->invalid)
2796 return codegen->invalid_instruction;2804 return codegen->invalid_instruction;
27972805
2798 IrInstruction *return_instruction = ir_build_return(irb, result->source_node, result);2806 IrInstruction *return_instruction = ir_build_return(irb, scope, result->source_node, result);
2799 assert(return_instruction);2807 assert(return_instruction);
28002808
2801 if (!ir_goto_pass2(irb)) {2809 if (!ir_goto_pass2(irb)) {
...@@ -2814,21 +2822,27 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {...@@ -2814,21 +2822,27 @@ IrInstruction *ir_gen_fn(CodeGen *codegn, FnTableEntry *fn_entry) {
2814 assert(fn_def_node->type == NodeTypeFnDef);2822 assert(fn_def_node->type == NodeTypeFnDef);
28152823
2816 AstNode *body_node = fn_def_node->data.fn_def.body;2824 AstNode *body_node = fn_def_node->data.fn_def.body;
2817 Scope *child_scope = fn_def_node->data.fn_def.child_scope;2825
2826 assert(fn_entry->child_scope);
2827 Scope *child_scope = fn_entry->child_scope;
28182828
2819 return ir_gen(codegn, body_node, child_scope, ir_executable);2829 return ir_gen(codegn, body_node, child_scope, ir_executable);
2820}2830}
28212831
2832static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction, Buf *msg) {
2833 return add_node_error(ira->codegen, source_instruction->source_node, msg);
2834}
2835
2822static IrInstruction *ir_eval_fn(IrAnalyze *ira, IrInstruction *source_instruction,2836static IrInstruction *ir_eval_fn(IrAnalyze *ira, IrInstruction *source_instruction,
2823 size_t arg_count, IrInstruction **args)2837 size_t arg_count, IrInstruction **args)
2824{2838{
2839 // TODO count this as part of the backward branch quota
2825 zig_panic("TODO ir_eval_fn");2840 zig_panic("TODO ir_eval_fn");
2826}2841}
28272842
2828static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) {2843static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) {
2829 if (ir_should_inline(&ira->new_irb)) {2844 if (ir_should_inline(&ira->new_irb)) {
2830 add_node_error(ira->codegen, source_instruction->source_node,2845 ir_add_error(ira, source_instruction, buf_sprintf("unable to evaluate constant expression"));
2831 buf_sprintf("unable to evaluate constant expression"));
2832 return false;2846 return false;
2833 }2847 }
2834 return true;2848 return true;
...@@ -2863,7 +2877,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc...@@ -2863,7 +2877,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
28632877
2864 const char *num_lit_str = (const_val->data.x_bignum.kind == BigNumKindFloat) ? "float" : "integer";2878 const char *num_lit_str = (const_val->data.x_bignum.kind == BigNumKindFloat) ? "float" : "integer";
28652879
2866 add_node_error(ira->codegen, instruction->source_node,2880 ir_add_error(ira, instruction,
2867 buf_sprintf("%s value %s cannot be implicitly casted to type '%s'",2881 buf_sprintf("%s value %s cannot be implicitly casted to type '%s'",
2868 num_lit_str,2882 num_lit_str,
2869 buf_ptr(bignum_to_buf(&const_val->data.x_bignum)),2883 buf_ptr(bignum_to_buf(&const_val->data.x_bignum)),
...@@ -3052,15 +3066,15 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -3052,15 +3066,15 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst
3052 TypeTableEntry *wanted_type, CastOp cast_op, bool need_alloca)3066 TypeTableEntry *wanted_type, CastOp cast_op, bool need_alloca)
3053{3067{
3054 if (value->static_value.special != ConstValSpecialRuntime) {3068 if (value->static_value.special != ConstValSpecialRuntime) {
3055 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->source_node, wanted_type, false);3069 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, false);
3056 eval_const_expr_implicit_cast(cast_op, &value->static_value, value->type_entry,3070 eval_const_expr_implicit_cast(cast_op, &value->static_value, value->type_entry,
3057 &result->static_value, wanted_type);3071 &result->static_value, wanted_type);
3058 return result;3072 return result;
3059 } else {3073 } else {
3060 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->source_node, wanted_type, value, cast_op);3074 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op);
3061 result->type_entry = wanted_type;3075 result->type_entry = wanted_type;
3062 if (need_alloca) {3076 if (need_alloca) {
3063 FnTableEntry *fn_entry = scope_fn_entry(source_instr->source_node->scope);3077 FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
3064 if (fn_entry)3078 if (fn_entry)
3065 fn_entry->alloca_list.append(result);3079 fn_entry->alloca_list.append(result);
3066 }3080 }
...@@ -3153,20 +3167,20 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in...@@ -3153,20 +3167,20 @@ static ConstExprValue *ir_build_const_from(IrAnalyze *ira, IrInstruction *old_in
3153 if (old_instruction->id == IrInstructionIdVarPtr) {3167 if (old_instruction->id == IrInstructionIdVarPtr) {
3154 IrInstructionVarPtr *old_var_ptr_instruction = (IrInstructionVarPtr *)old_instruction;3168 IrInstructionVarPtr *old_var_ptr_instruction = (IrInstructionVarPtr *)old_instruction;
3155 IrInstructionVarPtr *var_ptr_instruction = ir_create_instruction<IrInstructionVarPtr>(ira->new_irb.exec,3169 IrInstructionVarPtr *var_ptr_instruction = ir_create_instruction<IrInstructionVarPtr>(ira->new_irb.exec,
3156 old_instruction->source_node);3170 old_instruction->scope, old_instruction->source_node);
3157 var_ptr_instruction->var = old_var_ptr_instruction->var;3171 var_ptr_instruction->var = old_var_ptr_instruction->var;
3158 new_instruction = &var_ptr_instruction->base;3172 new_instruction = &var_ptr_instruction->base;
3159 } else if (old_instruction->id == IrInstructionIdFieldPtr) {3173 } else if (old_instruction->id == IrInstructionIdFieldPtr) {
3160 IrInstructionFieldPtr *field_ptr_instruction = ir_create_instruction<IrInstructionFieldPtr>(ira->new_irb.exec,3174 IrInstructionFieldPtr *field_ptr_instruction = ir_create_instruction<IrInstructionFieldPtr>(ira->new_irb.exec,
3161 old_instruction->source_node);3175 old_instruction->scope, old_instruction->source_node);
3162 new_instruction = &field_ptr_instruction->base;3176 new_instruction = &field_ptr_instruction->base;
3163 } else if (old_instruction->id == IrInstructionIdElemPtr) {3177 } else if (old_instruction->id == IrInstructionIdElemPtr) {
3164 IrInstructionElemPtr *elem_ptr_instruction = ir_create_instruction<IrInstructionElemPtr>(ira->new_irb.exec,3178 IrInstructionElemPtr *elem_ptr_instruction = ir_create_instruction<IrInstructionElemPtr>(ira->new_irb.exec,
3165 old_instruction->source_node);3179 old_instruction->scope, old_instruction->source_node);
3166 new_instruction = &elem_ptr_instruction->base;3180 new_instruction = &elem_ptr_instruction->base;
3167 } else {3181 } else {
3168 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(ira->new_irb.exec,3182 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(ira->new_irb.exec,
3169 old_instruction->source_node);3183 old_instruction->scope, old_instruction->source_node);
3170 new_instruction = &const_instruction->base;3184 new_instruction = &const_instruction->base;
3171 }3185 }
3172 ir_link_new_instruction(new_instruction, old_instruction);3186 ir_link_new_instruction(new_instruction, old_instruction);
...@@ -3553,13 +3567,13 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc...@@ -3553,13 +3567,13 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
3553 if (ptr->static_value.special != ConstValSpecialRuntime) {3567 if (ptr->static_value.special != ConstValSpecialRuntime) {
3554 ConstExprValue *pointee = const_ptr_pointee(&ptr->static_value);3568 ConstExprValue *pointee = const_ptr_pointee(&ptr->static_value);
3555 if (pointee->special != ConstValSpecialRuntime) {3569 if (pointee->special != ConstValSpecialRuntime) {
3556 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->source_node,3570 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope,
3557 child_type, pointee->depends_on_compile_var);3571 source_instruction->source_node, child_type, pointee->depends_on_compile_var);
3558 result->static_value = *pointee;3572 result->static_value = *pointee;
3559 return result;3573 return result;
3560 }3574 }
3561 }3575 }
3562 IrInstruction *load_ptr_instruction = ir_build_load_ptr(&ira->new_irb, source_instruction->source_node, ptr);3576 IrInstruction *load_ptr_instruction = ir_build_load_ptr(&ira->new_irb, source_instruction->scope, source_instruction->source_node, ptr);
3563 load_ptr_instruction->type_entry = child_type;3577 load_ptr_instruction->type_entry = child_type;
3564 return load_ptr_instruction;3578 return load_ptr_instruction;
3565 } else {3579 } else {
...@@ -3588,7 +3602,7 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst...@@ -3588,7 +3602,7 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst
3588 ir_link_new_instruction(value, source_instruction);3602 ir_link_new_instruction(value, source_instruction);
3589 return ptr_type;3603 return ptr_type;
3590 } else {3604 } else {
3591 FnTableEntry *fn_entry = scope_fn_entry(source_instruction->source_node->scope);3605 FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
3592 assert(fn_entry);3606 assert(fn_entry);
3593 IrInstruction *new_instruction = ir_build_ref_from(&ira->new_irb, source_instruction, value);3607 IrInstruction *new_instruction = ir_build_ref_from(&ira->new_irb, source_instruction, value);
3594 fn_entry->alloca_list.append(new_instruction);3608 fn_entry->alloca_list.append(new_instruction);
...@@ -3754,7 +3768,6 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -3754,7 +3768,6 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
3754 case TypeTableEntryIdTypeDecl:3768 case TypeTableEntryIdTypeDecl:
3755 case TypeTableEntryIdNamespace:3769 case TypeTableEntryIdNamespace:
3756 case TypeTableEntryIdBlock:3770 case TypeTableEntryIdBlock:
3757 case TypeTableEntryIdGenericFn:
3758 case TypeTableEntryIdBoundFn:3771 case TypeTableEntryIdBoundFn:
3759 if (!is_equality_cmp) {3772 if (!is_equality_cmp) {
3760 add_node_error(ira->codegen, source_node,3773 add_node_error(ira->codegen, source_node,
...@@ -4057,7 +4070,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -4057,7 +4070,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
4057 }4070 }
40584071
4059 AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration;4072 AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration;
4060 bool is_export = (variable_declaration->top_level_decl.visib_mod == VisibModExport);4073 bool is_export = (variable_declaration->visib_mod == VisibModExport);
4061 bool is_extern = variable_declaration->is_extern;4074 bool is_extern = variable_declaration->is_extern;
40624075
4063 var->ref_count = 0;4076 var->ref_count = 0;
...@@ -4119,7 +4132,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -4119,7 +4132,6 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
4119 case TypeTableEntryIdEnum:4132 case TypeTableEntryIdEnum:
4120 case TypeTableEntryIdUnion:4133 case TypeTableEntryIdUnion:
4121 case TypeTableEntryIdFn:4134 case TypeTableEntryIdFn:
4122 case TypeTableEntryIdGenericFn:
4123 case TypeTableEntryIdBoundFn:4135 case TypeTableEntryIdBoundFn:
4124 // OK4136 // OK
4125 break;4137 break;
...@@ -4136,8 +4148,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -4136,8 +4148,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
41364148
4137 ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value);4149 ir_build_var_decl_from(&ira->new_irb, &decl_var_instruction->base, var, var_type, casted_init_value);
41384150
4139 Scope *scope = decl_var_instruction->base.source_node->scope;4151 FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
4140 FnTableEntry *fn_entry = scope_fn_entry(scope);
4141 if (fn_entry)4152 if (fn_entry)
4142 fn_entry->variable_list.append(var);4153 fn_entry->variable_list.append(var);
41434154
...@@ -4241,7 +4252,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -4241,7 +4252,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
4241 fn_entry, fn_ref, call_param_count, casted_args);4252 fn_entry, fn_ref, call_param_count, casted_args);
42424253
4243 if (type_has_bits(return_type) && handle_is_ptr(return_type)) {4254 if (type_has_bits(return_type) && handle_is_ptr(return_type)) {
4244 FnTableEntry *fn_entry = scope_fn_entry(call_instruction->base.source_node->scope);4255 FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
4245 assert(fn_entry);4256 assert(fn_entry);
4246 fn_entry->alloca_list.append(new_call_instruction);4257 fn_entry->alloca_list.append(new_call_instruction);
4247 }4258 }
...@@ -4288,8 +4299,6 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction...@@ -4288,8 +4299,6 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction
4288 IrInstruction *first_arg_ptr = fn_ref->static_value.data.x_bound_fn.first_arg;4299 IrInstruction *first_arg_ptr = fn_ref->static_value.data.x_bound_fn.first_arg;
4289 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry,4300 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry,
4290 nullptr, first_arg_ptr, is_inline);4301 nullptr, first_arg_ptr, is_inline);
4291 } else if (fn_ref->type_entry->id == TypeTableEntryIdGenericFn) {
4292 zig_panic("TODO generic fn call");
4293 } else {4302 } else {
4294 add_node_error(ira->codegen, fn_ref->source_node,4303 add_node_error(ira->codegen, fn_ref->source_node,
4295 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->type_entry->name)));4304 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->type_entry->name)));
...@@ -4360,7 +4369,6 @@ static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstruct...@@ -4360,7 +4369,6 @@ static TypeTableEntry *ir_analyze_unary_prefix_op_err(IrAnalyze *ira, IrInstruct
4360 case TypeTableEntryIdEnum:4369 case TypeTableEntryIdEnum:
4361 case TypeTableEntryIdUnion:4370 case TypeTableEntryIdUnion:
4362 case TypeTableEntryIdFn:4371 case TypeTableEntryIdFn:
4363 case TypeTableEntryIdGenericFn:
4364 case TypeTableEntryIdBoundFn:4372 case TypeTableEntryIdBoundFn:
4365 {4373 {
4366 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base,4374 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base,
...@@ -4409,7 +4417,6 @@ static TypeTableEntry *ir_analyze_unary_address_of(IrAnalyze *ira, IrInstruction...@@ -4409,7 +4417,6 @@ static TypeTableEntry *ir_analyze_unary_address_of(IrAnalyze *ira, IrInstruction
4409 case TypeTableEntryIdBlock:4417 case TypeTableEntryIdBlock:
4410 case TypeTableEntryIdUnreachable:4418 case TypeTableEntryIdUnreachable:
4411 case TypeTableEntryIdVar:4419 case TypeTableEntryIdVar:
4412 case TypeTableEntryIdGenericFn:
4413 case TypeTableEntryIdBoundFn:4420 case TypeTableEntryIdBoundFn:
4414 add_node_error(ira->codegen, un_op_instruction->base.source_node,4421 add_node_error(ira->codegen, un_op_instruction->base.source_node,
4415 buf_sprintf("unable to get address of type '%s'", buf_ptr(&target_type->name)));4422 buf_sprintf("unable to get address of type '%s'", buf_ptr(&target_type->name)));
...@@ -4508,7 +4515,6 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op...@@ -4508,7 +4515,6 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op
4508 case TypeTableEntryIdFn:4515 case TypeTableEntryIdFn:
4509 case TypeTableEntryIdNamespace:4516 case TypeTableEntryIdNamespace:
4510 case TypeTableEntryIdBlock:4517 case TypeTableEntryIdBlock:
4511 case TypeTableEntryIdGenericFn:
4512 case TypeTableEntryIdBoundFn:4518 case TypeTableEntryIdBoundFn:
4513 {4519 {
4514 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base,4520 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base,
...@@ -4781,9 +4787,7 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc...@@ -4781,9 +4787,7 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc
4781 if (var->mem_slot_index != SIZE_MAX)4787 if (var->mem_slot_index != SIZE_MAX)
4782 mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];4788 mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];
4783 } else if (var->src_is_const) {4789 } else if (var->src_is_const) {
4784 AstNode *var_decl_node = var->decl_node;4790 mem_slot = var->value;
4785 assert(var_decl_node->type == NodeTypeVariableDeclaration);
4786 mem_slot = &var_decl_node->data.variable_declaration.top_level_decl.value->static_value;
4787 assert(mem_slot->special != ConstValSpecialRuntime);4791 assert(mem_slot->special != ConstValSpecialRuntime);
4788 }4792 }
47894793
...@@ -4925,15 +4929,15 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira,...@@ -4925,15 +4929,15 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira,
4925 if (!is_slice(bare_struct_type)) {4929 if (!is_slice(bare_struct_type)) {
4926 ScopeDecls *container_scope = get_container_scope(bare_struct_type);4930 ScopeDecls *container_scope = get_container_scope(bare_struct_type);
4927 auto entry = container_scope->decl_table.maybe_get(field_name);4931 auto entry = container_scope->decl_table.maybe_get(field_name);
4928 AstNode *fn_decl_node = entry ? entry->value : nullptr;4932 Tld *tld = entry ? entry->value : nullptr;
4929 if (fn_decl_node && fn_decl_node->type == NodeTypeFnProto) {4933 if (tld && tld->id == TldIdFn) {
4930 resolve_top_level_decl(ira->codegen, fn_decl_node, false);4934 resolve_top_level_decl(ira->codegen, tld, false);
4931 TopLevelDecl *tld = get_as_top_level_decl(fn_decl_node);
4932 if (tld->resolution == TldResolutionInvalid)4935 if (tld->resolution == TldResolutionInvalid)
4933 return ira->codegen->builtin_types.entry_invalid;4936 return ira->codegen->builtin_types.entry_invalid;
4934 FnTableEntry *fn_entry = fn_decl_node->data.fn_proto.fn_table_entry;4937 TldFn *tld_fn = (TldFn *)tld;
4938 FnTableEntry *fn_entry = tld_fn->fn_entry;
4935 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;4939 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;
4936 IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb,4940 IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, field_ptr_instruction->base.scope,
4937 field_ptr_instruction->base.source_node, fn_entry, container_ptr, depends_on_compile_var);4941 field_ptr_instruction->base.source_node, fn_entry, container_ptr, depends_on_compile_var);
4938 return ir_analyze_ref(ira, &field_ptr_instruction->base, bound_fn_value);4942 return ir_analyze_ref(ira, &field_ptr_instruction->base, bound_fn_value);
4939 }4943 }
...@@ -4976,53 +4980,63 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field...@@ -4976,53 +4980,63 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
4976 }4980 }
4977}4981}
49784982
4979static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, AstNode *decl_node,4983static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld,
4980 bool depends_on_compile_var)4984 bool depends_on_compile_var)
4981{4985{
4982 bool pointer_only = false;4986 bool pointer_only = false;
4983 resolve_top_level_decl(ira->codegen, decl_node, pointer_only);4987 resolve_top_level_decl(ira->codegen, tld, pointer_only);
4984 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
4985 if (tld->resolution == TldResolutionInvalid)4988 if (tld->resolution == TldResolutionInvalid)
4986 return ira->codegen->builtin_types.entry_invalid;4989 return ira->codegen->builtin_types.entry_invalid;
49874990
4988 if (decl_node->type == NodeTypeVariableDeclaration) {4991 switch (tld->id) {
4989 VariableTableEntry *var = decl_node->data.variable_declaration.variable;4992 case TldIdVar:
4990 return ir_analyze_var_ptr(ira, source_instruction, var);4993 {
4991 } else if (decl_node->type == NodeTypeFnProto) {4994 TldVar *tld_var = (TldVar *)tld;
4992 FnTableEntry *fn_entry = decl_node->data.fn_proto.fn_table_entry;4995 VariableTableEntry *var = tld_var->var;
4993 assert(fn_entry->type_entry);4996 return ir_analyze_var_ptr(ira, source_instruction, var);
49944997 }
4995 // TODO instead of allocating this every time, put it in the tld value and we can reference4998 case TldIdFn:
4996 // the same one every time4999 {
4997 ConstExprValue *const_val = allocate<ConstExprValue>(1);5000 TldFn *tld_fn = (TldFn *)tld;
4998 const_val->special = ConstValSpecialStatic;5001 FnTableEntry *fn_entry = tld_fn->fn_entry;
4999 if (fn_entry->type_entry->id == TypeTableEntryIdGenericFn) {5002 assert(fn_entry->type_entry);
5000 const_val->data.x_type = fn_entry->type_entry;5003
5001 } else {5004 // TODO instead of allocating this every time, put it in the tld value and we can reference
5005 // the same one every time
5006 ConstExprValue *const_val = allocate<ConstExprValue>(1);
5007 const_val->special = ConstValSpecialStatic;
5002 const_val->data.x_fn = fn_entry;5008 const_val->data.x_fn = fn_entry;
5009
5010 return ir_analyze_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, depends_on_compile_var);
5003 }5011 }
5012 case TldIdContainer:
5013 {
5014 TldContainer *tld_container = (TldContainer *)tld;
5015 assert(tld_container->type_entry);
50045016
5005 return ir_analyze_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, depends_on_compile_var);5017 // TODO instead of allocating this every time, put it in the tld value and we can reference
5006 } else if (decl_node->type == NodeTypeContainerDecl) {5018 // the same one every time
5007 zig_panic("TODO");5019 ConstExprValue *const_val = allocate<ConstExprValue>(1);
5008 //ConstExprValue *out_val = ir_build_const_from(ira, source_instruction, depends_on_compile_var);5020 const_val->special = ConstValSpecialStatic;
5009 //if (decl_node->data.struct_decl.generic_params.length > 0) {5021 const_val->data.x_type = tld_container->type_entry;
5010 // TypeTableEntry *type_entry = decl_node->data.struct_decl.generic_fn_type;5022
5011 // assert(type_entry);5023 return ir_analyze_const_ptr(ira, source_instruction, const_val, tld_container->type_entry, depends_on_compile_var);
5012 // out_val->data.x_type = type_entry;5024 }
5013 // return type_entry;5025 case TldIdTypeDef:
5014 //} else {5026 {
5015 // out_val->data.x_type = decl_node->data.struct_decl.type_entry;5027 TldTypeDef *tld_typedef = (TldTypeDef *)tld;
5016 // return ira->codegen->builtin_types.entry_type;5028 assert(tld_typedef->type_entry);
5017 //}5029
5018 } else if (decl_node->type == NodeTypeTypeDecl) {5030 // TODO instead of allocating this every time, put it in the tld value and we can reference
5019 zig_panic("TODO");5031 // the same one every time
5020 //ConstExprValue *out_val = ir_build_const_from(ira, source_instruction, depends_on_compile_var);5032 ConstExprValue *const_val = allocate<ConstExprValue>(1);
5021 //out_val->data.x_type = decl_node->data.type_decl.child_type_entry;5033 const_val->special = ConstValSpecialStatic;
5022 //return ira->codegen->builtin_types.entry_type;5034 const_val->data.x_type = tld_typedef->type_entry;
5023 } else {5035
5024 zig_unreachable();5036 return ir_analyze_const_ptr(ira, source_instruction, const_val, tld_typedef->type_entry, depends_on_compile_var);
5037 }
5025 }5038 }
5039 zig_unreachable();
5026}5040}
50275041
5028static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) {5042static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) {
...@@ -5068,10 +5082,10 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -5068,10 +5082,10 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
5068 } else if (child_type->id == TypeTableEntryIdStruct) {5082 } else if (child_type->id == TypeTableEntryIdStruct) {
5069 ScopeDecls *container_scope = get_container_scope(child_type);5083 ScopeDecls *container_scope = get_container_scope(child_type);
5070 auto entry = container_scope->decl_table.maybe_get(field_name);5084 auto entry = container_scope->decl_table.maybe_get(field_name);
5071 AstNode *decl_node = entry ? entry->value : nullptr;5085 Tld *tld = entry ? entry->value : nullptr;
5072 if (decl_node) {5086 if (tld) {
5073 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;5087 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;
5074 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, decl_node, depends_on_compile_var);5088 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, tld, depends_on_compile_var);
5075 } else {5089 } else {
5076 add_node_error(ira->codegen, source_node,5090 add_node_error(ira->codegen, source_node,
5077 buf_sprintf("container '%s' has no member called '%s'",5091 buf_sprintf("container '%s' has no member called '%s'",
...@@ -5098,30 +5112,29 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -5098,30 +5112,29 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
5098 ImportTableEntry *namespace_import = namespace_val->data.x_import;5112 ImportTableEntry *namespace_import = namespace_val->data.x_import;
50995113
5100 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;5114 bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var;
5101 AstNode *decl_node = find_decl(&namespace_import->decls_scope->base, field_name);5115 Tld *tld = find_decl(&namespace_import->decls_scope->base, field_name);
5102 if (!decl_node) {5116 if (!tld) {
5103 // we must now resolve all the use decls5117 // we must now resolve all the use decls
5118 // TODO move this check to find_decl?
5104 for (size_t i = 0; i < namespace_import->use_decls.length; i += 1) {5119 for (size_t i = 0; i < namespace_import->use_decls.length; i += 1) {
5105 AstNode *use_decl_node = namespace_import->use_decls.at(i);5120 AstNode *use_decl_node = namespace_import->use_decls.at(i);
5106 TopLevelDecl *tld = get_as_top_level_decl(use_decl_node);5121 if (use_decl_node->data.use.resolution == TldResolutionUnresolved) {
5107 if (tld->resolution == TldResolutionUnresolved) {
5108 preview_use_decl(ira->codegen, use_decl_node);5122 preview_use_decl(ira->codegen, use_decl_node);
5109 }5123 }
5110 resolve_use_decl(ira->codegen, use_decl_node);5124 resolve_use_decl(ira->codegen, use_decl_node);
5111 }5125 }
5112 decl_node = find_decl(&namespace_import->decls_scope->base, field_name);5126 tld = find_decl(&namespace_import->decls_scope->base, field_name);
5113 }5127 }
5114 if (decl_node) {5128 if (tld) {
5115 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
5116 if (tld->visib_mod == VisibModPrivate &&5129 if (tld->visib_mod == VisibModPrivate &&
5117 decl_node->owner != source_node->owner)5130 tld->import != source_node->owner)
5118 {5131 {
5119 ErrorMsg *msg = add_node_error(ira->codegen, source_node,5132 ErrorMsg *msg = add_node_error(ira->codegen, source_node,
5120 buf_sprintf("'%s' is private", buf_ptr(field_name)));5133 buf_sprintf("'%s' is private", buf_ptr(field_name)));
5121 add_error_note(ira->codegen, msg, decl_node, buf_sprintf("declared here"));5134 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here"));
5122 return ira->codegen->builtin_types.entry_invalid;5135 return ira->codegen->builtin_types.entry_invalid;
5123 }5136 }
5124 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, decl_node, depends_on_compile_var);5137 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, tld, depends_on_compile_var);
5125 } else {5138 } else {
5126 const char *import_name = namespace_import->path ? buf_ptr(namespace_import->path) : "(C import)";5139 const char *import_name = namespace_import->path ? buf_ptr(namespace_import->path) : "(C import)";
5127 add_node_error(ira->codegen, source_node,5140 add_node_error(ira->codegen, source_node,
...@@ -5176,7 +5189,8 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru...@@ -5176,7 +5189,8 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru
5176 if (ptr->id == IrInstructionIdVarPtr) {5189 if (ptr->id == IrInstructionIdVarPtr) {
5177 IrInstructionVarPtr *var_ptr_inst = (IrInstructionVarPtr *)ptr;5190 IrInstructionVarPtr *var_ptr_inst = (IrInstructionVarPtr *)ptr;
5178 VariableTableEntry *var = var_ptr_inst->var;5191 VariableTableEntry *var = var_ptr_inst->var;
5179 new_ptr_inst = ir_build_var_ptr(&ira->new_irb, store_ptr_instruction->base.source_node, var);5192 new_ptr_inst = ir_build_var_ptr(&ira->new_irb, store_ptr_instruction->base.scope,
5193 store_ptr_instruction->base.source_node, var);
5180 assert(var->mem_slot_index != SIZE_MAX);5194 assert(var->mem_slot_index != SIZE_MAX);
5181 ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];5195 ConstExprValue *mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];
5182 mem_slot->special = ConstValSpecialRuntime;5196 mem_slot->special = ConstValSpecialRuntime;
...@@ -5188,7 +5202,8 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru...@@ -5188,7 +5202,8 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru
5188 zig_unreachable();5202 zig_unreachable();
5189 }5203 }
5190 new_ptr_inst->type_entry = ptr->type_entry;5204 new_ptr_inst->type_entry = ptr->type_entry;
5191 ir_build_store_ptr(&ira->new_irb, store_ptr_instruction->base.source_node, new_ptr_inst, casted_value);5205 ir_build_store_ptr(&ira->new_irb, store_ptr_instruction->base.scope,
5206 store_ptr_instruction->base.source_node, new_ptr_inst, casted_value);
5192 return ir_analyze_void(ira, &store_ptr_instruction->base);5207 return ir_analyze_void(ira, &store_ptr_instruction->base);
5193 }5208 }
51945209
...@@ -5212,7 +5227,6 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi...@@ -5212,7 +5227,6 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi
5212 case TypeTableEntryIdNullLit:5227 case TypeTableEntryIdNullLit:
5213 case TypeTableEntryIdNamespace:5228 case TypeTableEntryIdNamespace:
5214 case TypeTableEntryIdBlock:5229 case TypeTableEntryIdBlock:
5215 case TypeTableEntryIdGenericFn:
5216 case TypeTableEntryIdBoundFn:5230 case TypeTableEntryIdBoundFn:
5217 case TypeTableEntryIdMetaType:5231 case TypeTableEntryIdMetaType:
5218 case TypeTableEntryIdVoid:5232 case TypeTableEntryIdVoid:
...@@ -5342,14 +5356,13 @@ static TypeTableEntry *ir_analyze_instruction_set_fn_visible(IrAnalyze *ira,...@@ -5342,14 +5356,13 @@ static TypeTableEntry *ir_analyze_instruction_set_fn_visible(IrAnalyze *ira,
5342 fn_entry->fn_export_set_node = source_node;5356 fn_entry->fn_export_set_node = source_node;
53435357
5344 AstNodeFnProto *fn_proto = &fn_entry->proto_node->data.fn_proto;5358 AstNodeFnProto *fn_proto = &fn_entry->proto_node->data.fn_proto;
5345 if (fn_proto->top_level_decl.visib_mod != VisibModExport) {5359 if (fn_proto->visib_mod != VisibModExport) {
5346 ErrorMsg *msg = add_node_error(ira->codegen, source_node,5360 ErrorMsg *msg = add_node_error(ira->codegen, source_node,
5347 buf_sprintf("function must be marked export to set function visibility"));5361 buf_sprintf("function must be marked export to set function visibility"));
5348 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("function declared here"));5362 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("function declared here"));
5349 return ira->codegen->builtin_types.entry_invalid;5363 return ira->codegen->builtin_types.entry_invalid;
5350 }5364 }
5351 if (!want_export)5365 fn_entry->internal_linkage = !want_export;
5352 LLVMSetLinkage(fn_entry->fn_value, LLVMInternalLinkage);
53535366
5354 ir_build_const_from(ira, &set_fn_visible_instruction->base, false);5367 ir_build_const_from(ira, &set_fn_visible_instruction->base, false);
5355 return ira->codegen->builtin_types.entry_void;5368 return ira->codegen->builtin_types.entry_void;
...@@ -5366,24 +5379,33 @@ static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,...@@ -5366,24 +5379,33 @@ static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,
5366 if (!target_val)5379 if (!target_val)
5367 return ira->codegen->builtin_types.entry_invalid;5380 return ira->codegen->builtin_types.entry_invalid;
53685381
5369 Scope *target_context;5382 bool *safety_off_ptr;
5383 AstNode **safety_set_node_ptr;
5370 if (target_type->id == TypeTableEntryIdBlock) {5384 if (target_type->id == TypeTableEntryIdBlock) {
5371 target_context = target_val->data.x_block;5385 ScopeBlock *block_scope = (ScopeBlock *)target_val->data.x_block;
5386 safety_off_ptr = &block_scope->safety_off;
5387 safety_set_node_ptr = &block_scope->safety_set_node;
5372 } else if (target_type->id == TypeTableEntryIdFn) {5388 } else if (target_type->id == TypeTableEntryIdFn) {
5373 target_context = target_val->data.x_fn->fn_def_node->data.fn_def.child_scope;5389 FnTableEntry *target_fn = target_val->data.x_fn;
5390 assert(target_fn->def_scope);
5391 safety_off_ptr = &target_fn->def_scope->safety_off;
5392 safety_set_node_ptr = &target_fn->def_scope->safety_set_node;
5374 } else if (target_type->id == TypeTableEntryIdMetaType) {5393 } else if (target_type->id == TypeTableEntryIdMetaType) {
5394 ScopeDecls *decls_scope;
5375 TypeTableEntry *type_arg = target_val->data.x_type;5395 TypeTableEntry *type_arg = target_val->data.x_type;
5376 if (type_arg->id == TypeTableEntryIdStruct) {5396 if (type_arg->id == TypeTableEntryIdStruct) {
5377 target_context = &type_arg->data.structure.decls_scope->base;5397 decls_scope = type_arg->data.structure.decls_scope;
5378 } else if (type_arg->id == TypeTableEntryIdEnum) {5398 } else if (type_arg->id == TypeTableEntryIdEnum) {
5379 target_context = &type_arg->data.enumeration.decls_scope->base;5399 decls_scope = type_arg->data.enumeration.decls_scope;
5380 } else if (type_arg->id == TypeTableEntryIdUnion) {5400 } else if (type_arg->id == TypeTableEntryIdUnion) {
5381 target_context = &type_arg->data.unionation.decls_scope->base;5401 decls_scope = type_arg->data.unionation.decls_scope;
5382 } else {5402 } else {
5383 add_node_error(ira->codegen, target_instruction->source_node,5403 add_node_error(ira->codegen, target_instruction->source_node,
5384 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&type_arg->name)));5404 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&type_arg->name)));
5385 return ira->codegen->builtin_types.entry_invalid;5405 return ira->codegen->builtin_types.entry_invalid;
5386 }5406 }
5407 safety_off_ptr = &decls_scope->safety_off;
5408 safety_set_node_ptr = &decls_scope->safety_set_node;
5387 } else {5409 } else {
5388 add_node_error(ira->codegen, target_instruction->source_node,5410 add_node_error(ira->codegen, target_instruction->source_node,
5389 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&target_type->name)));5411 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&target_type->name)));
...@@ -5396,14 +5418,14 @@ static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,...@@ -5396,14 +5418,14 @@ static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,
5396 return ira->codegen->builtin_types.entry_invalid;5418 return ira->codegen->builtin_types.entry_invalid;
53975419
5398 AstNode *source_node = set_debug_safety_instruction->base.source_node;5420 AstNode *source_node = set_debug_safety_instruction->base.source_node;
5399 if (target_context->safety_set_node) {5421 if (*safety_set_node_ptr) {
5400 ErrorMsg *msg = add_node_error(ira->codegen, source_node,5422 ErrorMsg *msg = add_node_error(ira->codegen, source_node,
5401 buf_sprintf("function test attribute set twice"));5423 buf_sprintf("function test attribute set twice"));
5402 add_error_note(ira->codegen, msg, target_context->safety_set_node, buf_sprintf("first set here"));5424 add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here"));
5403 return ira->codegen->builtin_types.entry_invalid;5425 return ira->codegen->builtin_types.entry_invalid;
5404 }5426 }
5405 target_context->safety_set_node = source_node;5427 *safety_set_node_ptr = source_node;
5406 target_context->safety_off = !want_debug_safety;5428 *safety_off_ptr = !want_debug_safety;
54075429
5408 ir_build_const_from(ira, &set_debug_safety_instruction->base, false);5430 ir_build_const_from(ira, &set_debug_safety_instruction->base, false);
5409 return ira->codegen->builtin_types.entry_void;5431 return ira->codegen->builtin_types.entry_void;
...@@ -5450,7 +5472,6 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,...@@ -5450,7 +5472,6 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
5450 case TypeTableEntryIdUnion:5472 case TypeTableEntryIdUnion:
5451 case TypeTableEntryIdFn:5473 case TypeTableEntryIdFn:
5452 case TypeTableEntryIdNamespace:5474 case TypeTableEntryIdNamespace:
5453 case TypeTableEntryIdGenericFn:
5454 case TypeTableEntryIdBoundFn:5475 case TypeTableEntryIdBoundFn:
5455 {5476 {
5456 TypeTableEntry *result_type = get_slice_type(ira->codegen, resolved_child_type, is_const);5477 TypeTableEntry *result_type = get_slice_type(ira->codegen, resolved_child_type, is_const);
...@@ -5494,7 +5515,7 @@ static TypeTableEntry *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionA...@@ -5494,7 +5515,7 @@ static TypeTableEntry *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionA
5494 }5515 }
54955516
5496 ir_build_asm_from(&ira->new_irb, &asm_instruction->base, input_list, output_types,5517 ir_build_asm_from(&ira->new_irb, &asm_instruction->base, input_list, output_types,
5497 asm_instruction->return_count, asm_instruction->has_side_effects);5518 asm_instruction->output_vars, asm_instruction->return_count, asm_instruction->has_side_effects);
5498 return return_type;5519 return return_type;
5499}5520}
55005521
...@@ -5540,7 +5561,6 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,...@@ -5540,7 +5561,6 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,
5540 case TypeTableEntryIdUnion:5561 case TypeTableEntryIdUnion:
5541 case TypeTableEntryIdFn:5562 case TypeTableEntryIdFn:
5542 case TypeTableEntryIdNamespace:5563 case TypeTableEntryIdNamespace:
5543 case TypeTableEntryIdGenericFn:
5544 case TypeTableEntryIdBoundFn:5564 case TypeTableEntryIdBoundFn:
5545 {5565 {
5546 TypeTableEntry *result_type = get_array_type(ira->codegen, child_type, size);5566 TypeTableEntry *result_type = get_array_type(ira->codegen, child_type, size);
...@@ -5611,7 +5631,6 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,...@@ -5611,7 +5631,6 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,
5611 case TypeTableEntryIdBlock:5631 case TypeTableEntryIdBlock:
5612 case TypeTableEntryIdNumLitFloat:5632 case TypeTableEntryIdNumLitFloat:
5613 case TypeTableEntryIdNumLitInt:5633 case TypeTableEntryIdNumLitInt:
5614 case TypeTableEntryIdGenericFn:
5615 case TypeTableEntryIdBoundFn:5634 case TypeTableEntryIdBoundFn:
5616 case TypeTableEntryIdMetaType:5635 case TypeTableEntryIdMetaType:
5617 case TypeTableEntryIdFn:5636 case TypeTableEntryIdFn:
...@@ -5905,7 +5924,6 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -5905,7 +5924,6 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
5905 case TypeTableEntryIdMaybe:5924 case TypeTableEntryIdMaybe:
5906 case TypeTableEntryIdUnion:5925 case TypeTableEntryIdUnion:
5907 case TypeTableEntryIdBlock:5926 case TypeTableEntryIdBlock:
5908 case TypeTableEntryIdGenericFn:
5909 case TypeTableEntryIdBoundFn:5927 case TypeTableEntryIdBoundFn:
5910 add_node_error(ira->codegen, switch_target_instruction->base.source_node,5928 add_node_error(ira->codegen, switch_target_instruction->base.source_node,
5911 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));5929 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name)));
...@@ -6009,7 +6027,7 @@ static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructi...@@ -6009,7 +6027,7 @@ static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructi
6009 ImportTableEntry *target_import = add_source_file(ira->codegen, target_package,6027 ImportTableEntry *target_import = add_source_file(ira->codegen, target_package,
6010 abs_full_path, search_dir, import_target_path, import_code);6028 abs_full_path, search_dir, import_target_path, import_code);
60116029
6012 scan_decls(ira->codegen, target_import, target_import->decls_scope, target_import->root);6030 scan_decls(ira->codegen, target_import, target_import->decls_scope, target_import->root, nullptr);
60136031
6014 ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base, depends_on_compile_var);6032 ConstExprValue *out_val = ir_build_const_from(ira, &import_instruction->base, depends_on_compile_var);
6015 out_val->data.x_import = target_import;6033 out_val->data.x_import = target_import;
...@@ -6064,7 +6082,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru...@@ -6064,7 +6082,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
60646082
6065 IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count);6083 IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count);
60666084
6067 FnTableEntry *fn_entry = scope_fn_entry(instruction->source_node->scope);6085 FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
6068 bool outside_fn = (fn_entry == nullptr);6086 bool outside_fn = (fn_entry == nullptr);
60696087
6070 ConstExprValue const_val = {};6088 ConstExprValue const_val = {};
...@@ -6167,7 +6185,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira...@@ -6167,7 +6185,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
6167 const_val.data.x_array.elements = allocate<ConstExprValue>(elem_count);6185 const_val.data.x_array.elements = allocate<ConstExprValue>(elem_count);
6168 const_val.data.x_array.size = elem_count;6186 const_val.data.x_array.size = elem_count;
61696187
6170 FnTableEntry *fn_entry = scope_fn_entry(instruction->base.source_node->scope);6188 FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
6171 bool outside_fn = (fn_entry == nullptr);6189 bool outside_fn = (fn_entry == nullptr);
61726190
6173 IrInstruction **new_items = allocate<IrInstruction *>(elem_count);6191 IrInstruction **new_items = allocate<IrInstruction *>(elem_count);
src/ir_print.cpp-8
...@@ -140,14 +140,6 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const...@@ -140,14 +140,6 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
140 fprintf(irp->f, "(namespace: %s)", buf_ptr(import->path));140 fprintf(irp->f, "(namespace: %s)", buf_ptr(import->path));
141 return;141 return;
142 }142 }
143 case TypeTableEntryIdGenericFn:
144 {
145 TypeTableEntry *type_entry = const_val->data.x_type;
146 AstNode *decl_node = type_entry->data.generic_fn.decl_node;
147 assert(decl_node->type == NodeTypeFnProto);
148 fprintf(irp->f, "%s", buf_ptr(decl_node->data.fn_proto.name));
149 return;
150 }
151 case TypeTableEntryIdBoundFn:143 case TypeTableEntryIdBoundFn:
152 {144 {
153 FnTableEntry *fn_entry = const_val->data.x_bound_fn.fn;145 FnTableEntry *fn_entry = const_val->data.x_bound_fn.fn;
src/parseh.cpp+33-66
...@@ -121,7 +121,7 @@ static AstNode *create_typed_var_decl_node(Context *c, bool is_const, const char...@@ -121,7 +121,7 @@ static AstNode *create_typed_var_decl_node(Context *c, bool is_const, const char
121 AstNode *node = create_node(c, NodeTypeVariableDeclaration);121 AstNode *node = create_node(c, NodeTypeVariableDeclaration);
122 node->data.variable_declaration.symbol = buf_create_from_str(var_name);122 node->data.variable_declaration.symbol = buf_create_from_str(var_name);
123 node->data.variable_declaration.is_const = is_const;123 node->data.variable_declaration.is_const = is_const;
124 node->data.variable_declaration.top_level_decl.visib_mod = c->visib_mod;124 node->data.variable_declaration.visib_mod = c->visib_mod;
125 node->data.variable_declaration.expr = init_node;125 node->data.variable_declaration.expr = init_node;
126 node->data.variable_declaration.type = type_node;126 node->data.variable_declaration.type = type_node;
127 return node;127 return node;
...@@ -139,16 +139,6 @@ static AstNode *create_prefix_node(Context *c, PrefixOp op, AstNode *child_node)...@@ -139,16 +139,6 @@ static AstNode *create_prefix_node(Context *c, PrefixOp op, AstNode *child_node)
139 return node;139 return node;
140}140}
141141
142static AstNode *create_struct_field_node(Context *c, const char *name, AstNode *type_node) {
143 assert(type_node);
144 AstNode *node = create_node(c, NodeTypeStructField);
145 node->data.struct_field.name = buf_create_from_str(name);
146 node->data.struct_field.top_level_decl.visib_mod = VisibModPub;
147 node->data.struct_field.type = type_node;
148
149 return node;
150}
151
152static AstNode *create_param_decl_node(Context *c, const char *name, AstNode *type_node, bool is_noalias) {142static AstNode *create_param_decl_node(Context *c, const char *name, AstNode *type_node, bool is_noalias) {
153 assert(type_node);143 assert(type_node);
154 AstNode *node = create_node(c, NodeTypeParamDecl);144 AstNode *node = create_node(c, NodeTypeParamDecl);
...@@ -214,15 +204,6 @@ static AstNode *create_num_lit_signed(Context *c, int64_t x) {...@@ -214,15 +204,6 @@ static AstNode *create_num_lit_signed(Context *c, int64_t x) {
214 return create_prefix_node(c, PrefixOpNegation, num_lit_node);204 return create_prefix_node(c, PrefixOpNegation, num_lit_node);
215}205}
216206
217static AstNode *create_type_decl_node(Context *c, const char *name, AstNode *child_type_node) {
218 AstNode *node = create_node(c, NodeTypeTypeDecl);
219 node->data.type_decl.symbol = buf_create_from_str(name);
220 node->data.type_decl.top_level_decl.visib_mod = c->visib_mod;
221 node->data.type_decl.child_type = child_type_node;
222
223 return node;
224}
225
226static AstNode *make_type_node(Context *c, TypeTableEntry *type_entry) {207static AstNode *make_type_node(Context *c, TypeTableEntry *type_entry) {
227 zig_panic("TODO bypass AST in parseh");208 zig_panic("TODO bypass AST in parseh");
228}209}
...@@ -231,7 +212,7 @@ static AstNode *create_fn_proto_node(Context *c, Buf *name, TypeTableEntry *fn_t...@@ -231,7 +212,7 @@ static AstNode *create_fn_proto_node(Context *c, Buf *name, TypeTableEntry *fn_t
231 assert(fn_type->id == TypeTableEntryIdFn);212 assert(fn_type->id == TypeTableEntryIdFn);
232 AstNode *node = create_node(c, NodeTypeFnProto);213 AstNode *node = create_node(c, NodeTypeFnProto);
233 node->data.fn_proto.is_inline = true;214 node->data.fn_proto.is_inline = true;
234 node->data.fn_proto.top_level_decl.visib_mod = c->visib_mod;215 node->data.fn_proto.visib_mod = c->visib_mod;
235 node->data.fn_proto.name = name;216 node->data.fn_proto.name = name;
236 node->data.fn_proto.return_type = make_type_node(c, fn_type->data.fn.fn_type_id.return_type);217 node->data.fn_proto.return_type = make_type_node(c, fn_type->data.fn.fn_type_id.return_type);
237218
...@@ -280,25 +261,40 @@ static const char *decl_name(const Decl *decl) {...@@ -280,25 +261,40 @@ static const char *decl_name(const Decl *decl) {
280 return (const char *)named_decl->getName().bytes_begin();261 return (const char *)named_decl->getName().bytes_begin();
281}262}
282263
283static AstNode *add_typedef_node(Context *c, TypeTableEntry *type_decl) {264static void add_typedef_node(Context *c, TypeTableEntry *type_decl) {
284 assert(type_decl);265 assert(type_decl);
285 assert(type_decl->id == TypeTableEntryIdTypeDecl);266 assert(type_decl->id == TypeTableEntryIdTypeDecl);
286267
287 AstNode *node = create_type_decl_node(c, buf_ptr(&type_decl->name),268 ScopeDecls *decls_scope = c->import->decls_scope;
288 make_type_node(c, type_decl->data.type_decl.child_type));269 TldTypeDef *tld_typedef = allocate<TldTypeDef>(1);
289 node->data.type_decl.override_type = type_decl;270 init_tld(&tld_typedef->base, TldIdTypeDef, &type_decl->name, c->visib_mod, c->source_node, &decls_scope->base, nullptr);
271 tld_typedef->type_entry = type_decl;
290272
273 decls_scope->decl_table.put(&type_decl->name, &tld_typedef->base);
291 c->global_type_table.put(&type_decl->name, type_decl);274 c->global_type_table.put(&type_decl->name, type_decl);
292 c->root->data.root.top_level_decls.append(node);
293 return node;
294}275}
295276
296static AstNode *add_const_var_node(Context *c, Buf *name, TypeTableEntry *type_entry) {277static void add_const_var_node(Context *c, Buf *name, TypeTableEntry *type_entry) {
297 AstNode *node = create_var_decl_node(c, buf_ptr(name), make_type_node(c, type_entry));278 ScopeDecls *decls_scope = c->import->decls_scope;
298279 TldVar *tld_var = allocate<TldVar>(1);
280 init_tld(&tld_var->base, TldIdVar, name, c->visib_mod, c->source_node, &decls_scope->base, nullptr);
281 bool is_const = true;
282 ConstExprValue *init_value = allocate<ConstExprValue>(1);
283 init_value->special = ConstValSpecialStatic;
284 init_value->data.x_type = type_entry;
285 tld_var->var = add_variable(c->codegen, c->source_node, &decls_scope->base, name, type_entry, is_const, init_value);
286
287 decls_scope->decl_table.put(name, &tld_var->base);
299 c->global_type_table.put(name, type_entry);288 c->global_type_table.put(name, type_entry);
300 c->root->data.root.top_level_decls.append(node);289}
301 return node;290
291static void add_container_tld(Context *c, TypeTableEntry *type_entry) {
292 ScopeDecls *decls_scope = c->import->decls_scope;
293 TldContainer *tld_container = allocate<TldContainer>(1);
294 init_tld(&tld_container->base, TldIdContainer, &type_entry->name, c->visib_mod, c->source_node, &decls_scope->base, nullptr);
295 tld_container->type_entry = type_entry;
296
297 decls_scope->decl_table.put(&type_entry->name, &tld_container->base);
302}298}
303299
304static AstNode *create_ap_num_lit_node(Context *c, const Decl *source_decl,300static AstNode *create_ap_num_lit_node(Context *c, const Decl *source_decl,
...@@ -617,7 +613,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const...@@ -617,7 +613,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
617 param_info->is_noalias = qt.isRestrictQualified();613 param_info->is_noalias = qt.isRestrictQualified();
618 }614 }
619615
620 return get_fn_type(c->codegen, &fn_type_id, true);616 return get_fn_type(c->codegen, &fn_type_id);
621 }617 }
622 case Type::Record:618 case Type::Record:
623 {619 {
...@@ -724,7 +720,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -724,7 +720,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
724 node->data.fn_proto.name = fn_name;720 node->data.fn_proto.name = fn_name;
725721
726 node->data.fn_proto.is_extern = fn_type->data.fn.fn_type_id.is_extern;722 node->data.fn_proto.is_extern = fn_type->data.fn.fn_type_id.is_extern;
727 node->data.fn_proto.top_level_decl.visib_mod = c->visib_mod;723 node->data.fn_proto.visib_mod = c->visib_mod;
728 node->data.fn_proto.is_var_args = fn_type->data.fn.fn_type_id.is_var_args;724 node->data.fn_proto.is_var_args = fn_type->data.fn.fn_type_id.is_var_args;
729 node->data.fn_proto.return_type = make_type_node(c, fn_type->data.fn.fn_type_id.return_type);725 node->data.fn_proto.return_type = make_type_node(c, fn_type->data.fn.fn_type_id.return_type);
730726
...@@ -939,9 +935,8 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)...@@ -939,9 +935,8 @@ static TypeTableEntry *resolve_enum_decl(Context *c, const EnumDecl *enum_decl)
939static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {935static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
940 TypeTableEntry *enum_type = resolve_enum_decl(c, enum_decl);936 TypeTableEntry *enum_type = resolve_enum_decl(c, enum_decl);
941937
942 if (enum_type->id == TypeTableEntryIdInvalid) {938 if (enum_type->id == TypeTableEntryIdInvalid)
943 return;939 return;
944 }
945940
946 // make an alias without the "enum_" prefix. this will get emitted at the941 // make an alias without the "enum_" prefix. this will get emitted at the
947 // end if it doesn't conflict with anything else942 // end if it doesn't conflict with anything else
...@@ -951,21 +946,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {...@@ -951,21 +946,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
951946
952 if (enum_type->id == TypeTableEntryIdEnum) {947 if (enum_type->id == TypeTableEntryIdEnum) {
953 if (enum_type->data.enumeration.complete) {948 if (enum_type->data.enumeration.complete) {
954 // now create top level decl for the type949 add_container_tld(c, enum_type);
955 AstNode *enum_node = create_node(c, NodeTypeContainerDecl);
956 enum_node->data.struct_decl.name = &enum_type->name;
957 enum_node->data.struct_decl.kind = ContainerKindEnum;
958 enum_node->data.struct_decl.top_level_decl.visib_mod = VisibModExport;
959 enum_node->data.struct_decl.type_entry = enum_type;
960
961 for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) {
962 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i];
963 AstNode *type_node = make_type_node(c, type_enum_field->type_entry);
964 AstNode *field_node = create_struct_field_node(c, buf_ptr(type_enum_field->name), type_node);
965 enum_node->data.struct_decl.fields.append(field_node);
966 }
967
968 c->root->data.root.top_level_decls.append(enum_node);
969 } else {950 } else {
970 TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(&enum_type->name),951 TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(&enum_type->name),
971 c->codegen->builtin_types.entry_u8);952 c->codegen->builtin_types.entry_u8);
...@@ -1127,21 +1108,7 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) {...@@ -1127,21 +1108,7 @@ static void visit_record_decl(Context *c, const RecordDecl *record_decl) {
1127 }1108 }
11281109
1129 if (struct_type->data.structure.complete) {1110 if (struct_type->data.structure.complete) {
1130 // now create a top level decl node for the type1111 add_container_tld(c, struct_type);
1131 AstNode *struct_node = create_node(c, NodeTypeContainerDecl);
1132 struct_node->data.struct_decl.name = &struct_type->name;
1133 struct_node->data.struct_decl.kind = ContainerKindStruct;
1134 struct_node->data.struct_decl.top_level_decl.visib_mod = VisibModExport;
1135 struct_node->data.struct_decl.type_entry = struct_type;
1136
1137 for (uint32_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {
1138 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
1139 AstNode *type_node = make_type_node(c, type_struct_field->type_entry);
1140 AstNode *field_node = create_struct_field_node(c, buf_ptr(type_struct_field->name), type_node);
1141 struct_node->data.struct_decl.fields.append(field_node);
1142 }
1143
1144 c->root->data.root.top_level_decls.append(struct_node);
1145 } else {1112 } else {
1146 TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(&struct_type->name),1113 TypeTableEntry *typedecl_type = get_typedecl_type(c->codegen, buf_ptr(&struct_type->name),
1147 c->codegen->builtin_types.entry_u8);1114 c->codegen->builtin_types.entry_u8);
src/parser.cpp+8-7
...@@ -1501,7 +1501,7 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to...@@ -1501,7 +1501,7 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to
15011501
1502 node->data.variable_declaration.is_inline = is_inline;1502 node->data.variable_declaration.is_inline = is_inline;
1503 node->data.variable_declaration.is_const = is_const;1503 node->data.variable_declaration.is_const = is_const;
1504 node->data.variable_declaration.top_level_decl.visib_mod = visib_mod;1504 node->data.variable_declaration.visib_mod = visib_mod;
15051505
1506 Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);1506 Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);
1507 node->data.variable_declaration.symbol = token_buf(name_token);1507 node->data.variable_declaration.symbol = token_buf(name_token);
...@@ -2079,7 +2079,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m...@@ -2079,7 +2079,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
2079 }2079 }
20802080
2081 AstNode *node = ast_create_node(pc, NodeTypeFnProto, fn_token);2081 AstNode *node = ast_create_node(pc, NodeTypeFnProto, fn_token);
2082 node->data.fn_proto.top_level_decl.visib_mod = visib_mod;2082 node->data.fn_proto.visib_mod = visib_mod;
2083 node->data.fn_proto.is_coldcc = is_coldcc;2083 node->data.fn_proto.is_coldcc = is_coldcc;
2084 node->data.fn_proto.is_nakedcc = is_nakedcc;2084 node->data.fn_proto.is_nakedcc = is_nakedcc;
20852085
...@@ -2144,6 +2144,7 @@ static AstNode *ast_parse_fn_def(ParseContext *pc, size_t *token_index, bool man...@@ -2144,6 +2144,7 @@ static AstNode *ast_parse_fn_def(ParseContext *pc, size_t *token_index, bool man
2144 AstNode *node = ast_create_node(pc, NodeTypeFnDef, first_token);2144 AstNode *node = ast_create_node(pc, NodeTypeFnDef, first_token);
2145 node->data.fn_def.fn_proto = fn_proto;2145 node->data.fn_def.fn_proto = fn_proto;
2146 node->data.fn_def.body = ast_parse_block(pc, token_index, true);2146 node->data.fn_def.body = ast_parse_block(pc, token_index, true);
2147 fn_proto->data.fn_proto.fn_def_node = node;
2147 return node;2148 return node;
2148}2149}
21492150
...@@ -2193,7 +2194,7 @@ static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index, VisibMod vi...@@ -2193,7 +2194,7 @@ static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index, VisibMod vi
2193 *token_index += 1;2194 *token_index += 1;
21942195
2195 AstNode *node = ast_create_node(pc, NodeTypeUse, use_kw);2196 AstNode *node = ast_create_node(pc, NodeTypeUse, use_kw);
2196 node->data.use.top_level_decl.visib_mod = visib_mod;2197 node->data.use.visib_mod = visib_mod;
2197 node->data.use.expr = ast_parse_expression(pc, token_index, true);2198 node->data.use.expr = ast_parse_expression(pc, token_index, true);
21982199
2199 ast_eat_token(pc, token_index, TokenIdSemicolon);2200 ast_eat_token(pc, token_index, TokenIdSemicolon);
...@@ -2227,7 +2228,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,...@@ -2227,7 +2228,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
2227 AstNode *node = ast_create_node(pc, NodeTypeContainerDecl, first_token);2228 AstNode *node = ast_create_node(pc, NodeTypeContainerDecl, first_token);
2228 node->data.struct_decl.kind = kind;2229 node->data.struct_decl.kind = kind;
2229 node->data.struct_decl.name = token_buf(struct_name);2230 node->data.struct_decl.name = token_buf(struct_name);
2230 node->data.struct_decl.top_level_decl.visib_mod = visib_mod;2231 node->data.struct_decl.visib_mod = visib_mod;
22312232
2232 Token *paren_or_brace = &pc->tokens->at(*token_index);2233 Token *paren_or_brace = &pc->tokens->at(*token_index);
2233 if (paren_or_brace->id == TokenIdLParen) {2234 if (paren_or_brace->id == TokenIdLParen) {
...@@ -2281,7 +2282,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,...@@ -2281,7 +2282,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
2281 AstNode *field_node = ast_create_node(pc, NodeTypeStructField, token);2282 AstNode *field_node = ast_create_node(pc, NodeTypeStructField, token);
2282 *token_index += 1;2283 *token_index += 1;
22832284
2284 field_node->data.struct_field.top_level_decl.visib_mod = visib_mod;2285 field_node->data.struct_field.visib_mod = visib_mod;
2285 field_node->data.struct_field.name = token_buf(token);2286 field_node->data.struct_field.name = token_buf(token);
22862287
2287 Token *expr_or_comma = &pc->tokens->at(*token_index);2288 Token *expr_or_comma = &pc->tokens->at(*token_index);
...@@ -2318,7 +2319,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index...@@ -2318,7 +2319,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index
2318 ast_eat_token(pc, token_index, TokenIdSemicolon);2319 ast_eat_token(pc, token_index, TokenIdSemicolon);
23192320
2320 AstNode *node = ast_create_node(pc, NodeTypeErrorValueDecl, first_token);2321 AstNode *node = ast_create_node(pc, NodeTypeErrorValueDecl, first_token);
2321 node->data.error_value_decl.top_level_decl.visib_mod = visib_mod;2322 node->data.error_value_decl.visib_mod = visib_mod;
2322 node->data.error_value_decl.name = token_buf(name_tok);2323 node->data.error_value_decl.name = token_buf(name_tok);
23232324
2324 return node;2325 return node;
...@@ -2344,7 +2345,7 @@ static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index, Visib...@@ -2344,7 +2345,7 @@ static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index, Visib
23442345
2345 ast_eat_token(pc, token_index, TokenIdSemicolon);2346 ast_eat_token(pc, token_index, TokenIdSemicolon);
23462347
2347 node->data.type_decl.top_level_decl.visib_mod = visib_mod;2348 node->data.type_decl.visib_mod = visib_mod;
23482349
2349 return node;2350 return node;
2350}2351}