authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-10 15:13:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-10 15:13:39-07:00
log3ef2f7058b0bbe2c81f79f990398aaab2e5a7a2f
treed5c6033ff111ff126dc14844ee85edbc0a0828b9
parentd4b8852d784b6f180e5329efa8d418397ee7f1ef

refactor out the horrible beast that was codegen_node


7 files changed, 1345 insertions(+), 1103 deletions(-)

src/all_types.hpp created+928
...@@ -0,0 +1,928 @@
1/*
2 * Copyright (c) 2015 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#ifndef ZIG_ALL_TYPES_HPP
9#define ZIG_ALL_TYPES_HPP
10
11#include "list.hpp"
12#include "buffer.hpp"
13#include "zig_llvm.hpp"
14#include "hash_map.hpp"
15#include "errmsg.hpp"
16
17struct AstNode;
18struct ImportTableEntry;
19struct AsmToken;
20struct FnTableEntry;
21struct BlockContext;
22struct TypeTableEntry;
23struct VariableTableEntry;
24struct Cast;
25struct BuiltinFnEntry;
26struct LabelTableEntry;
27struct TypeStructField;
28struct CodeGen;
29
30enum OutType {
31 OutTypeUnknown,
32 OutTypeExe,
33 OutTypeLib,
34 OutTypeObj,
35};
36
37enum CodeGenBuildType {
38 CodeGenBuildTypeDebug,
39 CodeGenBuildTypeRelease,
40};
41
42enum CastOp {
43 CastOpNothing,
44 CastOpPtrToInt,
45 CastOpIntWidenOrShorten,
46 CastOpToUnknownSizeArray,
47 CastOpMaybeWrap,
48 CastOpPointerReinterpret,
49};
50
51struct Cast {
52 CastOp op;
53 // if op is CastOpArrayToString, this will be a pointer to
54 // the string struct on the stack
55 LLVMValueRef ptr;
56 TypeTableEntry *after_type;
57 AstNode *source_node;
58};
59
60struct Expr {
61 TypeTableEntry *type_entry;
62 // the context in which this expression is evaluated.
63 // for blocks, this points to the containing scope, not the block's own scope for its children.
64 BlockContext *block_context;
65
66 // may be null for no cast
67 Cast implicit_cast; // happens first
68 Cast implicit_maybe_cast; // happens second
69};
70
71struct NumLitCodeGen {
72 TypeTableEntry *resolved_type;
73};
74
75struct StructValExprCodeGen {
76 TypeTableEntry *type_entry;
77 LLVMValueRef ptr;
78 AstNode *source_node;
79};
80
81struct TopLevelDecl {
82 // reminder: hash tables must be initialized before use
83 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> deps;
84 Buf *name;
85 ImportTableEntry *import;
86 // set this flag temporarily to detect infinite loops
87 bool in_current_deps;
88};
89
90enum NodeType {
91 NodeTypeRoot,
92 NodeTypeRootExportDecl,
93 NodeTypeFnProto,
94 NodeTypeFnDef,
95 NodeTypeFnDecl,
96 NodeTypeParamDecl,
97 NodeTypeType,
98 NodeTypeBlock,
99 NodeTypeExternBlock,
100 NodeTypeDirective,
101 NodeTypeReturnExpr,
102 NodeTypeVariableDeclaration,
103 NodeTypeBinOpExpr,
104 NodeTypeCastExpr,
105 NodeTypeNumberLiteral,
106 NodeTypeStringLiteral,
107 NodeTypeCharLiteral,
108 NodeTypeUnreachable,
109 NodeTypeSymbol,
110 NodeTypePrefixOpExpr,
111 NodeTypeFnCallExpr,
112 NodeTypeArrayAccessExpr,
113 NodeTypeSliceExpr,
114 NodeTypeFieldAccessExpr,
115 NodeTypeUse,
116 NodeTypeVoid,
117 NodeTypeBoolLiteral,
118 NodeTypeNullLiteral,
119 NodeTypeIfBoolExpr,
120 NodeTypeIfVarExpr,
121 NodeTypeWhileExpr,
122 NodeTypeLabel,
123 NodeTypeGoto,
124 NodeTypeBreak,
125 NodeTypeContinue,
126 NodeTypeAsmExpr,
127 NodeTypeStructDecl,
128 NodeTypeStructField,
129 NodeTypeStructValueExpr,
130 NodeTypeStructValueField,
131 NodeTypeEnumDecl,
132 NodeTypeEnumField,
133 NodeTypeCompilerFnExpr,
134 NodeTypeCompilerFnType,
135};
136
137struct AstNodeRoot {
138 ZigList<AstNode *> top_level_decls;
139};
140
141enum VisibMod {
142 VisibModPrivate,
143 VisibModPub,
144 VisibModExport,
145};
146
147struct AstNodeFnProto {
148 ZigList<AstNode *> *directives;
149 VisibMod visib_mod;
150 Buf name;
151 ZigList<AstNode *> params;
152 AstNode *return_type;
153 bool is_var_args;
154
155 // populated by semantic analyzer:
156
157 // the extern block this fn proto is inside. can be null.
158 AstNode *extern_node;
159 // the struct decl node this fn proto is inside. can be null.
160 AstNode *struct_node;
161 // the function definition this fn proto is inside. can be null.
162 AstNode *fn_def_node;
163 FnTableEntry *fn_table_entry;
164 bool skip;
165 TopLevelDecl top_level_decl;
166};
167
168struct AstNodeFnDef {
169 AstNode *fn_proto;
170 AstNode *body;
171
172 // populated by semantic analyzer
173 TypeTableEntry *implicit_return_type;
174 BlockContext *block_context;
175};
176
177struct AstNodeFnDecl {
178 AstNode *fn_proto;
179};
180
181struct AstNodeParamDecl {
182 Buf name;
183 AstNode *type;
184
185 // populated by semantic analyzer
186 VariableTableEntry *variable;
187};
188
189enum AstNodeTypeType {
190 AstNodeTypeTypePrimitive,
191 AstNodeTypeTypePointer,
192 AstNodeTypeTypeArray,
193 AstNodeTypeTypeMaybe,
194 AstNodeTypeTypeCompilerExpr,
195};
196
197struct AstNodeType {
198 AstNodeTypeType type;
199 Buf primitive_name;
200 AstNode *child_type;
201 AstNode *array_size; // can be null
202 bool is_const;
203 bool is_noalias;
204 AstNode *compiler_expr;
205
206 // populated by semantic analyzer
207 TypeTableEntry *entry;
208};
209
210struct AstNodeBlock {
211 ZigList<AstNode *> statements;
212
213 // populated by semantic analyzer
214 BlockContext *block_context;
215 Expr resolved_expr;
216};
217
218struct AstNodeReturnExpr {
219 // might be null in case of return void;
220 AstNode *expr;
221
222 // populated by semantic analyzer:
223 Expr resolved_expr;
224};
225
226struct AstNodeVariableDeclaration {
227 Buf symbol;
228 bool is_const;
229 VisibMod visib_mod;
230 // one or both of type and expr will be non null
231 AstNode *type;
232 AstNode *expr;
233
234 // populated by semantic analyzer
235 TopLevelDecl top_level_decl;
236 Expr resolved_expr;
237};
238
239enum BinOpType {
240 BinOpTypeInvalid,
241 BinOpTypeAssign,
242 BinOpTypeAssignTimes,
243 BinOpTypeAssignDiv,
244 BinOpTypeAssignMod,
245 BinOpTypeAssignPlus,
246 BinOpTypeAssignMinus,
247 BinOpTypeAssignBitShiftLeft,
248 BinOpTypeAssignBitShiftRight,
249 BinOpTypeAssignBitAnd,
250 BinOpTypeAssignBitXor,
251 BinOpTypeAssignBitOr,
252 BinOpTypeAssignBoolAnd,
253 BinOpTypeAssignBoolOr,
254 BinOpTypeBoolOr,
255 BinOpTypeBoolAnd,
256 BinOpTypeCmpEq,
257 BinOpTypeCmpNotEq,
258 BinOpTypeCmpLessThan,
259 BinOpTypeCmpGreaterThan,
260 BinOpTypeCmpLessOrEq,
261 BinOpTypeCmpGreaterOrEq,
262 BinOpTypeBinOr,
263 BinOpTypeBinXor,
264 BinOpTypeBinAnd,
265 BinOpTypeBitShiftLeft,
266 BinOpTypeBitShiftRight,
267 BinOpTypeAdd,
268 BinOpTypeSub,
269 BinOpTypeMult,
270 BinOpTypeDiv,
271 BinOpTypeMod,
272 BinOpTypeUnwrapMaybe,
273};
274
275struct AstNodeBinOpExpr {
276 AstNode *op1;
277 BinOpType bin_op;
278 AstNode *op2;
279
280 // populated by semantic analyzer:
281 // for when op is BinOpTypeAssign
282 VariableTableEntry *var_entry;
283 Expr resolved_expr;
284};
285
286struct AstNodeFnCallExpr {
287 AstNode *fn_ref_expr;
288 ZigList<AstNode *> params;
289 bool is_builtin;
290
291 // populated by semantic analyzer:
292 BuiltinFnEntry *builtin_fn;
293 Expr resolved_expr;
294};
295
296struct AstNodeArrayAccessExpr {
297 AstNode *array_ref_expr;
298 AstNode *subscript;
299
300 // populated by semantic analyzer:
301 Expr resolved_expr;
302};
303
304struct AstNodeSliceExpr {
305 AstNode *array_ref_expr;
306 AstNode *start;
307 AstNode *end;
308 bool is_const;
309
310 // populated by semantic analyzer:
311 Expr resolved_expr;
312 StructValExprCodeGen resolved_struct_val_expr;
313};
314
315struct AstNodeFieldAccessExpr {
316 AstNode *struct_expr;
317 Buf field_name;
318
319 // populated by semantic analyzer
320 int field_index;
321 TypeStructField *type_struct_field;
322 Expr resolved_expr;
323};
324
325struct AstNodeExternBlock {
326 ZigList<AstNode *> *directives;
327 ZigList<AstNode *> fn_decls;
328};
329
330struct AstNodeDirective {
331 Buf name;
332 Buf param;
333};
334
335struct AstNodeRootExportDecl {
336 Buf type;
337 Buf name;
338 ZigList<AstNode *> *directives;
339};
340
341struct AstNodeCastExpr {
342 AstNode *expr;
343 AstNode *type;
344
345 // populated by semantic analyzer
346 Cast cast;
347 Expr resolved_expr;
348};
349
350enum PrefixOp {
351 PrefixOpInvalid,
352 PrefixOpBoolNot,
353 PrefixOpBinNot,
354 PrefixOpNegation,
355 PrefixOpAddressOf,
356 PrefixOpConstAddressOf,
357 PrefixOpDereference,
358};
359
360struct AstNodePrefixOpExpr {
361 PrefixOp prefix_op;
362 AstNode *primary_expr;
363
364 // populated by semantic analyzer
365 Expr resolved_expr;
366};
367
368struct AstNodeUse {
369 Buf path;
370 ZigList<AstNode *> *directives;
371
372 // populated by semantic analyzer
373 ImportTableEntry *import;
374};
375
376struct AstNodeIfBoolExpr {
377 AstNode *condition;
378 AstNode *then_block;
379 AstNode *else_node; // null, block node, or other if expr node
380
381 // populated by semantic analyzer
382 Expr resolved_expr;
383};
384
385struct AstNodeIfVarExpr {
386 AstNodeVariableDeclaration var_decl;
387 AstNode *then_block;
388 AstNode *else_node; // null, block node, or other if expr node
389
390 // populated by semantic analyzer
391 TypeTableEntry *type;
392 BlockContext *block_context;
393 Expr resolved_expr;
394};
395
396struct AstNodeWhileExpr {
397 AstNode *condition;
398 AstNode *body;
399
400 // populated by semantic analyzer
401 bool condition_always_true;
402 bool contains_break;
403 Expr resolved_expr;
404};
405
406struct AstNodeLabel {
407 Buf name;
408
409 // populated by semantic analyzer
410 LabelTableEntry *label_entry;
411 Expr resolved_expr;
412};
413
414struct AstNodeGoto {
415 Buf name;
416
417 // populated by semantic analyzer
418 LabelTableEntry *label_entry;
419 Expr resolved_expr;
420};
421
422struct AsmOutput {
423 Buf asm_symbolic_name;
424 Buf constraint;
425 Buf variable_name;
426 AstNode *return_type; // null unless "=r" and return
427};
428
429struct AsmInput {
430 Buf asm_symbolic_name;
431 Buf constraint;
432 AstNode *expr;
433};
434
435struct SrcPos {
436 int line;
437 int column;
438};
439
440struct AstNodeAsmExpr {
441 bool is_volatile;
442 Buf asm_template;
443 ZigList<SrcPos> offset_map;
444 ZigList<AsmToken> token_list;
445 ZigList<AsmOutput*> output_list;
446 ZigList<AsmInput*> input_list;
447 ZigList<Buf*> clobber_list;
448
449 // populated by semantic analyzer
450 int return_count;
451 Expr resolved_expr;
452};
453
454struct AstNodeStructDecl {
455 Buf name;
456 ZigList<AstNode *> fields;
457 ZigList<AstNode *> fns;
458 ZigList<AstNode *> *directives;
459 VisibMod visib_mod;
460
461 // populated by semantic analyzer
462 TypeTableEntry *type_entry;
463 TopLevelDecl top_level_decl;
464};
465
466struct AstNodeStructField {
467 Buf name;
468 AstNode *type;
469 ZigList<AstNode *> *directives;
470};
471
472struct AstNodeEnumDecl {
473 Buf name;
474 ZigList<AstNode *> fields;
475 ZigList<AstNode *> *directives;
476 VisibMod visib_mod;
477};
478
479struct AstNodeEnumField {
480 Buf name;
481 ZigList<AstNode *> fields; // length 0 means simple enum
482 AstNode *val_expr;
483};
484
485struct AstNodeStringLiteral {
486 Buf buf;
487 bool c;
488
489 // populated by semantic analyzer:
490 Expr resolved_expr;
491};
492
493struct AstNodeCharLiteral {
494 uint8_t value;
495
496 // populated by semantic analyzer:
497 Expr resolved_expr;
498};
499
500enum NumLit {
501 NumLitF32,
502 NumLitF64,
503 NumLitF128,
504 NumLitU8,
505 NumLitU16,
506 NumLitU32,
507 NumLitU64,
508 NumLitI8,
509 NumLitI16,
510 NumLitI32,
511 NumLitI64,
512
513 NumLitCount
514};
515
516struct AstNodeNumberLiteral {
517 NumLit kind;
518
519 // overflow is true if when parsing the number, we discovered it would not
520 // fit without losing data in a uint64_t, int64_t, or double
521 bool overflow;
522
523 union {
524 uint64_t x_uint;
525 int64_t x_int;
526 double x_float;
527 } data;
528
529 // populated by semantic analyzer
530 NumLitCodeGen codegen;
531 Expr resolved_expr;
532};
533
534struct AstNodeStructValueField {
535 Buf name;
536 AstNode *expr;
537
538 // populated by semantic analyzer
539 int index;
540};
541
542struct AstNodeStructValueExpr {
543 AstNode *type;
544 ZigList<AstNode *> fields;
545
546 // populated by semantic analyzer
547 StructValExprCodeGen codegen;
548 Expr resolved_expr;
549};
550
551struct AstNodeCompilerFnExpr {
552 Buf name;
553 AstNode *expr;
554
555 // populated by semantic analyzer
556 Expr resolved_expr;
557};
558
559struct AstNodeCompilerFnType {
560 Buf name;
561 AstNode *type;
562
563 // populated by semantic analyzer
564 Expr resolved_expr;
565 NumLitCodeGen resolved_num_lit;
566};
567
568struct AstNodeNullLiteral {
569 // populated by semantic analyzer
570 StructValExprCodeGen resolved_struct_val_expr;
571 Expr resolved_expr;
572};
573
574struct AstNodeVoidExpr {
575 // populated by semantic analyzer
576 Expr resolved_expr;
577};
578
579struct AstNodeUnreachableExpr {
580 // populated by semantic analyzer
581 Expr resolved_expr;
582};
583
584struct AstNodeSymbolExpr {
585 Buf symbol;
586
587 // populated by semantic analyzer
588 Expr resolved_expr;
589};
590
591struct AstNodeBoolLiteral {
592 bool value;
593
594 // populated by semantic analyzer
595 Expr resolved_expr;
596};
597
598struct AstNodeBreakExpr {
599 // populated by semantic analyzer
600 Expr resolved_expr;
601};
602
603struct AstNodeContinueExpr {
604 // populated by semantic analyzer
605 Expr resolved_expr;
606};
607
608struct AstNode {
609 enum NodeType type;
610 int line;
611 int column;
612 uint32_t create_index; // for determinism purposes
613 ImportTableEntry *owner;
614 union {
615 AstNodeRoot root;
616 AstNodeRootExportDecl root_export_decl;
617 AstNodeFnDef fn_def;
618 AstNodeFnDecl fn_decl;
619 AstNodeFnProto fn_proto;
620 AstNodeType type;
621 AstNodeParamDecl param_decl;
622 AstNodeBlock block;
623 AstNodeReturnExpr return_expr;
624 AstNodeVariableDeclaration variable_declaration;
625 AstNodeBinOpExpr bin_op_expr;
626 AstNodeExternBlock extern_block;
627 AstNodeDirective directive;
628 AstNodeCastExpr cast_expr;
629 AstNodePrefixOpExpr prefix_op_expr;
630 AstNodeFnCallExpr fn_call_expr;
631 AstNodeArrayAccessExpr array_access_expr;
632 AstNodeSliceExpr slice_expr;
633 AstNodeUse use;
634 AstNodeIfBoolExpr if_bool_expr;
635 AstNodeIfVarExpr if_var_expr;
636 AstNodeWhileExpr while_expr;
637 AstNodeLabel label;
638 AstNodeGoto goto_expr;
639 AstNodeAsmExpr asm_expr;
640 AstNodeFieldAccessExpr field_access_expr;
641 AstNodeStructDecl struct_decl;
642 AstNodeStructField struct_field;
643 AstNodeEnumDecl enum_decl;
644 AstNodeEnumField enum_field;
645 AstNodeStringLiteral string_literal;
646 AstNodeCharLiteral char_literal;
647 AstNodeNumberLiteral number_literal;
648 AstNodeStructValueExpr struct_val_expr;
649 AstNodeStructValueField struct_val_field;
650 AstNodeCompilerFnExpr compiler_fn_expr;
651 AstNodeCompilerFnType compiler_fn_type;
652 AstNodeNullLiteral null_literal;
653 AstNodeVoidExpr void_expr;
654 AstNodeUnreachableExpr unreachable_expr;
655 AstNodeSymbolExpr symbol_expr;
656 AstNodeBoolLiteral bool_literal;
657 AstNodeBreakExpr break_expr;
658 AstNodeContinueExpr continue_expr;
659 } data;
660};
661
662enum AsmTokenId {
663 AsmTokenIdTemplate,
664 AsmTokenIdPercent,
665 AsmTokenIdVar,
666};
667
668struct AsmToken {
669 enum AsmTokenId id;
670 int start;
671 int end;
672};
673
674struct TypeTableEntryPointer {
675 TypeTableEntry *child_type;
676 bool is_const;
677 bool is_noalias;
678};
679
680struct TypeTableEntryInt {
681 bool is_signed;
682};
683
684struct TypeTableEntryArray {
685 TypeTableEntry *child_type;
686 uint64_t len;
687};
688
689struct TypeStructField {
690 Buf *name;
691 TypeTableEntry *type_entry;
692};
693
694struct TypeTableEntryStruct {
695 AstNode *decl_node;
696 bool is_packed;
697 int field_count;
698 TypeStructField *fields;
699 uint64_t size_bytes;
700 bool is_invalid; // true if any fields are invalid
701 bool is_unknown_size_array;
702 // reminder: hash tables must be initialized before use
703 HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table;
704
705 // set this flag temporarily to detect infinite loops
706 bool embedded_in_current;
707 bool reported_infinite_err;
708};
709
710struct TypeTableEntryNumLit {
711 NumLit kind;
712};
713
714struct TypeTableEntryMaybe {
715 TypeTableEntry *child_type;
716};
717
718enum TypeTableEntryId {
719 TypeTableEntryIdInvalid,
720 TypeTableEntryIdVoid,
721 TypeTableEntryIdBool,
722 TypeTableEntryIdUnreachable,
723 TypeTableEntryIdInt,
724 TypeTableEntryIdFloat,
725 TypeTableEntryIdPointer,
726 TypeTableEntryIdArray,
727 TypeTableEntryIdStruct,
728 TypeTableEntryIdNumberLiteral,
729 TypeTableEntryIdMaybe,
730};
731
732struct TypeTableEntry {
733 TypeTableEntryId id;
734
735 LLVMTypeRef type_ref;
736 LLVMZigDIType *di_type;
737 uint64_t size_in_bits;
738 uint64_t align_in_bits;
739
740 Buf name;
741
742 union {
743 TypeTableEntryPointer pointer;
744 TypeTableEntryInt integral;
745 TypeTableEntryArray array;
746 TypeTableEntryStruct structure;
747 TypeTableEntryNumLit num_lit;
748 TypeTableEntryMaybe maybe;
749 } data;
750
751 // use these fields to make sure we don't duplicate type table entries for the same type
752 TypeTableEntry *pointer_parent[2][2]; // 0 - const. 1 - noalias
753 TypeTableEntry *unknown_size_array_parent[2][2]; // 0 - const. 1 - noalias
754 HashMap<uint64_t, TypeTableEntry *, uint64_hash, uint64_eq> arrays_by_size;
755 TypeTableEntry *maybe_parent;
756
757};
758
759struct ImporterInfo {
760 ImportTableEntry *import;
761 AstNode *source_node;
762};
763
764struct ImportTableEntry {
765 AstNode *root;
766 Buf *path; // relative to root_source_dir
767 LLVMZigDIFile *di_file;
768 Buf *source_code;
769 ZigList<int> *line_offsets;
770 BlockContext *block_context;
771 ZigList<ImporterInfo> importers;
772
773 // reminder: hash tables must be initialized before use
774 HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table;
775 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> type_table;
776};
777
778struct LabelTableEntry {
779 AstNode *label_node;
780 LLVMBasicBlockRef basic_block;
781 bool used;
782 bool entered_from_fallthrough;
783};
784
785enum FnAttrId {
786 FnAttrIdNaked,
787 FnAttrIdAlwaysInline,
788};
789
790struct FnTableEntry {
791 LLVMValueRef fn_value;
792 AstNode *proto_node;
793 AstNode *fn_def_node;
794 bool is_extern;
795 bool internal_linkage;
796 unsigned calling_convention;
797 ImportTableEntry *import_entry;
798 ZigList<FnAttrId> fn_attr_list;
799 // Required to be a pre-order traversal of the AST. (parents must come before children)
800 ZigList<BlockContext *> all_block_contexts;
801 TypeTableEntry *member_of_struct;
802 Buf symbol_name;
803
804 // reminder: hash tables must be initialized before use
805 HashMap<Buf *, LabelTableEntry *, buf_hash, buf_eql_buf> label_table;
806};
807
808enum BuiltinFnId {
809 BuiltinFnIdInvalid,
810 BuiltinFnIdArithmeticWithOverflow,
811 BuiltinFnIdMemcpy,
812 BuiltinFnIdMemset,
813};
814
815struct BuiltinFnEntry {
816 BuiltinFnId id;
817 Buf name;
818 int param_count;
819 TypeTableEntry *return_type;
820 TypeTableEntry **param_types;
821 LLVMValueRef fn_val;
822};
823
824struct CodeGen {
825 LLVMModuleRef module;
826 ZigList<ErrorMsg*> errors;
827 LLVMBuilderRef builder;
828 LLVMZigDIBuilder *dbuilder;
829 LLVMZigDICompileUnit *compile_unit;
830
831 ZigList<Buf *> lib_search_paths;
832
833 // reminder: hash tables must be initialized before use
834 HashMap<Buf *, LLVMValueRef, buf_hash, buf_eql_buf> str_table;
835 HashMap<Buf *, bool, buf_hash, buf_eql_buf> link_table;
836 HashMap<Buf *, ImportTableEntry *, buf_hash, buf_eql_buf> import_table;
837 HashMap<Buf *, BuiltinFnEntry *, buf_hash, buf_eql_buf> builtin_fn_table;
838 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> primitive_type_table;
839 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> unresolved_top_level_decls;
840
841 uint32_t next_unresolved_index;
842
843 struct {
844 TypeTableEntry *entry_bool;
845 TypeTableEntry *entry_u8;
846 TypeTableEntry *entry_u16;
847 TypeTableEntry *entry_u32;
848 TypeTableEntry *entry_u64;
849 TypeTableEntry *entry_i8;
850 TypeTableEntry *entry_i16;
851 TypeTableEntry *entry_i32;
852 TypeTableEntry *entry_i64;
853 TypeTableEntry *entry_isize;
854 TypeTableEntry *entry_usize;
855 TypeTableEntry *entry_f32;
856 TypeTableEntry *entry_f64;
857 TypeTableEntry *entry_c_string_literal;
858 TypeTableEntry *entry_void;
859 TypeTableEntry *entry_unreachable;
860 TypeTableEntry *entry_invalid;
861 } builtin_types;
862
863 TypeTableEntry *num_lit_types[NumLitCount];
864
865 LLVMTargetDataRef target_data_ref;
866 unsigned pointer_size_bytes;
867 bool is_static;
868 bool strip_debug_symbols;
869 bool have_exported_main;
870 bool link_libc;
871 Buf *libc_path;
872 CodeGenBuildType build_type;
873 LLVMTargetMachineRef target_machine;
874 LLVMZigDIFile *dummy_di_file;
875 bool is_native_target;
876 Buf *root_source_dir;
877 Buf *root_out_name;
878
879 // The function definitions this module includes. There must be a corresponding
880 // fn_protos entry.
881 ZigList<FnTableEntry *> fn_defs;
882 // The function prototypes this module includes. In the case of external declarations,
883 // there will not be a corresponding fn_defs entry.
884 ZigList<FnTableEntry *> fn_protos;
885 ZigList<VariableTableEntry *> global_vars;
886
887 OutType out_type;
888 FnTableEntry *cur_fn;
889 BlockContext *cur_block_context;
890 ZigList<LLVMBasicBlockRef> break_block_stack;
891 ZigList<LLVMBasicBlockRef> continue_block_stack;
892 bool c_stdint_used;
893 AstNode *root_export_decl;
894 int version_major;
895 int version_minor;
896 int version_patch;
897 bool verbose;
898 ErrColor err_color;
899 ImportTableEntry *root_import;
900 ImportTableEntry *bootstrap_import;
901 LLVMValueRef memcpy_fn_val;
902 bool error_during_imports;
903};
904
905struct VariableTableEntry {
906 Buf name;
907 TypeTableEntry *type;
908 LLVMValueRef value_ref;
909 bool is_const;
910 bool is_ptr; // if true, value_ref is a pointer
911 AstNode *decl_node;
912 LLVMZigDILocalVariable *di_loc_var;
913 int arg_index;
914};
915
916struct BlockContext {
917 AstNode *node; // either NodeTypeFnDef or NodeTypeBlock or NodeTypeRoot
918 FnTableEntry *fn_entry; // null at the module scope
919 BlockContext *parent; // null when this is the root
920 HashMap<Buf *, VariableTableEntry *, buf_hash, buf_eql_buf> variable_table;
921 ZigList<Cast *> cast_expr_alloca_list;
922 ZigList<StructValExprCodeGen *> struct_val_expr_alloca_list;
923 AstNode *parent_loop_node;
924 AstNode *next_child_parent_loop_node;
925 LLVMZigDIScope *di_scope;
926};
927
928#endif
src/analyze.cpp+353-177
...@@ -6,6 +6,7 @@...@@ -6,6 +6,7 @@
6 */6 */
77
8#include "analyze.hpp"8#include "analyze.hpp"
9#include "parser.hpp"
9#include "error.hpp"10#include "error.hpp"
10#include "zig_llvm.hpp"11#include "zig_llvm.hpp"
11#include "os.hpp"12#include "os.hpp"
...@@ -14,7 +15,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -14,7 +15,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
14 TypeTableEntry *expected_type, AstNode *node);15 TypeTableEntry *expected_type, AstNode *node);
15static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,16static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,
16 AstNode *node, AstNodeNumberLiteral *out_number_literal);17 AstNode *node, AstNodeNumberLiteral *out_number_literal);
17static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *type_node, DeclNode *decl_node);18static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *type_node, TopLevelDecl *decl_node);
18static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableEntry *import,19static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableEntry *import,
19 BlockContext *context, TypeTableEntry *expected_type, AstNode *node);20 BlockContext *context, TypeTableEntry *expected_type, AstNode *node);
2021
...@@ -317,7 +318,7 @@ static TypeTableEntry *eval_const_expr_bin_op(CodeGen *g, BlockContext *context,...@@ -317,7 +318,7 @@ static TypeTableEntry *eval_const_expr_bin_op(CodeGen *g, BlockContext *context,
317 out_number_literal->kind = NumLitU8;318 out_number_literal->kind = NumLitU8;
318 out_number_literal->overflow = false;319 out_number_literal->overflow = false;
319 out_number_literal->data.x_uint = (op1_lit.data.x_uint != op2_lit.data.x_uint);320 out_number_literal->data.x_uint = (op1_lit.data.x_uint != op2_lit.data.x_uint);
320 return node->codegen_node->expr_node.type_entry;321 return get_resolved_expr(node)->type_entry;
321 } else {322 } else {
322 return g->builtin_types.entry_invalid;323 return g->builtin_types.entry_invalid;
323 }324 }
...@@ -330,7 +331,7 @@ static TypeTableEntry *eval_const_expr_bin_op(CodeGen *g, BlockContext *context,...@@ -330,7 +331,7 @@ static TypeTableEntry *eval_const_expr_bin_op(CodeGen *g, BlockContext *context,
330 out_number_literal->kind = NumLitU8;331 out_number_literal->kind = NumLitU8;
331 out_number_literal->overflow = false;332 out_number_literal->overflow = false;
332 out_number_literal->data.x_uint = (op1_lit.data.x_uint < op2_lit.data.x_uint);333 out_number_literal->data.x_uint = (op1_lit.data.x_uint < op2_lit.data.x_uint);
333 return node->codegen_node->expr_node.type_entry;334 return get_resolved_expr(node)->type_entry;
334 } else {335 } else {
335 return g->builtin_types.entry_invalid;336 return g->builtin_types.entry_invalid;
336 }337 }
...@@ -343,7 +344,7 @@ static TypeTableEntry *eval_const_expr_bin_op(CodeGen *g, BlockContext *context,...@@ -343,7 +344,7 @@ static TypeTableEntry *eval_const_expr_bin_op(CodeGen *g, BlockContext *context,
343 out_number_literal->kind = NumLitU64;344 out_number_literal->kind = NumLitU64;
344 out_number_literal->overflow = false;345 out_number_literal->overflow = false;
345 out_number_literal->data.x_uint = (op1_lit.data.x_uint % op2_lit.data.x_uint);346 out_number_literal->data.x_uint = (op1_lit.data.x_uint % op2_lit.data.x_uint);
346 return node->codegen_node->expr_node.type_entry;347 return get_resolved_expr(node)->type_entry;
347 } else {348 } else {
348 return g->builtin_types.entry_invalid;349 return g->builtin_types.entry_invalid;
349 }350 }
...@@ -390,20 +391,20 @@ static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,...@@ -390,20 +391,20 @@ static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,
390 switch (node->type) {391 switch (node->type) {
391 case NodeTypeNumberLiteral:392 case NodeTypeNumberLiteral:
392 *out_number_literal = node->data.number_literal;393 *out_number_literal = node->data.number_literal;
393 return node->codegen_node->expr_node.type_entry;394 return get_resolved_expr(node)->type_entry;
394 case NodeTypeBoolLiteral:395 case NodeTypeBoolLiteral:
395 out_number_literal->data.x_uint = node->data.bool_literal ? 1 : 0;396 out_number_literal->data.x_uint = node->data.bool_literal.value ? 1 : 0;
396 return node->codegen_node->expr_node.type_entry;397 return get_resolved_expr(node)->type_entry;
397 case NodeTypeNullLiteral:398 case NodeTypeNullLiteral:
398 return node->codegen_node->expr_node.type_entry;399 return get_resolved_expr(node)->type_entry;
399 case NodeTypeBinOpExpr:400 case NodeTypeBinOpExpr:
400 return eval_const_expr_bin_op(g, context, node, out_number_literal);401 return eval_const_expr_bin_op(g, context, node, out_number_literal);
401 case NodeTypeCompilerFnType:402 case NodeTypeCompilerFnType:
402 {403 {
403 Buf *name = &node->data.compiler_fn_type.name;404 Buf *name = &node->data.compiler_fn_type.name;
404 TypeTableEntry *expr_type = node->codegen_node->expr_node.type_entry;405 TypeTableEntry *expr_type = get_resolved_expr(node)->type_entry;
405 if (buf_eql_str(name, "sizeof")) {406 if (buf_eql_str(name, "sizeof")) {
406 TypeTableEntry *target_type = node->data.compiler_fn_type.type->codegen_node->data.type_node.entry;407 TypeTableEntry *target_type = node->data.compiler_fn_type.type->data.type.entry;
407 out_number_literal->overflow = false;408 out_number_literal->overflow = false;
408 out_number_literal->data.x_uint = target_type->size_in_bits / 8;409 out_number_literal->data.x_uint = target_type->size_in_bits / 8;
409 out_number_literal->kind = get_number_literal_kind_unsigned(out_number_literal->data.x_uint);410 out_number_literal->kind = get_number_literal_kind_unsigned(out_number_literal->data.x_uint);
...@@ -420,11 +421,11 @@ static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,...@@ -420,11 +421,11 @@ static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,
420 }421 }
421 case NodeTypeSymbol:422 case NodeTypeSymbol:
422 {423 {
423 VariableTableEntry *var = find_variable(context, &node->data.symbol);424 VariableTableEntry *var = find_variable(context, &node->data.symbol_expr.symbol);
424 assert(var);425 assert(var);
425 AstNode *decl_node = var->decl_node;426 AstNode *decl_node = var->decl_node;
426 AstNode *expr_node = decl_node->data.variable_declaration.expr;427 AstNode *expr_node = decl_node->data.variable_declaration.expr;
427 BlockContext *next_context = expr_node->codegen_node->expr_node.block_context;428 BlockContext *next_context = get_resolved_expr(expr_node)->block_context;
428 return eval_const_expr(g, next_context, expr_node, out_number_literal);429 return eval_const_expr(g, next_context, expr_node, out_number_literal);
429 }430 }
430 default:431 default:
...@@ -436,8 +437,6 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry...@@ -436,8 +437,6 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry
436 BlockContext *context, bool noalias_allowed)437 BlockContext *context, bool noalias_allowed)
437{438{
438 assert(node->type == NodeTypeType);439 assert(node->type == NodeTypeType);
439 alloc_codegen_node(node);
440 TypeNode *type_node = &node->codegen_node->data.type_node;
441 switch (node->data.type.type) {440 switch (node->data.type.type) {
442 case AstNodeTypeTypePrimitive:441 case AstNodeTypeTypePrimitive:
443 {442 {
...@@ -447,13 +446,13 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry...@@ -447,13 +446,13 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry
447 table_entry = g->primitive_type_table.maybe_get(name);446 table_entry = g->primitive_type_table.maybe_get(name);
448 }447 }
449 if (table_entry) {448 if (table_entry) {
450 type_node->entry = table_entry->value;449 node->data.type.entry = table_entry->value;
451 } else {450 } else {
452 add_node_error(g, node,451 add_node_error(g, node,
453 buf_sprintf("invalid type name: '%s'", buf_ptr(name)));452 buf_sprintf("invalid type name: '%s'", buf_ptr(name)));
454 type_node->entry = g->builtin_types.entry_invalid;453 node->data.type.entry = g->builtin_types.entry_invalid;
455 }454 }
456 return type_node->entry;455 return node->data.type.entry;
457 }456 }
458 case AstNodeTypeTypePointer:457 case AstNodeTypeTypePointer:
459 {458 {
...@@ -468,19 +467,19 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry...@@ -468,19 +467,19 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry
468 }467 }
469468
470 resolve_type(g, node->data.type.child_type, import, context, false);469 resolve_type(g, node->data.type.child_type, import, context, false);
471 TypeTableEntry *child_type = node->data.type.child_type->codegen_node->data.type_node.entry;470 TypeTableEntry *child_type = node->data.type.child_type->data.type.entry;
472 assert(child_type);471 assert(child_type);
473 if (child_type->id == TypeTableEntryIdUnreachable) {472 if (child_type->id == TypeTableEntryIdUnreachable) {
474 add_node_error(g, node,473 add_node_error(g, node,
475 buf_create_from_str("pointer to unreachable not allowed"));474 buf_create_from_str("pointer to unreachable not allowed"));
476 type_node->entry = g->builtin_types.entry_invalid;475 node->data.type.entry = g->builtin_types.entry_invalid;
477 return type_node->entry;476 return node->data.type.entry;
478 } else if (child_type->id == TypeTableEntryIdInvalid) {477 } else if (child_type->id == TypeTableEntryIdInvalid) {
479 type_node->entry = child_type;478 node->data.type.entry = child_type;
480 return child_type;479 return child_type;
481 } else {480 } else {
482 type_node->entry = get_pointer_to_type(g, child_type, node->data.type.is_const, use_noalias);481 node->data.type.entry = get_pointer_to_type(g, child_type, node->data.type.is_const, use_noalias);
483 return type_node->entry;482 return node->data.type.entry;
484 }483 }
485 }484 }
486 case AstNodeTypeTypeArray:485 case AstNodeTypeTypeArray:
...@@ -501,16 +500,16 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry...@@ -501,16 +500,16 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry
501 if (child_type->id == TypeTableEntryIdUnreachable) {500 if (child_type->id == TypeTableEntryIdUnreachable) {
502 add_node_error(g, node,501 add_node_error(g, node,
503 buf_create_from_str("array of unreachable not allowed"));502 buf_create_from_str("array of unreachable not allowed"));
504 type_node->entry = g->builtin_types.entry_invalid;503 node->data.type.entry = g->builtin_types.entry_invalid;
505 return type_node->entry;504 return node->data.type.entry;
506 }505 }
507506
508 if (size_node) {507 if (size_node) {
509 TypeTableEntry *size_type = analyze_expression(g, import, context,508 TypeTableEntry *size_type = analyze_expression(g, import, context,
510 g->builtin_types.entry_usize, size_node);509 g->builtin_types.entry_usize, size_node);
511 if (size_type->id == TypeTableEntryIdInvalid) {510 if (size_type->id == TypeTableEntryIdInvalid) {
512 type_node->entry = g->builtin_types.entry_invalid;511 node->data.type.entry = g->builtin_types.entry_invalid;
513 return type_node->entry;512 return node->data.type.entry;
514 }513 }
515514
516 AstNodeNumberLiteral number_literal;515 AstNodeNumberLiteral number_literal;
...@@ -520,27 +519,27 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry...@@ -520,27 +519,27 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry
520 if (resolved_type->data.integral.is_signed) {519 if (resolved_type->data.integral.is_signed) {
521 add_node_error(g, size_node,520 add_node_error(g, size_node,
522 buf_create_from_str("array size must be unsigned integer"));521 buf_create_from_str("array size must be unsigned integer"));
523 type_node->entry = g->builtin_types.entry_invalid;522 node->data.type.entry = g->builtin_types.entry_invalid;
524 } else {523 } else {
525 type_node->entry = get_array_type(g, import, child_type, number_literal.data.x_uint);524 node->data.type.entry = get_array_type(g, import, child_type, number_literal.data.x_uint);
526 }525 }
527 } else {526 } else {
528 add_node_error(g, size_node,527 add_node_error(g, size_node,
529 buf_create_from_str("unable to resolve constant expression"));528 buf_create_from_str("unable to resolve constant expression"));
530 type_node->entry = g->builtin_types.entry_invalid;529 node->data.type.entry = g->builtin_types.entry_invalid;
531 }530 }
532 return type_node->entry;531 return node->data.type.entry;
533 } else {532 } else {
534 type_node->entry = get_unknown_size_array_type(g, import, child_type,533 node->data.type.entry = get_unknown_size_array_type(g, import, child_type,
535 node->data.type.is_const, use_noalias);534 node->data.type.is_const, use_noalias);
536 return type_node->entry;535 return node->data.type.entry;
537 }536 }
538537
539 }538 }
540 case AstNodeTypeTypeMaybe:539 case AstNodeTypeTypeMaybe:
541 {540 {
542 resolve_type(g, node->data.type.child_type, import, context, false);541 resolve_type(g, node->data.type.child_type, import, context, false);
543 TypeTableEntry *child_type = node->data.type.child_type->codegen_node->data.type_node.entry;542 TypeTableEntry *child_type = node->data.type.child_type->data.type.entry;
544 assert(child_type);543 assert(child_type);
545 if (child_type->id == TypeTableEntryIdUnreachable) {544 if (child_type->id == TypeTableEntryIdUnreachable) {
546 add_node_error(g, node,545 add_node_error(g, node,
...@@ -548,22 +547,22 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry...@@ -548,22 +547,22 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry
548 } else if (child_type->id == TypeTableEntryIdInvalid) {547 } else if (child_type->id == TypeTableEntryIdInvalid) {
549 return child_type;548 return child_type;
550 }549 }
551 type_node->entry = get_maybe_type(g, import, child_type);550 node->data.type.entry = get_maybe_type(g, import, child_type);
552 return type_node->entry;551 return node->data.type.entry;
553 }552 }
554 case AstNodeTypeTypeCompilerExpr:553 case AstNodeTypeTypeCompilerExpr:
555 {554 {
556 AstNode *compiler_expr_node = node->data.type.compiler_expr;555 AstNode *compiler_expr_node = node->data.type.compiler_expr;
557 Buf *fn_name = &compiler_expr_node->data.compiler_fn_expr.name;556 Buf *fn_name = &compiler_expr_node->data.compiler_fn_expr.name;
558 if (buf_eql_str(fn_name, "typeof")) {557 if (buf_eql_str(fn_name, "typeof")) {
559 type_node->entry = analyze_expression(g, import, context, nullptr,558 node->data.type.entry = analyze_expression(g, import, context, nullptr,
560 compiler_expr_node->data.compiler_fn_expr.expr);559 compiler_expr_node->data.compiler_fn_expr.expr);
561 } else {560 } else {
562 add_node_error(g, node,561 add_node_error(g, node,
563 buf_sprintf("invalid compiler function: '%s'", buf_ptr(fn_name)));562 buf_sprintf("invalid compiler function: '%s'", buf_ptr(fn_name)));
564 type_node->entry = g->builtin_types.entry_invalid;563 node->data.type.entry = g->builtin_types.entry_invalid;
565 }564 }
566 return type_node->entry;565 return node->data.type.entry;
567 }566 }
568 }567 }
569 zig_unreachable();568 zig_unreachable();
...@@ -631,8 +630,7 @@ static void preview_function_labels(CodeGen *g, AstNode *node, FnTableEntry *fn_...@@ -631,8 +630,7 @@ static void preview_function_labels(CodeGen *g, AstNode *node, FnTableEntry *fn_
631 Buf *name = &label_node->data.label.name;630 Buf *name = &label_node->data.label.name;
632 fn_table_entry->label_table.put(name, label_entry);631 fn_table_entry->label_table.put(name, label_entry);
633632
634 alloc_codegen_node(label_node);633 label_node->data.label.label_entry = label_entry;
635 label_node->codegen_node->data.label_entry = label_entry;
636 }634 }
637}635}
638636
...@@ -732,7 +730,8 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,...@@ -732,7 +730,8 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
732 AstNode *struct_node = proto_node->data.fn_proto.struct_node;730 AstNode *struct_node = proto_node->data.fn_proto.struct_node;
733 TypeTableEntry *struct_type;731 TypeTableEntry *struct_type;
734 if (struct_node) {732 if (struct_node) {
735 struct_type = struct_node->codegen_node->data.struct_decl_node.type_entry;733 assert(struct_node->type == NodeTypeStructDecl);
734 struct_type = struct_node->data.struct_decl.type_entry;
736 } else {735 } else {
737 struct_type = nullptr;736 struct_type = nullptr;
738 }737 }
...@@ -749,13 +748,14 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,...@@ -749,13 +748,14 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
749 if (entry) {748 if (entry) {
750 add_node_error(g, proto_node,749 add_node_error(g, proto_node,
751 buf_sprintf("redefinition of '%s'", buf_ptr(proto_name)));750 buf_sprintf("redefinition of '%s'", buf_ptr(proto_name)));
752 proto_node->codegen_node->data.fn_proto_node.skip = true;751 proto_node->data.fn_proto.skip = true;
753 skip = true;752 skip = true;
754 } else if (is_pub) {753 } else if (is_pub) {
754 // TODO is this else if branch a mistake?
755 auto entry = fn_table->maybe_get(proto_name);755 auto entry = fn_table->maybe_get(proto_name);
756 if (entry) {756 if (entry) {
757 add_node_error(g, proto_node, buf_sprintf("redefinition of '%s'", buf_ptr(proto_name)));757 add_node_error(g, proto_node, buf_sprintf("redefinition of '%s'", buf_ptr(proto_name)));
758 proto_node->codegen_node->data.fn_proto_node.skip = true;758 proto_node->data.fn_proto.skip = true;
759 skip = true;759 skip = true;
760 }760 }
761 }761 }
...@@ -804,7 +804,7 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,...@@ -804,7 +804,7 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
804 resolve_function_proto(g, proto_node, fn_table_entry, import);804 resolve_function_proto(g, proto_node, fn_table_entry, import);
805805
806806
807 proto_node->codegen_node->data.fn_proto_node.fn_table_entry = fn_table_entry;807 proto_node->data.fn_proto.fn_table_entry = fn_table_entry;
808808
809 if (fn_def_node) {809 if (fn_def_node) {
810 preview_function_labels(g, fn_def_node->data.fn_def.body, fn_table_entry);810 preview_function_labels(g, fn_def_node->data.fn_def.body, fn_table_entry);
...@@ -888,8 +888,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode...@@ -888,8 +888,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
888 break;888 break;
889 case NodeTypeStructDecl:889 case NodeTypeStructDecl:
890 {890 {
891 StructDeclNode *struct_codegen = &node->codegen_node->data.struct_decl_node;891 TypeTableEntry *type_entry = node->data.struct_decl.type_entry;
892 TypeTableEntry *type_entry = struct_codegen->type_entry;
893892
894 resolve_struct_type(g, import, type_entry);893 resolve_struct_type(g, import, type_entry);
895894
...@@ -962,8 +961,8 @@ static TypeTableEntry *get_return_type(BlockContext *context) {...@@ -962,8 +961,8 @@ static TypeTableEntry *get_return_type(BlockContext *context) {
962 AstNode *fn_proto_node = fn_entry->proto_node;961 AstNode *fn_proto_node = fn_entry->proto_node;
963 assert(fn_proto_node->type == NodeTypeFnProto);962 assert(fn_proto_node->type == NodeTypeFnProto);
964 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;963 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
965 assert(return_type_node->codegen_node);964 assert(return_type_node->type == NodeTypeType);
966 return return_type_node->codegen_node->data.type_node.entry;965 return return_type_node->data.type.entry;
967}966}
968967
969static bool num_lit_fits_in_other_type(CodeGen *g, TypeTableEntry *literal_type, TypeTableEntry *other_type) {968static bool num_lit_fits_in_other_type(CodeGen *g, TypeTableEntry *literal_type, TypeTableEntry *other_type) {
...@@ -1003,15 +1002,14 @@ static bool num_lit_fits_in_other_type(CodeGen *g, TypeTableEntry *literal_type,...@@ -1003,15 +1002,14 @@ static bool num_lit_fits_in_other_type(CodeGen *g, TypeTableEntry *literal_type,
1003 zig_unreachable();1002 zig_unreachable();
1004}1003}
10051004
1006static TypeTableEntry * resolve_rhs_number_literal(CodeGen *g, AstNode *non_literal_node,1005static TypeTableEntry *resolve_rhs_number_literal(CodeGen *g, AstNode *non_literal_node,
1007 TypeTableEntry *non_literal_type, AstNode *literal_node, TypeTableEntry *literal_type)1006 TypeTableEntry *non_literal_type, AstNode *literal_node, TypeTableEntry *literal_type)
1008{1007{
1009 assert(literal_node->codegen_node);1008 NumLitCodeGen *num_lit_codegen = get_resolved_num_lit(literal_node);
1010 NumberLiteralNode *codegen_num_lit = &literal_node->codegen_node->data.num_lit_node;
10111009
1012 if (non_literal_type && num_lit_fits_in_other_type(g, literal_type, non_literal_type)) {1010 if (non_literal_type && num_lit_fits_in_other_type(g, literal_type, non_literal_type)) {
1013 assert(!codegen_num_lit->resolved_type);1011 assert(!num_lit_codegen->resolved_type);
1014 codegen_num_lit->resolved_type = non_literal_type;1012 num_lit_codegen->resolved_type = non_literal_type;
1015 return non_literal_type;1013 return non_literal_type;
1016 } else {1014 } else {
1017 return nullptr;1015 return nullptr;
...@@ -1024,11 +1022,8 @@ static TypeTableEntry * resolve_number_literals(CodeGen *g, AstNode *node1, AstN...@@ -1024,11 +1022,8 @@ static TypeTableEntry * resolve_number_literals(CodeGen *g, AstNode *node1, AstN
1024 if (type1->id == TypeTableEntryIdNumberLiteral &&1022 if (type1->id == TypeTableEntryIdNumberLiteral &&
1025 type2->id == TypeTableEntryIdNumberLiteral)1023 type2->id == TypeTableEntryIdNumberLiteral)
1026 {1024 {
1027 assert(node1->codegen_node);1025 NumLitCodeGen *codegen_num_lit_1 = get_resolved_num_lit(node1);
1028 assert(node2->codegen_node);1026 NumLitCodeGen *codegen_num_lit_2 = get_resolved_num_lit(node2);
1029
1030 NumberLiteralNode *codegen_num_lit_1 = &node1->codegen_node->data.num_lit_node;
1031 NumberLiteralNode *codegen_num_lit_2 = &node2->codegen_node->data.num_lit_node;
10321027
1033 assert(!codegen_num_lit_1->resolved_type);1028 assert(!codegen_num_lit_1->resolved_type);
1034 assert(!codegen_num_lit_2->resolved_type);1029 assert(!codegen_num_lit_2->resolved_type);
...@@ -1113,9 +1108,10 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont...@@ -1113,9 +1108,10 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
1113 if (actual_type->id == TypeTableEntryIdNumberLiteral &&1108 if (actual_type->id == TypeTableEntryIdNumberLiteral &&
1114 num_lit_fits_in_other_type(g, actual_type, expected_type))1109 num_lit_fits_in_other_type(g, actual_type, expected_type))
1115 {1110 {
1116 assert(!node->codegen_node->data.num_lit_node.resolved_type ||1111 NumLitCodeGen *num_lit_code_gen = get_resolved_num_lit(node);
1117 node->codegen_node->data.num_lit_node.resolved_type == expected_type);1112 assert(!num_lit_code_gen->resolved_type ||
1118 node->codegen_node->data.num_lit_node.resolved_type = expected_type;1113 num_lit_code_gen->resolved_type == expected_type);
1114 num_lit_code_gen->resolved_type = expected_type;
1119 return expected_type;1115 return expected_type;
1120 }1116 }
11211117
...@@ -1134,10 +1130,11 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont...@@ -1134,10 +1130,11 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
1134 if (resolved_type->id == TypeTableEntryIdInvalid) {1130 if (resolved_type->id == TypeTableEntryIdInvalid) {
1135 return resolved_type;1131 return resolved_type;
1136 }1132 }
1137 node->codegen_node->expr_node.implicit_maybe_cast.op = CastOpMaybeWrap;1133 Expr *expr = get_resolved_expr(node);
1138 node->codegen_node->expr_node.implicit_maybe_cast.after_type = expected_type;1134 expr->implicit_maybe_cast.op = CastOpMaybeWrap;
1139 node->codegen_node->expr_node.implicit_maybe_cast.source_node = node;1135 expr->implicit_maybe_cast.after_type = expected_type;
1140 context->cast_expr_alloca_list.append(&node->codegen_node->expr_node.implicit_maybe_cast);1136 expr->implicit_maybe_cast.source_node = node;
1137 context->cast_expr_alloca_list.append(&expr->implicit_maybe_cast);
1141 return expected_type;1138 return expected_type;
1142 }1139 }
11431140
...@@ -1147,9 +1144,10 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont...@@ -1147,9 +1144,10 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
1147 expected_type->data.integral.is_signed == actual_type->data.integral.is_signed &&1144 expected_type->data.integral.is_signed == actual_type->data.integral.is_signed &&
1148 expected_type->size_in_bits > actual_type->size_in_bits)1145 expected_type->size_in_bits > actual_type->size_in_bits)
1149 {1146 {
1150 node->codegen_node->expr_node.implicit_cast.after_type = expected_type;1147 Expr *expr = get_resolved_expr(node);
1151 node->codegen_node->expr_node.implicit_cast.op = CastOpIntWidenOrShorten;1148 expr->implicit_cast.after_type = expected_type;
1152 node->codegen_node->expr_node.implicit_cast.source_node = node;1149 expr->implicit_cast.op = CastOpIntWidenOrShorten;
1150 expr->implicit_cast.source_node = node;
1153 return expected_type;1151 return expected_type;
1154 }1152 }
11551153
...@@ -1159,10 +1157,11 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont...@@ -1159,10 +1157,11 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
1159 actual_type->id == TypeTableEntryIdArray &&1157 actual_type->id == TypeTableEntryIdArray &&
1160 actual_type->data.array.child_type == expected_type->data.structure.fields[0].type_entry->data.pointer.child_type)1158 actual_type->data.array.child_type == expected_type->data.structure.fields[0].type_entry->data.pointer.child_type)
1161 {1159 {
1162 node->codegen_node->expr_node.implicit_cast.after_type = expected_type;1160 Expr *expr = get_resolved_expr(node);
1163 node->codegen_node->expr_node.implicit_cast.op = CastOpToUnknownSizeArray;1161 expr->implicit_cast.after_type = expected_type;
1164 node->codegen_node->expr_node.implicit_cast.source_node = node;1162 expr->implicit_cast.op = CastOpToUnknownSizeArray;
1165 context->cast_expr_alloca_list.append(&node->codegen_node->expr_node.implicit_cast);1163 expr->implicit_cast.source_node = node;
1164 context->cast_expr_alloca_list.append(&expr->implicit_cast);
1166 return expected_type;1165 return expected_type;
1167 }1166 }
11681167
...@@ -1225,7 +1224,7 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {...@@ -1225,7 +1224,7 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
12251224
1226 if (node && node->type == NodeTypeFnDef) {1225 if (node && node->type == NodeTypeFnDef) {
1227 AstNode *fn_proto_node = node->data.fn_def.fn_proto;1226 AstNode *fn_proto_node = node->data.fn_def.fn_proto;
1228 context->fn_entry = fn_proto_node->codegen_node->data.fn_proto_node.fn_table_entry;1227 context->fn_entry = fn_proto_node->data.fn_proto.fn_table_entry;
1229 } else if (parent) {1228 } else if (parent) {
1230 context->fn_entry = parent->fn_entry;1229 context->fn_entry = parent->fn_entry;
1231 }1230 }
...@@ -1275,6 +1274,8 @@ static void get_struct_field(TypeTableEntry *struct_type, Buf *name, TypeStructF...@@ -1275,6 +1274,8 @@ static void get_struct_field(TypeTableEntry *struct_type, Buf *name, TypeStructF
1275static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,1274static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
1276 AstNode *node)1275 AstNode *node)
1277{1276{
1277 assert(node->type == NodeTypeFieldAccessExpr);
1278
1278 TypeTableEntry *struct_type = analyze_expression(g, import, context, nullptr,1279 TypeTableEntry *struct_type = analyze_expression(g, import, context, nullptr,
1279 node->data.field_access_expr.struct_expr);1280 node->data.field_access_expr.struct_expr);
12801281
...@@ -1283,20 +1284,16 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i...@@ -1283,20 +1284,16 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
1283 if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer &&1284 if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer &&
1284 struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct))1285 struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct))
1285 {1286 {
1286 assert(node->codegen_node);
1287 FieldAccessNode *codegen_field_access = &node->codegen_node->data.field_access_node;
1288 assert(codegen_field_access);
1289
1290 Buf *field_name = &node->data.field_access_expr.field_name;1287 Buf *field_name = &node->data.field_access_expr.field_name;
12911288
1292 TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ?1289 TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ?
1293 struct_type : struct_type->data.pointer.child_type;1290 struct_type : struct_type->data.pointer.child_type;
12941291
1295 get_struct_field(bare_struct_type, field_name,1292 get_struct_field(bare_struct_type, field_name,
1296 &codegen_field_access->type_struct_field,1293 &node->data.field_access_expr.type_struct_field,
1297 &codegen_field_access->field_index);1294 &node->data.field_access_expr.field_index);
1298 if (codegen_field_access->type_struct_field) {1295 if (node->data.field_access_expr.type_struct_field) {
1299 return_type = codegen_field_access->type_struct_field->type_entry;1296 return_type = node->data.field_access_expr.type_struct_field->type_entry;
1300 } else {1297 } else {
1301 add_node_error(g, node,1298 add_node_error(g, node,
1302 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&struct_type->name)));1299 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&struct_type->name)));
...@@ -1329,6 +1326,8 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i...@@ -1329,6 +1326,8 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
1329static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,1326static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
1330 AstNode *node)1327 AstNode *node)
1331{1328{
1329 assert(node->type == NodeTypeSliceExpr);
1330
1332 TypeTableEntry *array_type = analyze_expression(g, import, context, nullptr,1331 TypeTableEntry *array_type = analyze_expression(g, import, context, nullptr,
1333 node->data.slice_expr.array_ref_expr);1332 node->data.slice_expr.array_ref_expr);
13341333
...@@ -1355,10 +1354,9 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import,...@@ -1355,10 +1354,9 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import,
1355 }1354 }
13561355
1357 if (return_type->id != TypeTableEntryIdInvalid) {1356 if (return_type->id != TypeTableEntryIdInvalid) {
1358 assert(node->codegen_node);1357 node->data.slice_expr.resolved_struct_val_expr.type_entry = return_type;
1359 node->codegen_node->data.struct_val_expr_node.type_entry = return_type;1358 node->data.slice_expr.resolved_struct_val_expr.source_node = node;
1360 node->codegen_node->data.struct_val_expr_node.source_node = node;1359 context->struct_val_expr_alloca_list.append(&node->data.slice_expr.resolved_struct_val_expr);
1361 context->struct_val_expr_alloca_list.append(&node->codegen_node->data.struct_val_expr_node);
1362 }1360 }
13631361
1364 analyze_expression(g, import, context, g->builtin_types.entry_usize, node->data.slice_expr.start);1362 analyze_expression(g, import, context, g->builtin_types.entry_usize, node->data.slice_expr.start);
...@@ -1463,6 +1461,8 @@ static bool is_op_allowed(TypeTableEntry *type, BinOpType op) {...@@ -1463,6 +1461,8 @@ static bool is_op_allowed(TypeTableEntry *type, BinOpType op) {
1463static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,1461static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
1464 TypeTableEntry *expected_type, AstNode *node)1462 TypeTableEntry *expected_type, AstNode *node)
1465{1463{
1464 assert(node->type == NodeTypeCastExpr);
1465
1466 TypeTableEntry *wanted_type = resolve_type(g, node->data.cast_expr.type, import, context, false);1466 TypeTableEntry *wanted_type = resolve_type(g, node->data.cast_expr.type, import, context, false);
1467 TypeTableEntry *actual_type = analyze_expression(g, import, context, nullptr, node->data.cast_expr.expr);1467 TypeTableEntry *actual_type = analyze_expression(g, import, context, nullptr, node->data.cast_expr.expr);
14681468
...@@ -1472,43 +1472,41 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B...@@ -1472,43 +1472,41 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
1472 return g->builtin_types.entry_invalid;1472 return g->builtin_types.entry_invalid;
1473 }1473 }
14741474
1475 CastNode *cast_node = &node->codegen_node->data.cast_node;1475 Cast *cast = &node->data.cast_expr.cast;
1476 cast_node->source_node = node;1476 cast->source_node = node;
1477 cast_node->after_type = wanted_type;1477 cast->after_type = wanted_type;
14781478
1479 // special casing this for now, TODO think about casting and do a general solution
1480 if ((wanted_type == g->builtin_types.entry_isize || wanted_type == g->builtin_types.entry_usize) &&1479 if ((wanted_type == g->builtin_types.entry_isize || wanted_type == g->builtin_types.entry_usize) &&
1481 actual_type->id == TypeTableEntryIdPointer)1480 actual_type->id == TypeTableEntryIdPointer)
1482 {1481 {
1483 cast_node->op = CastOpPtrToInt;1482 cast->op = CastOpPtrToInt;
1484 return wanted_type;1483 return wanted_type;
1485 } else if (wanted_type->id == TypeTableEntryIdInt &&1484 } else if (wanted_type->id == TypeTableEntryIdInt &&
1486 actual_type->id == TypeTableEntryIdInt)1485 actual_type->id == TypeTableEntryIdInt)
1487 {1486 {
1488 cast_node->op = CastOpIntWidenOrShorten;1487 cast->op = CastOpIntWidenOrShorten;
1489 return wanted_type;1488 return wanted_type;
1490 } else if (wanted_type->id == TypeTableEntryIdStruct &&1489 } else if (wanted_type->id == TypeTableEntryIdStruct &&
1491 wanted_type->data.structure.is_unknown_size_array &&1490 wanted_type->data.structure.is_unknown_size_array &&
1492 actual_type->id == TypeTableEntryIdArray &&1491 actual_type->id == TypeTableEntryIdArray &&
1493 actual_type->data.array.child_type == wanted_type->data.structure.fields[0].type_entry)1492 actual_type->data.array.child_type == wanted_type->data.structure.fields[0].type_entry)
1494 {1493 {
1495 cast_node->op = CastOpToUnknownSizeArray;1494 cast->op = CastOpToUnknownSizeArray;
1496 context->cast_expr_alloca_list.append(cast_node);1495 context->cast_expr_alloca_list.append(cast);
1497 return wanted_type;1496 return wanted_type;
1498 } else if (actual_type->id == TypeTableEntryIdNumberLiteral &&1497 } else if (actual_type->id == TypeTableEntryIdNumberLiteral &&
1499 num_lit_fits_in_other_type(g, actual_type, wanted_type))1498 num_lit_fits_in_other_type(g, actual_type, wanted_type))
1500 {1499 {
1501 AstNode *literal_node = node->data.cast_expr.expr;1500 AstNode *literal_node = node->data.cast_expr.expr;
1502 assert(literal_node->codegen_node);1501 NumLitCodeGen *codegen_num_lit = get_resolved_num_lit(literal_node);
1503 NumberLiteralNode *codegen_num_lit = &literal_node->codegen_node->data.num_lit_node;
1504 assert(!codegen_num_lit->resolved_type);1502 assert(!codegen_num_lit->resolved_type);
1505 codegen_num_lit->resolved_type = wanted_type;1503 codegen_num_lit->resolved_type = wanted_type;
1506 cast_node->op = CastOpNothing;1504 cast->op = CastOpNothing;
1507 return wanted_type;1505 return wanted_type;
1508 } else if (actual_type->id == TypeTableEntryIdPointer &&1506 } else if (actual_type->id == TypeTableEntryIdPointer &&
1509 wanted_type->id == TypeTableEntryIdPointer)1507 wanted_type->id == TypeTableEntryIdPointer)
1510 {1508 {
1511 cast_node->op = CastOpPointerReinterpret;1509 cast->op = CastOpPointerReinterpret;
1512 return wanted_type;1510 return wanted_type;
1513 } else {1511 } else {
1514 add_node_error(g, node,1512 add_node_error(g, node,
...@@ -1529,7 +1527,7 @@ static TypeTableEntry *analyze_lvalue(CodeGen *g, ImportTableEntry *import, Bloc...@@ -1529,7 +1527,7 @@ static TypeTableEntry *analyze_lvalue(CodeGen *g, ImportTableEntry *import, Bloc
1529{1527{
1530 TypeTableEntry *expected_rhs_type = nullptr;1528 TypeTableEntry *expected_rhs_type = nullptr;
1531 if (lhs_node->type == NodeTypeSymbol) {1529 if (lhs_node->type == NodeTypeSymbol) {
1532 Buf *name = &lhs_node->data.symbol;1530 Buf *name = &lhs_node->data.symbol_expr.symbol;
1533 VariableTableEntry *var = find_variable(block_context, name);1531 VariableTableEntry *var = find_variable(block_context, name);
1534 if (var) {1532 if (var) {
1535 if (purpose == LValPurposeAssign && var->is_const) {1533 if (purpose == LValPurposeAssign && var->is_const) {
...@@ -1551,7 +1549,6 @@ static TypeTableEntry *analyze_lvalue(CodeGen *g, ImportTableEntry *import, Bloc...@@ -1551,7 +1549,6 @@ static TypeTableEntry *analyze_lvalue(CodeGen *g, ImportTableEntry *import, Bloc
1551 } else if (lhs_node->type == NodeTypeArrayAccessExpr) {1549 } else if (lhs_node->type == NodeTypeArrayAccessExpr) {
1552 expected_rhs_type = analyze_array_access_expr(g, import, block_context, lhs_node);1550 expected_rhs_type = analyze_array_access_expr(g, import, block_context, lhs_node);
1553 } else if (lhs_node->type == NodeTypeFieldAccessExpr) {1551 } else if (lhs_node->type == NodeTypeFieldAccessExpr) {
1554 alloc_codegen_node(lhs_node);
1555 expected_rhs_type = analyze_field_access_expr(g, import, block_context, lhs_node);1552 expected_rhs_type = analyze_field_access_expr(g, import, block_context, lhs_node);
1556 } else if (lhs_node->type == NodeTypePrefixOpExpr &&1553 } else if (lhs_node->type == NodeTypePrefixOpExpr &&
1557 lhs_node->data.prefix_op_expr.prefix_op == PrefixOpDereference)1554 lhs_node->data.prefix_op_expr.prefix_op == PrefixOpDereference)
...@@ -1774,10 +1771,9 @@ static TypeTableEntry *analyze_null_literal_expr(CodeGen *g, ImportTableEntry *i...@@ -1774,10 +1771,9 @@ static TypeTableEntry *analyze_null_literal_expr(CodeGen *g, ImportTableEntry *i
1774 if (expected_type) {1771 if (expected_type) {
1775 assert(expected_type->id == TypeTableEntryIdMaybe);1772 assert(expected_type->id == TypeTableEntryIdMaybe);
17761773
1777 assert(node->codegen_node);1774 node->data.null_literal.resolved_struct_val_expr.type_entry = expected_type;
1778 node->codegen_node->data.struct_val_expr_node.type_entry = expected_type;1775 node->data.null_literal.resolved_struct_val_expr.source_node = node;
1779 node->codegen_node->data.struct_val_expr_node.source_node = node;1776 block_context->struct_val_expr_alloca_list.append(&node->data.null_literal.resolved_struct_val_expr);
1780 block_context->struct_val_expr_alloca_list.append(&node->codegen_node->data.struct_val_expr_node);
17811777
1782 return expected_type;1778 return expected_type;
1783 } else {1779 } else {
...@@ -1796,7 +1792,7 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry...@@ -1796,7 +1792,7 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry
1796 buf_sprintf("number literal too large to be represented in any type"));1792 buf_sprintf("number literal too large to be represented in any type"));
1797 return g->builtin_types.entry_invalid;1793 return g->builtin_types.entry_invalid;
1798 } else if (expected_type) {1794 } else if (expected_type) {
1799 NumberLiteralNode *codegen_num_lit = &node->codegen_node->data.num_lit_node;1795 NumLitCodeGen *codegen_num_lit = get_resolved_num_lit(node);
1800 assert(!codegen_num_lit->resolved_type);1796 assert(!codegen_num_lit->resolved_type);
1801 TypeTableEntry *after_implicit_cast_resolved_type =1797 TypeTableEntry *after_implicit_cast_resolved_type =
1802 resolve_type_compatibility(g, block_context, node, expected_type, num_lit_type);1798 resolve_type_compatibility(g, block_context, node, expected_type, num_lit_type);
...@@ -1837,10 +1833,9 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp...@@ -1837,10 +1833,9 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp
1837 return g->builtin_types.entry_invalid;1833 return g->builtin_types.entry_invalid;
1838 }1834 }
18391835
1840 assert(node->codegen_node);1836 node->data.struct_val_expr.codegen.type_entry = type_entry;
1841 node->codegen_node->data.struct_val_expr_node.type_entry = type_entry;1837 node->data.struct_val_expr.codegen.source_node = node;
1842 node->codegen_node->data.struct_val_expr_node.source_node = node;1838 context->struct_val_expr_alloca_list.append(&node->data.struct_val_expr.codegen);
1843 context->struct_val_expr_alloca_list.append(&node->codegen_node->data.struct_val_expr_node);
18441839
1845 int expr_field_count = struct_val_expr->fields.length;1840 int expr_field_count = struct_val_expr->fields.length;
1846 int actual_field_count = type_entry->data.structure.field_count;1841 int actual_field_count = type_entry->data.structure.field_count;
...@@ -1848,6 +1843,8 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp...@@ -1848,6 +1843,8 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp
1848 int *field_use_counts = allocate<int>(actual_field_count);1843 int *field_use_counts = allocate<int>(actual_field_count);
1849 for (int i = 0; i < expr_field_count; i += 1) {1844 for (int i = 0; i < expr_field_count; i += 1) {
1850 AstNode *val_field_node = struct_val_expr->fields.at(i);1845 AstNode *val_field_node = struct_val_expr->fields.at(i);
1846 assert(val_field_node->type == NodeTypeStructValueField);
1847
1851 int field_index;1848 int field_index;
1852 TypeStructField *type_field = find_struct_type_field(type_entry,1849 TypeStructField *type_field = find_struct_type_field(type_entry,
1853 &val_field_node->data.struct_val_field.name, &field_index);1850 &val_field_node->data.struct_val_field.name, &field_index);
...@@ -1865,8 +1862,7 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp...@@ -1865,8 +1862,7 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp
1865 continue;1862 continue;
1866 }1863 }
18671864
1868 alloc_codegen_node(val_field_node);1865 val_field_node->data.struct_val_field.index = field_index;
1869 val_field_node->codegen_node->data.struct_val_field_node.index = field_index;
18701866
1871 analyze_expression(g, import, context, type_field->type_entry,1867 analyze_expression(g, import, context, type_field->type_entry,
1872 val_field_node->data.struct_val_field.expr);1868 val_field_node->data.struct_val_field.expr);
...@@ -1885,6 +1881,8 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp...@@ -1885,6 +1881,8 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp
1885static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,1881static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
1886 TypeTableEntry *expected_type, AstNode *node)1882 TypeTableEntry *expected_type, AstNode *node)
1887{1883{
1884 assert(node->type == NodeTypeWhileExpr);
1885
1888 AstNode *condition_node = node->data.while_expr.condition;1886 AstNode *condition_node = node->data.while_expr.condition;
1889 AstNode *while_body_node = node->data.while_expr.body;1887 AstNode *while_body_node = node->data.while_expr.body;
1890 TypeTableEntry *condition_type = analyze_expression(g, import, context,1888 TypeTableEntry *condition_type = analyze_expression(g, import, context,
...@@ -1907,8 +1905,8 @@ static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import,...@@ -1907,8 +1905,8 @@ static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import,
1907 assert(resolved_type->id == TypeTableEntryIdBool);1905 assert(resolved_type->id == TypeTableEntryIdBool);
1908 bool constant_cond_value = number_literal.data.x_uint;1906 bool constant_cond_value = number_literal.data.x_uint;
1909 if (constant_cond_value) {1907 if (constant_cond_value) {
1910 node->codegen_node->data.while_node.condition_always_true = true;1908 node->data.while_expr.condition_always_true = true;
1911 if (!node->codegen_node->data.while_node.contains_break) {1909 if (!node->data.while_expr.contains_break) {
1912 expr_return_type = g->builtin_types.entry_unreachable;1910 expr_return_type = g->builtin_types.entry_unreachable;
1913 }1911 }
1914 }1912 }
...@@ -1921,12 +1919,14 @@ static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import,...@@ -1921,12 +1919,14 @@ static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import,
1921static TypeTableEntry *analyze_break_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,1919static TypeTableEntry *analyze_break_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
1922 TypeTableEntry *expected_type, AstNode *node)1920 TypeTableEntry *expected_type, AstNode *node)
1923{1921{
1922 assert(node->type == NodeTypeBreak);
1923
1924 AstNode *loop_node = context->parent_loop_node;1924 AstNode *loop_node = context->parent_loop_node;
1925 if (loop_node) {1925 if (loop_node) {
1926 loop_node->codegen_node->data.while_node.contains_break = true;1926 assert(loop_node->type == NodeTypeWhileExpr);
1927 loop_node->data.while_expr.contains_break = true;
1927 } else {1928 } else {
1928 add_node_error(g, node,1929 add_node_error(g, node, buf_sprintf("'break' expression outside loop"));
1929 buf_sprintf("'break' expression outside loop"));
1930 }1930 }
1931 return g->builtin_types.entry_unreachable;1931 return g->builtin_types.entry_unreachable;
1932}1932}
...@@ -1935,8 +1935,7 @@ static TypeTableEntry *analyze_continue_expr(CodeGen *g, ImportTableEntry *impor...@@ -1935,8 +1935,7 @@ static TypeTableEntry *analyze_continue_expr(CodeGen *g, ImportTableEntry *impor
1935 TypeTableEntry *expected_type, AstNode *node)1935 TypeTableEntry *expected_type, AstNode *node)
1936{1936{
1937 if (!context->parent_loop_node) {1937 if (!context->parent_loop_node) {
1938 add_node_error(g, node,1938 add_node_error(g, node, buf_sprintf("'continue' expression outside loop"));
1939 buf_sprintf("'continue' expression outside loop"));
1940 }1939 }
1941 return g->builtin_types.entry_unreachable;1940 return g->builtin_types.entry_unreachable;
1942}1941}
...@@ -1981,7 +1980,7 @@ static TypeTableEntry *analyze_if_var_expr(CodeGen *g, ImportTableEntry *import,...@@ -1981,7 +1980,7 @@ static TypeTableEntry *analyze_if_var_expr(CodeGen *g, ImportTableEntry *import,
1981 assert(node->type == NodeTypeIfVarExpr);1980 assert(node->type == NodeTypeIfVarExpr);
19821981
1983 BlockContext *child_context = new_block_context(node, context);1982 BlockContext *child_context = new_block_context(node, context);
1984 node->codegen_node->data.if_var_node.block_context = child_context;1983 node->data.if_var_expr.block_context = child_context;
19851984
1986 analyze_variable_declaration_raw(g, import, child_context, node, &node->data.if_var_expr.var_decl, true);1985 analyze_variable_declaration_raw(g, import, child_context, node, &node->data.if_var_expr.var_decl, true);
19871986
...@@ -2032,8 +2031,10 @@ static TypeTableEntry *analyze_compiler_fn_type(CodeGen *g, ImportTableEntry *im...@@ -2032,8 +2031,10 @@ static TypeTableEntry *analyze_compiler_fn_type(CodeGen *g, ImportTableEntry *im
2032static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,2031static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
2033 TypeTableEntry *expected_type, AstNode *node)2032 TypeTableEntry *expected_type, AstNode *node)
2034{2033{
2034 assert(node->type == NodeTypeFnCallExpr);
2035
2035 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;2036 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
2036 Buf *name = &fn_ref_expr->data.symbol;2037 Buf *name = &fn_ref_expr->data.symbol_expr.symbol;
20372038
2038 auto entry = g->builtin_fn_table.maybe_get(name);2039 auto entry = g->builtin_fn_table.maybe_get(name);
20392040
...@@ -2041,8 +2042,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -2041,8 +2042,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
2041 BuiltinFnEntry *builtin_fn = entry->value;2042 BuiltinFnEntry *builtin_fn = entry->value;
2042 int actual_param_count = node->data.fn_call_expr.params.length;2043 int actual_param_count = node->data.fn_call_expr.params.length;
20432044
2044 assert(node->codegen_node);2045 node->data.fn_call_expr.builtin_fn = builtin_fn;
2045 node->codegen_node->data.fn_call_node.builtin_fn = builtin_fn;
20462046
2047 if (builtin_fn->param_count != actual_param_count) {2047 if (builtin_fn->param_count != actual_param_count) {
2048 add_node_error(g, node,2048 add_node_error(g, node,
...@@ -2155,7 +2155,7 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import...@@ -2155,7 +2155,7 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
2155 if (node->data.fn_call_expr.is_builtin) {2155 if (node->data.fn_call_expr.is_builtin) {
2156 return analyze_builtin_fn_call_expr(g, import, context, expected_type, node);2156 return analyze_builtin_fn_call_expr(g, import, context, expected_type, node);
2157 }2157 }
2158 name = &fn_ref_expr->data.symbol;2158 name = &fn_ref_expr->data.symbol_expr.symbol;
2159 } else {2159 } else {
2160 add_node_error(g, node,2160 add_node_error(g, node,
2161 buf_sprintf("function pointers not yet supported"));2161 buf_sprintf("function pointers not yet supported"));
...@@ -2210,13 +2210,15 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import...@@ -2210,13 +2210,15 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
2210 AstNode *param_decl_node = fn_proto->params.at(fn_proto_i);2210 AstNode *param_decl_node = fn_proto->params.at(fn_proto_i);
2211 assert(param_decl_node->type == NodeTypeParamDecl);2211 assert(param_decl_node->type == NodeTypeParamDecl);
2212 AstNode *param_type_node = param_decl_node->data.param_decl.type;2212 AstNode *param_type_node = param_decl_node->data.param_decl.type;
2213 if (param_type_node->codegen_node)2213 assert(param_type_node->type == NodeTypeType);
2214 expected_param_type = param_type_node->codegen_node->data.type_node.entry;2214 if (param_type_node->data.type.entry) {
2215 expected_param_type = param_type_node->data.type.entry;
2216 }
2215 }2217 }
2216 analyze_expression(g, import, context, expected_param_type, child);2218 analyze_expression(g, import, context, expected_param_type, child);
2217 }2219 }
22182220
2219 return fn_proto->return_type->codegen_node->data.type_node.entry;2221 return fn_proto->return_type->data.type.entry;
2220 }2222 }
2221}2223}
22222224
...@@ -2224,18 +2226,17 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -2224,18 +2226,17 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
2224 TypeTableEntry *expected_type, AstNode *node)2226 TypeTableEntry *expected_type, AstNode *node)
2225{2227{
2226 TypeTableEntry *return_type = nullptr;2228 TypeTableEntry *return_type = nullptr;
2227 alloc_codegen_node(node);
2228 switch (node->type) {2229 switch (node->type) {
2229 case NodeTypeBlock:2230 case NodeTypeBlock:
2230 {2231 {
2231 BlockContext *child_context = new_block_context(node, context);2232 BlockContext *child_context = new_block_context(node, context);
2232 node->codegen_node->data.block_node.block_context = child_context;2233 node->data.block.block_context = child_context;
2233 return_type = g->builtin_types.entry_void;2234 return_type = g->builtin_types.entry_void;
22342235
2235 for (int i = 0; i < node->data.block.statements.length; i += 1) {2236 for (int i = 0; i < node->data.block.statements.length; i += 1) {
2236 AstNode *child = node->data.block.statements.at(i);2237 AstNode *child = node->data.block.statements.at(i);
2237 if (child->type == NodeTypeLabel) {2238 if (child->type == NodeTypeLabel) {
2238 LabelTableEntry *label_entry = child->codegen_node->data.label_entry;2239 LabelTableEntry *label_entry = child->data.label.label_entry;
2239 assert(label_entry);2240 assert(label_entry);
2240 label_entry->entered_from_fallthrough = (return_type->id != TypeTableEntryIdUnreachable);2241 label_entry->entered_from_fallthrough = (return_type->id != TypeTableEntryIdUnreachable);
2241 return_type = g->builtin_types.entry_void;2242 return_type = g->builtin_types.entry_void;
...@@ -2288,13 +2289,13 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -2288,13 +2289,13 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
2288 case NodeTypeGoto:2289 case NodeTypeGoto:
2289 {2290 {
2290 FnTableEntry *fn_table_entry = get_context_fn_entry(context);2291 FnTableEntry *fn_table_entry = get_context_fn_entry(context);
2291 auto table_entry = fn_table_entry->label_table.maybe_get(&node->data.go_to.name);2292 auto table_entry = fn_table_entry->label_table.maybe_get(&node->data.goto_expr.name);
2292 if (table_entry) {2293 if (table_entry) {
2293 node->codegen_node->data.label_entry = table_entry->value;2294 node->data.goto_expr.label_entry = table_entry->value;
2294 table_entry->value->used = true;2295 table_entry->value->used = true;
2295 } else {2296 } else {
2296 add_node_error(g, node,2297 add_node_error(g, node,
2297 buf_sprintf("use of undeclared label '%s'", buf_ptr(&node->data.go_to.name)));2298 buf_sprintf("use of undeclared label '%s'", buf_ptr(&node->data.goto_expr.name)));
2298 }2299 }
2299 return_type = g->builtin_types.entry_unreachable;2300 return_type = g->builtin_types.entry_unreachable;
2300 break;2301 break;
...@@ -2380,7 +2381,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -2380,7 +2381,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
23802381
2381 case NodeTypeSymbol:2382 case NodeTypeSymbol:
2382 {2383 {
2383 return_type = analyze_variable_name(g, import, context, node, &node->data.symbol);2384 return_type = analyze_variable_name(g, import, context, node, &node->data.symbol_expr.symbol);
2384 break;2385 break;
2385 }2386 }
2386 case NodeTypeCastExpr:2387 case NodeTypeCastExpr:
...@@ -2507,8 +2508,8 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,...@@ -2507,8 +2508,8 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
2507 assert(return_type);2508 assert(return_type);
2508 resolve_type_compatibility(g, context, node, expected_type, return_type);2509 resolve_type_compatibility(g, context, node, expected_type, return_type);
25092510
2510 node->codegen_node->expr_node.type_entry = return_type;2511 get_resolved_expr(node)->type_entry = return_type;
2511 node->codegen_node->expr_node.block_context = context;2512 get_resolved_expr(node)->block_context = context;
25122513
2513 return return_type;2514 return return_type;
2514}2515}
...@@ -2519,15 +2520,14 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo...@@ -2519,15 +2520,14 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo
2519 AstNode *fn_proto_node = node->data.fn_def.fn_proto;2520 AstNode *fn_proto_node = node->data.fn_def.fn_proto;
2520 assert(fn_proto_node->type == NodeTypeFnProto);2521 assert(fn_proto_node->type == NodeTypeFnProto);
25212522
2522 if (fn_proto_node->codegen_node->data.fn_proto_node.skip) {2523 if (fn_proto_node->data.fn_proto.skip) {
2523 // we detected an error with this function definition which prevents us2524 // we detected an error with this function definition which prevents us
2524 // from further analyzing it.2525 // from further analyzing it.
2525 return;2526 return;
2526 }2527 }
25272528
2528 alloc_codegen_node(node);
2529 BlockContext *context = new_block_context(node, import->block_context);2529 BlockContext *context = new_block_context(node, import->block_context);
2530 node->codegen_node->data.fn_def_node.block_context = context;2530 node->data.fn_def.block_context = context;
25312531
2532 AstNodeFnProto *fn_proto = &fn_proto_node->data.fn_proto;2532 AstNodeFnProto *fn_proto = &fn_proto_node->data.fn_proto;
2533 bool is_exported = (fn_proto->visib_mod == VisibModExport);2533 bool is_exported = (fn_proto->visib_mod == VisibModExport);
...@@ -2538,7 +2538,7 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo...@@ -2538,7 +2538,7 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo
2538 // define local variables for parameters2538 // define local variables for parameters
2539 AstNodeParamDecl *param_decl = &param_decl_node->data.param_decl;2539 AstNodeParamDecl *param_decl = &param_decl_node->data.param_decl;
2540 assert(param_decl->type->type == NodeTypeType);2540 assert(param_decl->type->type == NodeTypeType);
2541 TypeTableEntry *type = param_decl->type->codegen_node->data.type_node.entry;2541 TypeTableEntry *type = param_decl->type->data.type.entry;
25422542
2543 if (is_exported && type->id == TypeTableEntryIdStruct) {2543 if (is_exported && type->id == TypeTableEntryIdStruct) {
2544 add_node_error(g, param_decl_node,2544 add_node_error(g, param_decl_node,
...@@ -2552,8 +2552,7 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo...@@ -2552,8 +2552,7 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo
2552 variable_entry->decl_node = param_decl_node;2552 variable_entry->decl_node = param_decl_node;
2553 variable_entry->arg_index = i;2553 variable_entry->arg_index = i;
25542554
2555 alloc_codegen_node(param_decl_node);2555 param_decl_node->data.param_decl.variable = variable_entry;
2556 param_decl_node->codegen_node->data.param_decl_node.variable = variable_entry;
25572556
2558 VariableTableEntry *existing_entry = find_local_variable(context, &variable_entry->name);2557 VariableTableEntry *existing_entry = find_local_variable(context, &variable_entry->name);
2559 if (!existing_entry) {2558 if (!existing_entry) {
...@@ -2571,13 +2570,13 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo...@@ -2571,13 +2570,13 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo
2571 }2570 }
2572 }2571 }
25732572
2574 TypeTableEntry *expected_type = fn_proto->return_type->codegen_node->data.type_node.entry;2573 TypeTableEntry *expected_type = fn_proto->return_type->data.type.entry;
2575 TypeTableEntry *block_return_type = analyze_expression(g, import, context, expected_type, node->data.fn_def.body);2574 TypeTableEntry *block_return_type = analyze_expression(g, import, context, expected_type, node->data.fn_def.body);
25762575
2577 node->codegen_node->data.fn_def_node.implicit_return_type = block_return_type;2576 node->data.fn_def.implicit_return_type = block_return_type;
25782577
2579 {2578 {
2580 FnTableEntry *fn_table_entry = fn_proto_node->codegen_node->data.fn_proto_node.fn_table_entry;2579 FnTableEntry *fn_table_entry = fn_proto_node->data.fn_proto.fn_table_entry;
2581 auto it = fn_table_entry->label_table.entry_iterator();2580 auto it = fn_table_entry->label_table.entry_iterator();
2582 for (;;) {2581 for (;;) {
2583 auto *entry = it.next();2582 auto *entry = it.next();
...@@ -2656,7 +2655,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode...@@ -2656,7 +2655,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
2656}2655}
26572656
2658static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *expr_node,2657static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *expr_node,
2659 DeclNode *decl_node)2658 TopLevelDecl *decl_node)
2660{2659{
2661 switch (expr_node->type) {2660 switch (expr_node->type) {
2662 case NodeTypeNumberLiteral:2661 case NodeTypeNumberLiteral:
...@@ -2672,7 +2671,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode...@@ -2672,7 +2671,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
2672 // no dependencies on other top level declarations2671 // no dependencies on other top level declarations
2673 break;2672 break;
2674 case NodeTypeSymbol:2673 case NodeTypeSymbol:
2675 decl_node->deps.put(&expr_node->data.symbol, expr_node);2674 decl_node->deps.put(&expr_node->data.symbol_expr.symbol, expr_node);
2676 break;2675 break;
2677 case NodeTypeBinOpExpr:2676 case NodeTypeBinOpExpr:
2678 collect_expr_decl_deps(g, import, expr_node->data.bin_op_expr.op1, decl_node);2677 collect_expr_decl_deps(g, import, expr_node->data.bin_op_expr.op1, decl_node);
...@@ -2787,7 +2786,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode...@@ -2787,7 +2786,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
2787 }2786 }
2788}2787}
27892788
2790static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *type_node, DeclNode *decl_node) {2789static void collect_type_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *type_node, TopLevelDecl *decl_node) {
2791 assert(type_node->type == NodeTypeType);2790 assert(type_node->type == NodeTypeType);
2792 switch (type_node->data.type.type) {2791 switch (type_node->data.type.type) {
2793 case AstNodeTypeTypePrimitive:2792 case AstNodeTypeTypePrimitive:
...@@ -2824,16 +2823,13 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -2824,16 +2823,13 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
2824 switch (node->type) {2823 switch (node->type) {
2825 case NodeTypeStructDecl:2824 case NodeTypeStructDecl:
2826 {2825 {
2827 alloc_codegen_node(node);
2828 StructDeclNode *struct_codegen = &node->codegen_node->data.struct_decl_node;
2829
2830 Buf *name = &node->data.struct_decl.name;2826 Buf *name = &node->data.struct_decl.name;
2831 auto table_entry = g->primitive_type_table.maybe_get(name);2827 auto table_entry = g->primitive_type_table.maybe_get(name);
2832 if (!table_entry) {2828 if (!table_entry) {
2833 table_entry = import->type_table.maybe_get(name);2829 table_entry = import->type_table.maybe_get(name);
2834 }2830 }
2835 if (table_entry) {2831 if (table_entry) {
2836 struct_codegen->type_entry = table_entry->value;2832 node->data.struct_decl.type_entry = table_entry->value;
2837 add_node_error(g, node,2833 add_node_error(g, node,
2838 buf_sprintf("redefinition of '%s'", buf_ptr(name)));2834 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
2839 } else {2835 } else {
...@@ -2848,7 +2844,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -2848,7 +2844,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
2848 // put off adding the debug type until we do the full struct body2844 // put off adding the debug type until we do the full struct body
2849 // this type is incomplete until we do another pass2845 // this type is incomplete until we do another pass
2850 import->type_table.put(&entry->name, entry);2846 import->type_table.put(&entry->name, entry);
2851 struct_codegen->type_entry = entry;2847 node->data.struct_decl.type_entry = entry;
28522848
2853 bool is_pub = (node->data.struct_decl.visib_mod != VisibModPrivate);2849 bool is_pub = (node->data.struct_decl.visib_mod != VisibModPrivate);
2854 if (is_pub) {2850 if (is_pub) {
...@@ -2867,14 +2863,15 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -2867,14 +2863,15 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
2867 }2863 }
28682864
2869 // determine which other top level declarations this struct depends on.2865 // determine which other top level declarations this struct depends on.
2870 DeclNode *decl_node = &node->codegen_node->decl_node;2866 TopLevelDecl *decl_node = &node->data.struct_decl.top_level_decl;
2867 decl_node->deps.init(1);
2871 for (int i = 0; i < node->data.struct_decl.fields.length; i += 1) {2868 for (int i = 0; i < node->data.struct_decl.fields.length; i += 1) {
2872 AstNode *field_node = node->data.struct_decl.fields.at(i);2869 AstNode *field_node = node->data.struct_decl.fields.at(i);
2873 AstNode *type_node = field_node->data.struct_field.type;2870 AstNode *type_node = field_node->data.struct_field.type;
2874 collect_type_decl_deps(g, import, type_node, decl_node);2871 collect_type_decl_deps(g, import, type_node, decl_node);
2875 }2872 }
2876 node->codegen_node->decl_node.name = name;2873 decl_node->name = name;
2877 node->codegen_node->decl_node.import = import;2874 decl_node->import = import;
2878 if (decl_node->deps.size() > 0) {2875 if (decl_node->deps.size() > 0) {
2879 g->unresolved_top_level_decls.put(name, node);2876 g->unresolved_top_level_decls.put(name, node);
2880 } else {2877 } else {
...@@ -2913,8 +2910,8 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -2913,8 +2910,8 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
2913 case NodeTypeVariableDeclaration:2910 case NodeTypeVariableDeclaration:
2914 {2911 {
2915 // determine which other top level declarations this variable declaration depends on.2912 // determine which other top level declarations this variable declaration depends on.
2916 alloc_codegen_node(node);2913 TopLevelDecl *decl_node = &node->data.variable_declaration.top_level_decl;
2917 DeclNode *decl_node = &node->codegen_node->decl_node;2914 decl_node->deps.init(1);
2918 if (node->data.variable_declaration.type) {2915 if (node->data.variable_declaration.type) {
2919 collect_type_decl_deps(g, import, node->data.variable_declaration.type, decl_node);2916 collect_type_decl_deps(g, import, node->data.variable_declaration.type, decl_node);
2920 }2917 }
...@@ -2922,8 +2919,8 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -2922,8 +2919,8 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
2922 collect_expr_decl_deps(g, import, node->data.variable_declaration.expr, decl_node);2919 collect_expr_decl_deps(g, import, node->data.variable_declaration.expr, decl_node);
2923 }2920 }
2924 Buf *name = &node->data.variable_declaration.symbol;2921 Buf *name = &node->data.variable_declaration.symbol;
2925 node->codegen_node->decl_node.name = name;2922 decl_node->name = name;
2926 node->codegen_node->decl_node.import = import;2923 decl_node->import = import;
2927 if (decl_node->deps.size() > 0) {2924 if (decl_node->deps.size() > 0) {
2928 g->unresolved_top_level_decls.put(name, node);2925 g->unresolved_top_level_decls.put(name, node);
2929 } else {2926 } else {
...@@ -2934,8 +2931,8 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -2934,8 +2931,8 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
2934 case NodeTypeFnProto:2931 case NodeTypeFnProto:
2935 {2932 {
2936 // determine which other top level declarations this function prototype depends on.2933 // determine which other top level declarations this function prototype depends on.
2937 alloc_codegen_node(node);2934 TopLevelDecl *decl_node = &node->data.fn_proto.top_level_decl;
2938 DeclNode *decl_node = &node->codegen_node->decl_node;2935 decl_node->deps.init(1);
2939 for (int i = 0; i < node->data.fn_proto.params.length; i += 1) {2936 for (int i = 0; i < node->data.fn_proto.params.length; i += 1) {
2940 AstNode *param_node = node->data.fn_proto.params.at(i);2937 AstNode *param_node = node->data.fn_proto.params.at(i);
2941 assert(param_node->type == NodeTypeParamDecl);2938 assert(param_node->type == NodeTypeParamDecl);
...@@ -2943,8 +2940,8 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -2943,8 +2940,8 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
2943 }2940 }
29442941
2945 Buf *name = &node->data.fn_proto.name;2942 Buf *name = &node->data.fn_proto.name;
2946 node->codegen_node->decl_node.name = name;2943 decl_node->name = name;
2947 node->codegen_node->decl_node.import = import;2944 decl_node->import = import;
2948 if (decl_node->deps.size() > 0) {2945 if (decl_node->deps.size() > 0) {
2949 g->unresolved_top_level_decls.put(name, node);2946 g->unresolved_top_level_decls.put(name, node);
2950 } else {2947 } else {
...@@ -2999,7 +2996,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast...@@ -2999,7 +2996,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
2999}2996}
30002997
3001static void recursive_resolve_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {2998static void recursive_resolve_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
3002 auto it = node->codegen_node->decl_node.deps.entry_iterator();2999 auto it = get_resolved_top_level_decl(node)->deps.entry_iterator();
3003 for (;;) {3000 for (;;) {
3004 auto *entry = it.next();3001 auto *entry = it.next();
3005 if (!entry)3002 if (!entry)
...@@ -3012,23 +3009,24 @@ static void recursive_resolve_decl(CodeGen *g, ImportTableEntry *import, AstNode...@@ -3012,23 +3009,24 @@ static void recursive_resolve_decl(CodeGen *g, ImportTableEntry *import, AstNode
30123009
3013 AstNode *child_node = unresolved_entry->value;3010 AstNode *child_node = unresolved_entry->value;
30143011
3015 if (child_node->codegen_node->decl_node.in_current_deps) {3012 if (get_resolved_top_level_decl(child_node)->in_current_deps) {
3016 // dependency loop. we'll let the fact that it's not in the respective3013 // dependency loop. we'll let the fact that it's not in the respective
3017 // table cause an error in resolve_top_level_decl.3014 // table cause an error in resolve_top_level_decl.
3018 continue;3015 continue;
3019 }3016 }
30203017
3021 // set temporary flag3018 // set temporary flag
3022 child_node->codegen_node->decl_node.in_current_deps = true;3019 TopLevelDecl *top_level_decl = get_resolved_top_level_decl(child_node);
3020 top_level_decl->in_current_deps = true;
30233021
3024 recursive_resolve_decl(g, child_node->codegen_node->decl_node.import, child_node);3022 recursive_resolve_decl(g, top_level_decl->import, child_node);
30253023
3026 // unset temporary flag3024 // unset temporary flag
3027 child_node->codegen_node->decl_node.in_current_deps = false;3025 top_level_decl->in_current_deps = false;
3028 }3026 }
30293027
3030 resolve_top_level_decl(g, import, node);3028 resolve_top_level_decl(g, import, node);
3031 g->unresolved_top_level_decls.remove(node->codegen_node->decl_node.name);3029 g->unresolved_top_level_decls.remove(get_resolved_top_level_decl(node)->name);
3032}3030}
30333031
3034static void resolve_top_level_declarations_root(CodeGen *g, ImportTableEntry *import, AstNode *node) {3032static void resolve_top_level_declarations_root(CodeGen *g, ImportTableEntry *import, AstNode *node) {
...@@ -3051,12 +3049,13 @@ static void resolve_top_level_declarations_root(CodeGen *g, ImportTableEntry *im...@@ -3051,12 +3049,13 @@ static void resolve_top_level_declarations_root(CodeGen *g, ImportTableEntry *im
30513049
3052 }3050 }
3053 // set temporary flag3051 // set temporary flag
3054 decl_node->codegen_node->decl_node.in_current_deps = true;3052 TopLevelDecl *top_level_decl = get_resolved_top_level_decl(decl_node);
3053 top_level_decl->in_current_deps = true;
30553054
3056 recursive_resolve_decl(g, decl_node->codegen_node->decl_node.import, decl_node);3055 recursive_resolve_decl(g, top_level_decl->import, decl_node);
30573056
3058 // unset temporary flag3057 // unset temporary flag
3059 decl_node->codegen_node->decl_node.in_current_deps = false;3058 top_level_decl->in_current_deps = false;
3060 }3059 }
3061}3060}
30623061
...@@ -3089,7 +3088,7 @@ void semantic_analyze(CodeGen *g) {...@@ -3089,7 +3088,7 @@ void semantic_analyze(CodeGen *g) {
3089 buf_sprintf("invalid directive: '%s'", buf_ptr(name)));3088 buf_sprintf("invalid directive: '%s'", buf_ptr(name)));
3090 }3089 }
30913090
3092 ImportTableEntry *target_import = child->codegen_node->data.import_node.import;3091 ImportTableEntry *target_import = child->data.use.import;
3093 assert(target_import);3092 assert(target_import);
30943093
3095 target_import->importers.append({import, child});3094 target_import->importers.append({import, child});
...@@ -3144,9 +3143,186 @@ void semantic_analyze(CodeGen *g) {...@@ -3144,9 +3143,186 @@ void semantic_analyze(CodeGen *g) {
3144 }3143 }
3145}3144}
31463145
3147void alloc_codegen_node(AstNode *node) {3146Expr *get_resolved_expr(AstNode *node) {
3148 assert(!node->codegen_node);3147 switch (node->type) {
3149 node->codegen_node = allocate<CodeGenNode>(1);3148 case NodeTypeReturnExpr:
3150 node->codegen_node->decl_node.deps.init(1);3149 return &node->data.return_expr.resolved_expr;
3150 case NodeTypeBinOpExpr:
3151 return &node->data.bin_op_expr.resolved_expr;
3152 case NodeTypeCastExpr:
3153 return &node->data.cast_expr.resolved_expr;
3154 case NodeTypePrefixOpExpr:
3155 return &node->data.prefix_op_expr.resolved_expr;
3156 case NodeTypeFnCallExpr:
3157 return &node->data.fn_call_expr.resolved_expr;
3158 case NodeTypeArrayAccessExpr:
3159 return &node->data.array_access_expr.resolved_expr;
3160 case NodeTypeSliceExpr:
3161 return &node->data.slice_expr.resolved_expr;
3162 case NodeTypeFieldAccessExpr:
3163 return &node->data.field_access_expr.resolved_expr;
3164 case NodeTypeIfBoolExpr:
3165 return &node->data.if_bool_expr.resolved_expr;
3166 case NodeTypeIfVarExpr:
3167 return &node->data.if_var_expr.resolved_expr;
3168 case NodeTypeWhileExpr:
3169 return &node->data.while_expr.resolved_expr;
3170 case NodeTypeAsmExpr:
3171 return &node->data.asm_expr.resolved_expr;
3172 case NodeTypeStructValueExpr:
3173 return &node->data.struct_val_expr.resolved_expr;
3174 case NodeTypeNumberLiteral:
3175 return &node->data.number_literal.resolved_expr;
3176 case NodeTypeStringLiteral:
3177 return &node->data.string_literal.resolved_expr;
3178 case NodeTypeBlock:
3179 return &node->data.block.resolved_expr;
3180 case NodeTypeVoid:
3181 return &node->data.void_expr.resolved_expr;
3182 case NodeTypeUnreachable:
3183 return &node->data.unreachable_expr.resolved_expr;
3184 case NodeTypeSymbol:
3185 return &node->data.symbol_expr.resolved_expr;
3186 case NodeTypeVariableDeclaration:
3187 return &node->data.variable_declaration.resolved_expr;
3188 case NodeTypeCharLiteral:
3189 return &node->data.char_literal.resolved_expr;
3190 case NodeTypeBoolLiteral:
3191 return &node->data.bool_literal.resolved_expr;
3192 case NodeTypeNullLiteral:
3193 return &node->data.null_literal.resolved_expr;
3194 case NodeTypeGoto:
3195 return &node->data.goto_expr.resolved_expr;
3196 case NodeTypeBreak:
3197 return &node->data.break_expr.resolved_expr;
3198 case NodeTypeContinue:
3199 return &node->data.continue_expr.resolved_expr;
3200 case NodeTypeCompilerFnExpr:
3201 return &node->data.compiler_fn_expr.resolved_expr;
3202 case NodeTypeCompilerFnType:
3203 return &node->data.compiler_fn_type.resolved_expr;
3204 case NodeTypeLabel:
3205 return &node->data.label.resolved_expr;
3206 case NodeTypeRoot:
3207 case NodeTypeRootExportDecl:
3208 case NodeTypeFnProto:
3209 case NodeTypeFnDef:
3210 case NodeTypeFnDecl:
3211 case NodeTypeParamDecl:
3212 case NodeTypeType:
3213 case NodeTypeExternBlock:
3214 case NodeTypeDirective:
3215 case NodeTypeUse:
3216 case NodeTypeStructDecl:
3217 case NodeTypeStructField:
3218 case NodeTypeStructValueField:
3219 case NodeTypeEnumDecl:
3220 case NodeTypeEnumField:
3221 zig_unreachable();
3222 }
3223}
3224
3225NumLitCodeGen *get_resolved_num_lit(AstNode *node) {
3226 switch (node->type) {
3227 case NodeTypeNumberLiteral:
3228 return &node->data.number_literal.codegen;
3229 case NodeTypeCompilerFnType:
3230 return &node->data.compiler_fn_type.resolved_num_lit;
3231 case NodeTypeReturnExpr:
3232 case NodeTypeBinOpExpr:
3233 case NodeTypeCastExpr:
3234 case NodeTypePrefixOpExpr:
3235 case NodeTypeFnCallExpr:
3236 case NodeTypeArrayAccessExpr:
3237 case NodeTypeSliceExpr:
3238 case NodeTypeFieldAccessExpr:
3239 case NodeTypeIfBoolExpr:
3240 case NodeTypeIfVarExpr:
3241 case NodeTypeWhileExpr:
3242 case NodeTypeAsmExpr:
3243 case NodeTypeStructValueExpr:
3244 case NodeTypeRoot:
3245 case NodeTypeRootExportDecl:
3246 case NodeTypeFnProto:
3247 case NodeTypeFnDef:
3248 case NodeTypeFnDecl:
3249 case NodeTypeParamDecl:
3250 case NodeTypeType:
3251 case NodeTypeBlock:
3252 case NodeTypeExternBlock:
3253 case NodeTypeDirective:
3254 case NodeTypeVariableDeclaration:
3255 case NodeTypeStringLiteral:
3256 case NodeTypeCharLiteral:
3257 case NodeTypeUnreachable:
3258 case NodeTypeSymbol:
3259 case NodeTypeUse:
3260 case NodeTypeVoid:
3261 case NodeTypeBoolLiteral:
3262 case NodeTypeNullLiteral:
3263 case NodeTypeLabel:
3264 case NodeTypeGoto:
3265 case NodeTypeBreak:
3266 case NodeTypeContinue:
3267 case NodeTypeStructDecl:
3268 case NodeTypeStructField:
3269 case NodeTypeStructValueField:
3270 case NodeTypeEnumDecl:
3271 case NodeTypeEnumField:
3272 case NodeTypeCompilerFnExpr:
3273 zig_unreachable();
3274 }
3151}3275}
31523276
3277TopLevelDecl *get_resolved_top_level_decl(AstNode *node) {
3278 switch (node->type) {
3279 case NodeTypeVariableDeclaration:
3280 return &node->data.variable_declaration.top_level_decl;
3281 case NodeTypeFnProto:
3282 return &node->data.fn_proto.top_level_decl;
3283 case NodeTypeStructDecl:
3284 return &node->data.struct_decl.top_level_decl;
3285 case NodeTypeNumberLiteral:
3286 case NodeTypeReturnExpr:
3287 case NodeTypeBinOpExpr:
3288 case NodeTypeCastExpr:
3289 case NodeTypePrefixOpExpr:
3290 case NodeTypeFnCallExpr:
3291 case NodeTypeArrayAccessExpr:
3292 case NodeTypeSliceExpr:
3293 case NodeTypeFieldAccessExpr:
3294 case NodeTypeIfBoolExpr:
3295 case NodeTypeIfVarExpr:
3296 case NodeTypeWhileExpr:
3297 case NodeTypeAsmExpr:
3298 case NodeTypeStructValueExpr:
3299 case NodeTypeRoot:
3300 case NodeTypeRootExportDecl:
3301 case NodeTypeFnDef:
3302 case NodeTypeFnDecl:
3303 case NodeTypeParamDecl:
3304 case NodeTypeType:
3305 case NodeTypeBlock:
3306 case NodeTypeExternBlock:
3307 case NodeTypeDirective:
3308 case NodeTypeStringLiteral:
3309 case NodeTypeCharLiteral:
3310 case NodeTypeUnreachable:
3311 case NodeTypeSymbol:
3312 case NodeTypeUse:
3313 case NodeTypeVoid:
3314 case NodeTypeBoolLiteral:
3315 case NodeTypeNullLiteral:
3316 case NodeTypeLabel:
3317 case NodeTypeGoto:
3318 case NodeTypeBreak:
3319 case NodeTypeContinue:
3320 case NodeTypeStructField:
3321 case NodeTypeStructValueField:
3322 case NodeTypeEnumDecl:
3323 case NodeTypeEnumField:
3324 case NodeTypeCompilerFnExpr:
3325 case NodeTypeCompilerFnType:
3326 zig_unreachable();
3327 }
3328}
src/analyze.hpp+4-402
...@@ -8,414 +8,16 @@...@@ -8,414 +8,16 @@
8#ifndef ZIG_ANALYZE_HPP8#ifndef ZIG_ANALYZE_HPP
9#define ZIG_ANALYZE_HPP9#define ZIG_ANALYZE_HPP
1010
11#include "codegen.hpp"11#include "all_types.hpp"
12#include "hash_map.hpp"
13#include "zig_llvm.hpp"
14#include "errmsg.hpp"
15
16struct FnTableEntry;
17struct BlockContext;
18struct TypeTableEntry;
19struct VariableTableEntry;
20struct CastNode;
21struct StructValExprNode;
22
23struct TypeTableEntryPointer {
24 TypeTableEntry *child_type;
25 bool is_const;
26 bool is_noalias;
27};
28
29struct TypeTableEntryInt {
30 bool is_signed;
31};
32
33struct TypeTableEntryArray {
34 TypeTableEntry *child_type;
35 uint64_t len;
36};
37
38struct TypeStructField {
39 Buf *name;
40 TypeTableEntry *type_entry;
41};
42
43struct TypeTableEntryStruct {
44 AstNode *decl_node;
45 bool is_packed;
46 int field_count;
47 TypeStructField *fields;
48 uint64_t size_bytes;
49 bool is_invalid; // true if any fields are invalid
50 bool is_unknown_size_array;
51 // reminder: hash tables must be initialized before use
52 HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table;
53
54 // set this flag temporarily to detect infinite loops
55 bool embedded_in_current;
56 bool reported_infinite_err;
57};
58
59struct TypeTableEntryNumLit {
60 NumLit kind;
61};
62
63struct TypeTableEntryMaybe {
64 TypeTableEntry *child_type;
65};
66
67enum TypeTableEntryId {
68 TypeTableEntryIdInvalid,
69 TypeTableEntryIdVoid,
70 TypeTableEntryIdBool,
71 TypeTableEntryIdUnreachable,
72 TypeTableEntryIdInt,
73 TypeTableEntryIdFloat,
74 TypeTableEntryIdPointer,
75 TypeTableEntryIdArray,
76 TypeTableEntryIdStruct,
77 TypeTableEntryIdNumberLiteral,
78 TypeTableEntryIdMaybe,
79};
80
81struct TypeTableEntry {
82 TypeTableEntryId id;
83
84 LLVMTypeRef type_ref;
85 LLVMZigDIType *di_type;
86 uint64_t size_in_bits;
87 uint64_t align_in_bits;
88
89 Buf name;
90
91 union {
92 TypeTableEntryPointer pointer;
93 TypeTableEntryInt integral;
94 TypeTableEntryArray array;
95 TypeTableEntryStruct structure;
96 TypeTableEntryNumLit num_lit;
97 TypeTableEntryMaybe maybe;
98 } data;
99
100 // use these fields to make sure we don't duplicate type table entries for the same type
101 TypeTableEntry *pointer_parent[2][2]; // 0 - const. 1 - noalias
102 TypeTableEntry *unknown_size_array_parent[2][2]; // 0 - const. 1 - noalias
103 HashMap<uint64_t, TypeTableEntry *, uint64_hash, uint64_eq> arrays_by_size;
104 TypeTableEntry *maybe_parent;
105
106};
107
108struct ImporterInfo {
109 ImportTableEntry *import;
110 AstNode *source_node;
111};
112
113struct ImportTableEntry {
114 AstNode *root;
115 Buf *path; // relative to root_source_dir
116 LLVMZigDIFile *di_file;
117 Buf *source_code;
118 ZigList<int> *line_offsets;
119 BlockContext *block_context;
120 ZigList<ImporterInfo> importers;
121
122 // reminder: hash tables must be initialized before use
123 HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table;
124 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> type_table;
125};
126
127struct LabelTableEntry {
128 AstNode *label_node;
129 LLVMBasicBlockRef basic_block;
130 bool used;
131 bool entered_from_fallthrough;
132};
133
134enum FnAttrId {
135 FnAttrIdNaked,
136 FnAttrIdAlwaysInline,
137};
138
139struct FnTableEntry {
140 LLVMValueRef fn_value;
141 AstNode *proto_node;
142 AstNode *fn_def_node;
143 bool is_extern;
144 bool internal_linkage;
145 unsigned calling_convention;
146 ImportTableEntry *import_entry;
147 ZigList<FnAttrId> fn_attr_list;
148 // Required to be a pre-order traversal of the AST. (parents must come before children)
149 ZigList<BlockContext *> all_block_contexts;
150 TypeTableEntry *member_of_struct;
151 Buf symbol_name;
152
153 // reminder: hash tables must be initialized before use
154 HashMap<Buf *, LabelTableEntry *, buf_hash, buf_eql_buf> label_table;
155};
156
157enum BuiltinFnId {
158 BuiltinFnIdInvalid,
159 BuiltinFnIdArithmeticWithOverflow,
160 BuiltinFnIdMemcpy,
161 BuiltinFnIdMemset,
162};
163
164struct BuiltinFnEntry {
165 BuiltinFnId id;
166 Buf name;
167 int param_count;
168 TypeTableEntry *return_type;
169 TypeTableEntry **param_types;
170 LLVMValueRef fn_val;
171};
172
173struct CodeGen {
174 LLVMModuleRef module;
175 ZigList<ErrorMsg*> errors;
176 LLVMBuilderRef builder;
177 LLVMZigDIBuilder *dbuilder;
178 LLVMZigDICompileUnit *compile_unit;
179
180 ZigList<Buf *> lib_search_paths;
181
182 // reminder: hash tables must be initialized before use
183 HashMap<Buf *, LLVMValueRef, buf_hash, buf_eql_buf> str_table;
184 HashMap<Buf *, bool, buf_hash, buf_eql_buf> link_table;
185 HashMap<Buf *, ImportTableEntry *, buf_hash, buf_eql_buf> import_table;
186 HashMap<Buf *, BuiltinFnEntry *, buf_hash, buf_eql_buf> builtin_fn_table;
187 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> primitive_type_table;
188 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> unresolved_top_level_decls;
189
190 uint32_t next_unresolved_index;
191
192 struct {
193 TypeTableEntry *entry_bool;
194 TypeTableEntry *entry_u8;
195 TypeTableEntry *entry_u16;
196 TypeTableEntry *entry_u32;
197 TypeTableEntry *entry_u64;
198 TypeTableEntry *entry_i8;
199 TypeTableEntry *entry_i16;
200 TypeTableEntry *entry_i32;
201 TypeTableEntry *entry_i64;
202 TypeTableEntry *entry_isize;
203 TypeTableEntry *entry_usize;
204 TypeTableEntry *entry_f32;
205 TypeTableEntry *entry_f64;
206 TypeTableEntry *entry_c_string_literal;
207 TypeTableEntry *entry_void;
208 TypeTableEntry *entry_unreachable;
209 TypeTableEntry *entry_invalid;
210 } builtin_types;
211
212 TypeTableEntry *num_lit_types[NumLitCount];
213
214 LLVMTargetDataRef target_data_ref;
215 unsigned pointer_size_bytes;
216 bool is_static;
217 bool strip_debug_symbols;
218 bool have_exported_main;
219 bool link_libc;
220 Buf *libc_path;
221 CodeGenBuildType build_type;
222 LLVMTargetMachineRef target_machine;
223 LLVMZigDIFile *dummy_di_file;
224 bool is_native_target;
225 Buf *root_source_dir;
226 Buf *root_out_name;
227
228 // The function definitions this module includes. There must be a corresponding
229 // fn_protos entry.
230 ZigList<FnTableEntry *> fn_defs;
231 // The function prototypes this module includes. In the case of external declarations,
232 // there will not be a corresponding fn_defs entry.
233 ZigList<FnTableEntry *> fn_protos;
234 ZigList<VariableTableEntry *> global_vars;
235
236 OutType out_type;
237 FnTableEntry *cur_fn;
238 BlockContext *cur_block_context;
239 ZigList<LLVMBasicBlockRef> break_block_stack;
240 ZigList<LLVMBasicBlockRef> continue_block_stack;
241 bool c_stdint_used;
242 AstNode *root_export_decl;
243 int version_major;
244 int version_minor;
245 int version_patch;
246 bool verbose;
247 ErrColor err_color;
248 ImportTableEntry *root_import;
249 ImportTableEntry *bootstrap_import;
250 LLVMValueRef memcpy_fn_val;
251 bool error_during_imports;
252};
253
254struct VariableTableEntry {
255 Buf name;
256 TypeTableEntry *type;
257 LLVMValueRef value_ref;
258 bool is_const;
259 bool is_ptr; // if true, value_ref is a pointer
260 AstNode *decl_node;
261 LLVMZigDILocalVariable *di_loc_var;
262 int arg_index;
263};
264
265struct BlockContext {
266 AstNode *node; // either NodeTypeFnDef or NodeTypeBlock or NodeTypeRoot
267 FnTableEntry *fn_entry; // null at the module scope
268 BlockContext *parent; // null when this is the root
269 HashMap<Buf *, VariableTableEntry *, buf_hash, buf_eql_buf> variable_table;
270 ZigList<CastNode *> cast_expr_alloca_list;
271 ZigList<StructValExprNode *> struct_val_expr_alloca_list;
272 AstNode *parent_loop_node;
273 AstNode *next_child_parent_loop_node;
274 LLVMZigDIScope *di_scope;
275};
276
277struct TypeNode {
278 TypeTableEntry *entry;
279};
280
281struct FnProtoNode {
282 FnTableEntry *fn_table_entry;
283 bool skip;
284};
285
286struct FnDefNode {
287 TypeTableEntry *implicit_return_type;
288 BlockContext *block_context;
289};
290
291
292struct AssignNode {
293 VariableTableEntry *var_entry;
294};
295
296struct BlockNode {
297 BlockContext *block_context;
298};
299
300struct StructDeclNode {
301 TypeTableEntry *type_entry;
302};
303
304struct FieldAccessNode {
305 int field_index;
306 TypeStructField *type_struct_field;
307};
308
309enum CastOp {
310 CastOpNothing,
311 CastOpPtrToInt,
312 CastOpIntWidenOrShorten,
313 CastOpToUnknownSizeArray,
314 CastOpMaybeWrap,
315 CastOpPointerReinterpret,
316};
317
318struct CastNode {
319 CastOp op;
320 // if op is CastOpArrayToString, this will be a pointer to
321 // the string struct on the stack
322 LLVMValueRef ptr;
323 TypeTableEntry *after_type;
324 AstNode *source_node;
325};
326
327struct ExprNode {
328 TypeTableEntry *type_entry;
329 // the context in which this expression is evaluated.
330 // for blocks, this points to the containing scope, not the block's own scope for its children.
331 BlockContext *block_context;
332
333 // may be null for no cast
334 CastNode implicit_cast; // happens first
335 CastNode implicit_maybe_cast; // happens second
336};
337
338struct NumberLiteralNode {
339 TypeTableEntry *resolved_type;
340};
341
342struct VarDeclNode {
343 TypeTableEntry *type;
344};
345
346struct StructValFieldNode {
347 int index;
348};
349
350struct StructValExprNode {
351 TypeTableEntry *type_entry;
352 LLVMValueRef ptr;
353 AstNode *source_node;
354};
355
356struct IfVarNode {
357 BlockContext *block_context;
358};
359
360struct ParamDeclNode {
361 VariableTableEntry *variable;
362};
363
364struct ImportNode {
365 ImportTableEntry *import;
366};
367
368struct WhileNode {
369 bool condition_always_true;
370 bool contains_break;
371};
372
373struct FnCallNode {
374 BuiltinFnEntry *builtin_fn;
375};
376
377struct DeclNode {
378 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> deps;
379 Buf *name;
380 ImportTableEntry *import;
381 // set this flag temporarily to detect infinite loops
382 bool in_current_deps;
383};
384
385// TODO get rid of this structure and put the data directly in the appropriate AST node
386struct CodeGenNode {
387 union {
388 TypeNode type_node; // for NodeTypeType
389 FnDefNode fn_def_node; // for NodeTypeFnDef
390 FnProtoNode fn_proto_node; // for NodeTypeFnProto
391 LabelTableEntry *label_entry; // for NodeTypeGoto and NodeTypeLabel
392 AssignNode assign_node; // for NodeTypeBinOpExpr where op is BinOpTypeAssign
393 BlockNode block_node; // for NodeTypeBlock
394 StructDeclNode struct_decl_node; // for NodeTypeStructDecl
395 FieldAccessNode field_access_node; // for NodeTypeFieldAccessExpr
396 CastNode cast_node; // for NodeTypeCastExpr
397 // note: I've been using this field on some non-number literal nodes too.
398 NumberLiteralNode num_lit_node; // for NodeTypeNumberLiteral
399 VarDeclNode var_decl_node; // for NodeTypeVariableDeclaration
400 StructValFieldNode struct_val_field_node; // for NodeTypeStructValueField
401 // note: I've been using this field on some non-struct val expressions too.
402 StructValExprNode struct_val_expr_node; // for NodeTypeStructValueExpr
403 IfVarNode if_var_node; // for NodeTypeStructValueExpr
404 ParamDeclNode param_decl_node; // for NodeTypeParamDecl
405 ImportNode import_node; // for NodeTypeUse
406 WhileNode while_node; // for NodeTypeWhileExpr
407 FnCallNode fn_call_node; // for NodeTypeFnCallExpr
408 } data;
409 ExprNode expr_node; // for all the expression nodes
410 DeclNode decl_node; // for all top level decls
411};
41212
413void semantic_analyze(CodeGen *g);13void semantic_analyze(CodeGen *g);
414void add_node_error(CodeGen *g, AstNode *node, Buf *msg);14void add_node_error(CodeGen *g, AstNode *node, Buf *msg);
415void alloc_codegen_node(AstNode *node);
416TypeTableEntry *new_type_table_entry(TypeTableEntryId id);15TypeTableEntry *new_type_table_entry(TypeTableEntryId id);
417TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const, bool is_noalias);16TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const, bool is_noalias);
418VariableTableEntry *find_variable(BlockContext *context, Buf *name);17VariableTableEntry *find_variable(BlockContext *context, Buf *name);
419BlockContext *new_block_context(AstNode *node, BlockContext *parent);18BlockContext *new_block_context(AstNode *node, BlockContext *parent);
19Expr *get_resolved_expr(AstNode *node);
20NumLitCodeGen *get_resolved_num_lit(AstNode *node);
21TopLevelDecl *get_resolved_top_level_decl(AstNode *node);
42022
421#endif23#endif
src/codegen.cpp+50-61
...@@ -75,9 +75,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType b...@@ -75,9 +75,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType b
7575
76static TypeTableEntry *get_type_for_type_node(CodeGen *g, AstNode *type_node) {76static TypeTableEntry *get_type_for_type_node(CodeGen *g, AstNode *type_node) {
77 assert(type_node->type == NodeTypeType);77 assert(type_node->type == NodeTypeType);
78 assert(type_node->codegen_node);78 return type_node->data.type.entry;
79 assert(type_node->codegen_node->data.type_node.entry);
80 return type_node->codegen_node->data.type_node.entry;
81}79}
8280
83static TypeTableEntry *fn_proto_type_from_type_node(CodeGen *g, AstNode *type_node) {81static TypeTableEntry *fn_proto_type_from_type_node(CodeGen *g, AstNode *type_node) {
...@@ -138,15 +136,16 @@ static LLVMValueRef find_or_create_string(CodeGen *g, Buf *str, bool c) {...@@ -138,15 +136,16 @@ static LLVMValueRef find_or_create_string(CodeGen *g, Buf *str, bool c) {
138}136}
139137
140static TypeTableEntry *get_expr_type(AstNode *node) {138static TypeTableEntry *get_expr_type(AstNode *node) {
141 TypeTableEntry *cast_type = node->codegen_node->expr_node.implicit_cast.after_type;139 Expr *expr = get_resolved_expr(node);
142 return cast_type ? cast_type : node->codegen_node->expr_node.type_entry;140 TypeTableEntry *cast_type = expr->implicit_cast.after_type;
141 return cast_type ? cast_type : expr->type_entry;
143}142}
144143
145static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {144static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
146 assert(node->type == NodeTypeFnCallExpr);145 assert(node->type == NodeTypeFnCallExpr);
147 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;146 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
148 assert(fn_ref_expr->type == NodeTypeSymbol);147 assert(fn_ref_expr->type == NodeTypeSymbol);
149 BuiltinFnEntry *builtin_fn = node->codegen_node->data.fn_call_node.builtin_fn;148 BuiltinFnEntry *builtin_fn = node->data.fn_call_expr.builtin_fn;
150149
151 switch (builtin_fn->id) {150 switch (builtin_fn->id) {
152 case BuiltinFnIdInvalid:151 case BuiltinFnIdInvalid:
...@@ -265,7 +264,7 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {...@@ -265,7 +264,7 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
265 // Assume that the expression evaluates to a simple name and return the buf264 // Assume that the expression evaluates to a simple name and return the buf
266 // TODO after we support function pointers we can make this generic265 // TODO after we support function pointers we can make this generic
267 assert(fn_ref_expr->type == NodeTypeSymbol);266 assert(fn_ref_expr->type == NodeTypeSymbol);
268 Buf *name = &fn_ref_expr->data.symbol;267 Buf *name = &fn_ref_expr->data.symbol_expr.symbol;
269268
270 struct_type = nullptr;269 struct_type = nullptr;
271 first_param_expr = nullptr;270 first_param_expr = nullptr;
...@@ -388,8 +387,8 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou...@@ -388,8 +387,8 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou
388387
389 LLVMValueRef struct_ptr;388 LLVMValueRef struct_ptr;
390 if (struct_expr_node->type == NodeTypeSymbol) {389 if (struct_expr_node->type == NodeTypeSymbol) {
391 VariableTableEntry *var = find_variable(struct_expr_node->codegen_node->expr_node.block_context,390 VariableTableEntry *var = find_variable(get_resolved_expr(struct_expr_node)->block_context,
392 &struct_expr_node->data.symbol);391 &struct_expr_node->data.symbol_expr.symbol);
393 assert(var);392 assert(var);
394393
395 if (var->is_ptr && var->type->id == TypeTableEntryIdPointer) {394 if (var->is_ptr && var->type->id == TypeTableEntryIdPointer) {
...@@ -413,14 +412,12 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou...@@ -413,14 +412,12 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou
413 assert(LLVMGetTypeKind(LLVMTypeOf(struct_ptr)) == LLVMPointerTypeKind);412 assert(LLVMGetTypeKind(LLVMTypeOf(struct_ptr)) == LLVMPointerTypeKind);
414 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(struct_ptr))) == LLVMStructTypeKind);413 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(struct_ptr))) == LLVMStructTypeKind);
415414
416 FieldAccessNode *codegen_field_access = &node->codegen_node->data.field_access_node;415 assert(node->data.field_access_expr.field_index >= 0);
417416
418 assert(codegen_field_access->field_index >= 0);417 *out_type_entry = node->data.field_access_expr.type_struct_field->type_entry;
419
420 *out_type_entry = codegen_field_access->type_struct_field->type_entry;
421418
422 add_debug_source_node(g, node);419 add_debug_source_node(g, node);
423 return LLVMBuildStructGEP(g->builder, struct_ptr, codegen_field_access->field_index, "");420 return LLVMBuildStructGEP(g->builder, struct_ptr, node->data.field_access_expr.field_index, "");
424}421}
425422
426static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {423static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {
...@@ -429,7 +426,7 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {...@@ -429,7 +426,7 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {
429 AstNode *array_ref_node = node->data.slice_expr.array_ref_expr;426 AstNode *array_ref_node = node->data.slice_expr.array_ref_expr;
430 TypeTableEntry *array_type = get_expr_type(array_ref_node);427 TypeTableEntry *array_type = get_expr_type(array_ref_node);
431428
432 LLVMValueRef tmp_struct_ptr = node->codegen_node->data.struct_val_expr_node.ptr;429 LLVMValueRef tmp_struct_ptr = node->data.slice_expr.resolved_struct_val_expr.ptr;
433 LLVMValueRef array_ptr = gen_array_base_ptr(g, array_ref_node);430 LLVMValueRef array_ptr = gen_array_base_ptr(g, array_ref_node);
434431
435 if (array_type->id == TypeTableEntryIdArray) {432 if (array_type->id == TypeTableEntryIdArray) {
...@@ -545,8 +542,8 @@ static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node,...@@ -545,8 +542,8 @@ static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node,
545 LLVMValueRef target_ref;542 LLVMValueRef target_ref;
546543
547 if (node->type == NodeTypeSymbol) {544 if (node->type == NodeTypeSymbol) {
548 VariableTableEntry *var = find_variable(expr_node->codegen_node->expr_node.block_context,545 VariableTableEntry *var = find_variable(get_resolved_expr(expr_node)->block_context,
549 &node->data.symbol);546 &node->data.symbol_expr.symbol);
550 assert(var);547 assert(var);
551 // semantic checking ensures no variables are constant548 // semantic checking ensures no variables are constant
552 assert(!var->is_const);549 assert(!var->is_const);
...@@ -630,7 +627,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {...@@ -630,7 +627,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
630}627}
631628
632static LLVMValueRef gen_bare_cast(CodeGen *g, AstNode *node, LLVMValueRef expr_val,629static LLVMValueRef gen_bare_cast(CodeGen *g, AstNode *node, LLVMValueRef expr_val,
633 TypeTableEntry *actual_type, TypeTableEntry *wanted_type, CastNode *cast_node)630 TypeTableEntry *actual_type, TypeTableEntry *wanted_type, Cast *cast_node)
634{631{
635 switch (cast_node->op) {632 switch (cast_node->op) {
636 case CastOpNothing:633 case CastOpNothing:
...@@ -705,7 +702,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {...@@ -705,7 +702,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
705 TypeTableEntry *actual_type = get_expr_type(node->data.cast_expr.expr);702 TypeTableEntry *actual_type = get_expr_type(node->data.cast_expr.expr);
706 TypeTableEntry *wanted_type = get_expr_type(node);703 TypeTableEntry *wanted_type = get_expr_type(node);
707704
708 CastNode *cast_node = &node->codegen_node->data.cast_node;705 Cast *cast_node = &node->data.cast_expr.cast;
709706
710 return gen_bare_cast(g, node, expr_val, actual_type, wanted_type, cast_node);707 return gen_bare_cast(g, node, expr_val, actual_type, wanted_type, cast_node);
711708
...@@ -1218,7 +1215,7 @@ static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) {...@@ -1218,7 +1215,7 @@ static LLVMValueRef gen_if_var_expr(CodeGen *g, AstNode *node) {
1218 assert(node->data.if_var_expr.var_decl.expr);1215 assert(node->data.if_var_expr.var_decl.expr);
12191216
1220 BlockContext *old_block_context = g->cur_block_context;1217 BlockContext *old_block_context = g->cur_block_context;
1221 BlockContext *new_block_context = node->codegen_node->data.if_var_node.block_context;1218 BlockContext *new_block_context = node->data.if_var_expr.block_context;
12221219
1223 LLVMValueRef init_val;1220 LLVMValueRef init_val;
1224 gen_var_decl_raw(g, node, &node->data.if_var_expr.var_decl, new_block_context, true, &init_val);1221 gen_var_decl_raw(g, node, &node->data.if_var_expr.var_decl, new_block_context, true, &init_val);
...@@ -1242,7 +1239,7 @@ static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *i...@@ -1242,7 +1239,7 @@ static LLVMValueRef gen_block(CodeGen *g, AstNode *block_node, TypeTableEntry *i
1242 assert(block_node->type == NodeTypeBlock);1239 assert(block_node->type == NodeTypeBlock);
12431240
1244 BlockContext *old_block_context = g->cur_block_context;1241 BlockContext *old_block_context = g->cur_block_context;
1245 g->cur_block_context = block_node->codegen_node->data.block_node.block_context;1242 g->cur_block_context = block_node->data.block.block_context;
12461243
1247 LLVMValueRef return_value;1244 LLVMValueRef return_value;
1248 for (int i = 0; i < block_node->data.block.statements.length; i += 1) {1245 for (int i = 0; i < block_node->data.block.statements.length; i += 1) {
...@@ -1347,7 +1344,7 @@ static LLVMValueRef gen_asm_expr(CodeGen *g, AstNode *node) {...@@ -1347,7 +1344,7 @@ static LLVMValueRef gen_asm_expr(CodeGen *g, AstNode *node) {
13471344
1348 if (!is_return) {1345 if (!is_return) {
1349 VariableTableEntry *variable = find_variable(1346 VariableTableEntry *variable = find_variable(
1350 node->codegen_node->expr_node.block_context,1347 get_resolved_expr(node)->block_context,
1351 &asm_output->variable_name);1348 &asm_output->variable_name);
1352 assert(variable);1349 assert(variable);
1353 param_types[param_index] = LLVMTypeOf(variable->value_ref);1350 param_types[param_index] = LLVMTypeOf(variable->value_ref);
...@@ -1396,7 +1393,7 @@ static LLVMValueRef gen_null_literal(CodeGen *g, AstNode *node) {...@@ -1396,7 +1393,7 @@ static LLVMValueRef gen_null_literal(CodeGen *g, AstNode *node) {
1396 TypeTableEntry *type_entry = get_expr_type(node);1393 TypeTableEntry *type_entry = get_expr_type(node);
1397 assert(type_entry->id == TypeTableEntryIdMaybe);1394 assert(type_entry->id == TypeTableEntryIdMaybe);
13981395
1399 LLVMValueRef tmp_struct_ptr = node->codegen_node->data.struct_val_expr_node.ptr;1396 LLVMValueRef tmp_struct_ptr = node->data.null_literal.resolved_struct_val_expr.ptr;
14001397
1401 add_debug_source_node(g, node);1398 add_debug_source_node(g, node);
1402 LLVMValueRef field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 1, "");1399 LLVMValueRef field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 1, "");
...@@ -1416,12 +1413,13 @@ static LLVMValueRef gen_struct_val_expr(CodeGen *g, AstNode *node) {...@@ -1416,12 +1413,13 @@ static LLVMValueRef gen_struct_val_expr(CodeGen *g, AstNode *node) {
1416 int field_count = type_entry->data.structure.field_count;1413 int field_count = type_entry->data.structure.field_count;
1417 assert(field_count == node->data.struct_val_expr.fields.length);1414 assert(field_count == node->data.struct_val_expr.fields.length);
14181415
1419 StructValExprNode *struct_val_expr_node = &node->codegen_node->data.struct_val_expr_node;1416 StructValExprCodeGen *struct_val_expr_node = &node->data.struct_val_expr.codegen;
1420 LLVMValueRef tmp_struct_ptr = struct_val_expr_node->ptr;1417 LLVMValueRef tmp_struct_ptr = struct_val_expr_node->ptr;
14211418
1422 for (int i = 0; i < field_count; i += 1) {1419 for (int i = 0; i < field_count; i += 1) {
1423 AstNode *field_node = node->data.struct_val_expr.fields.at(i);1420 AstNode *field_node = node->data.struct_val_expr.fields.at(i);
1424 int index = field_node->codegen_node->data.struct_val_field_node.index;1421 assert(field_node->type == NodeTypeStructValueField);
1422 int index = field_node->data.struct_val_field.index;
1425 TypeStructField *type_struct_field = &type_entry->data.structure.fields[index];1423 TypeStructField *type_struct_field = &type_entry->data.structure.fields[index];
1426 assert(buf_eql_buf(type_struct_field->name, &field_node->data.struct_val_field.name));1424 assert(buf_eql_buf(type_struct_field->name, &field_node->data.struct_val_field.name));
14271425
...@@ -1439,8 +1437,8 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) {...@@ -1439,8 +1437,8 @@ static LLVMValueRef gen_while_expr(CodeGen *g, AstNode *node) {
1439 assert(node->data.while_expr.condition);1437 assert(node->data.while_expr.condition);
1440 assert(node->data.while_expr.body);1438 assert(node->data.while_expr.body);
14411439
1442 bool condition_always_true = node->codegen_node->data.while_node.condition_always_true;1440 bool condition_always_true = node->data.while_expr.condition_always_true;
1443 bool contains_break = node->codegen_node->data.while_node.contains_break;1441 bool contains_break = node->data.while_expr.contains_break;
1444 if (condition_always_true) {1442 if (condition_always_true) {
1445 // generate a forever loop1443 // generate a forever loop
14461444
...@@ -1559,17 +1557,17 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa...@@ -1559,17 +1557,17 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
1559static LLVMValueRef gen_var_decl_expr(CodeGen *g, AstNode *node) {1557static LLVMValueRef gen_var_decl_expr(CodeGen *g, AstNode *node) {
1560 LLVMValueRef init_val;1558 LLVMValueRef init_val;
1561 return gen_var_decl_raw(g, node, &node->data.variable_declaration,1559 return gen_var_decl_raw(g, node, &node->data.variable_declaration,
1562 node->codegen_node->expr_node.block_context, false, &init_val);1560 get_resolved_expr(node)->block_context, false, &init_val);
1563}1561}
15641562
1565static LLVMValueRef gen_number_literal_raw(CodeGen *g, AstNode *source_node,1563static LLVMValueRef gen_number_literal_raw(CodeGen *g, AstNode *source_node,
1566 NumberLiteralNode *codegen_num_lit, AstNodeNumberLiteral *num_lit_node)1564 NumLitCodeGen *codegen_num_lit, AstNodeNumberLiteral *num_lit_node)
1567{1565{
1568 TypeTableEntry *type_entry = codegen_num_lit->resolved_type;1566 TypeTableEntry *type_entry = codegen_num_lit->resolved_type;
1569 assert(type_entry);1567 assert(type_entry);
15701568
1571 // override the expression type for number literals1569 // override the expression type for number literals
1572 source_node->codegen_node->expr_node.type_entry = type_entry;1570 get_resolved_expr(source_node)->type_entry = type_entry;
15731571
1574 if (type_entry->id == TypeTableEntryIdInt) {1572 if (type_entry->id == TypeTableEntryIdInt) {
1575 // here the union has int64_t and uint64_t and we purposefully read1573 // here the union has int64_t and uint64_t and we purposefully read
...@@ -1594,7 +1592,7 @@ static LLVMValueRef gen_compiler_fn_type(CodeGen *g, AstNode *node) {...@@ -1594,7 +1592,7 @@ static LLVMValueRef gen_compiler_fn_type(CodeGen *g, AstNode *node) {
1594 Buf *name = &node->data.compiler_fn_type.name;1592 Buf *name = &node->data.compiler_fn_type.name;
1595 TypeTableEntry *type_entry = get_type_for_type_node(g, node->data.compiler_fn_type.type);1593 TypeTableEntry *type_entry = get_type_for_type_node(g, node->data.compiler_fn_type.type);
1596 if (buf_eql_str(name, "sizeof")) {1594 if (buf_eql_str(name, "sizeof")) {
1597 NumberLiteralNode *codegen_num_lit = &node->codegen_node->data.num_lit_node;1595 NumLitCodeGen *codegen_num_lit = get_resolved_num_lit(node);
1598 AstNodeNumberLiteral num_lit_node;1596 AstNodeNumberLiteral num_lit_node;
1599 num_lit_node.kind = type_entry->data.num_lit.kind;1597 num_lit_node.kind = type_entry->data.num_lit.kind;
1600 num_lit_node.overflow = false;1598 num_lit_node.overflow = false;
...@@ -1632,7 +1630,7 @@ static LLVMValueRef gen_compiler_fn_type(CodeGen *g, AstNode *node) {...@@ -1632,7 +1630,7 @@ static LLVMValueRef gen_compiler_fn_type(CodeGen *g, AstNode *node) {
1632static LLVMValueRef gen_number_literal(CodeGen *g, AstNode *node) {1630static LLVMValueRef gen_number_literal(CodeGen *g, AstNode *node) {
1633 assert(node->type == NodeTypeNumberLiteral);1631 assert(node->type == NodeTypeNumberLiteral);
16341632
1635 NumberLiteralNode *codegen_num_lit = &node->codegen_node->data.num_lit_node;1633 NumLitCodeGen *codegen_num_lit = get_resolved_num_lit(node);
1636 assert(codegen_num_lit);1634 assert(codegen_num_lit);
16371635
1638 return gen_number_literal_raw(g, node, codegen_num_lit, &node->data.number_literal);1636 return gen_number_literal_raw(g, node, codegen_num_lit, &node->data.number_literal);
...@@ -1664,7 +1662,7 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {...@@ -1664,7 +1662,7 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {
1664 case NodeTypeVoid:1662 case NodeTypeVoid:
1665 return nullptr;1663 return nullptr;
1666 case NodeTypeBoolLiteral:1664 case NodeTypeBoolLiteral:
1667 if (node->data.bool_literal)1665 if (node->data.bool_literal.value)
1668 return LLVMConstAllOnes(LLVMInt1Type());1666 return LLVMConstAllOnes(LLVMInt1Type());
1669 else1667 else
1670 return LLVMConstNull(LLVMInt1Type());1668 return LLVMConstNull(LLVMInt1Type());
...@@ -1696,8 +1694,8 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {...@@ -1696,8 +1694,8 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {
1696 case NodeTypeSymbol:1694 case NodeTypeSymbol:
1697 {1695 {
1698 VariableTableEntry *variable = find_variable(1696 VariableTableEntry *variable = find_variable(
1699 node->codegen_node->expr_node.block_context,1697 get_resolved_expr(node)->block_context,
1700 &node->data.symbol);1698 &node->data.symbol_expr.symbol);
1701 assert(variable);1699 assert(variable);
1702 if (variable->type->id == TypeTableEntryIdVoid) {1700 if (variable->type->id == TypeTableEntryIdVoid) {
1703 return nullptr;1701 return nullptr;
...@@ -1721,14 +1719,14 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {...@@ -1721,14 +1719,14 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {
1721 return gen_block(g, node, nullptr);1719 return gen_block(g, node, nullptr);
1722 case NodeTypeGoto:1720 case NodeTypeGoto:
1723 add_debug_source_node(g, node);1721 add_debug_source_node(g, node);
1724 return LLVMBuildBr(g->builder, node->codegen_node->data.label_entry->basic_block);1722 return LLVMBuildBr(g->builder, node->data.goto_expr.label_entry->basic_block);
1725 case NodeTypeBreak:1723 case NodeTypeBreak:
1726 return gen_break(g, node);1724 return gen_break(g, node);
1727 case NodeTypeContinue:1725 case NodeTypeContinue:
1728 return gen_continue(g, node);1726 return gen_continue(g, node);
1729 case NodeTypeLabel:1727 case NodeTypeLabel:
1730 {1728 {
1731 LabelTableEntry *label_entry = node->codegen_node->data.label_entry;1729 LabelTableEntry *label_entry = node->data.label.label_entry;
1732 assert(label_entry);1730 assert(label_entry);
1733 LLVMBasicBlockRef basic_block = label_entry->basic_block;1731 LLVMBasicBlockRef basic_block = label_entry->basic_block;
1734 if (label_entry->entered_from_fallthrough) {1732 if (label_entry->entered_from_fallthrough) {
...@@ -1770,19 +1768,19 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {...@@ -1770,19 +1768,19 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
1770 return val;1768 return val;
1771 }1769 }
17721770
1773 assert(node->codegen_node);1771 Expr *expr = get_resolved_expr(node);
17741772
1775 TypeTableEntry *before_type = node->codegen_node->expr_node.type_entry;1773 TypeTableEntry *before_type = expr->type_entry;
1776 if (before_type && before_type->id == TypeTableEntryIdUnreachable) {1774 if (before_type && before_type->id == TypeTableEntryIdUnreachable) {
1777 return val;1775 return val;
1778 }1776 }
1779 CastNode *cast_node = &node->codegen_node->expr_node.implicit_cast;1777 Cast *cast_node = &expr->implicit_cast;
1780 if (cast_node->after_type) {1778 if (cast_node->after_type) {
1781 val = gen_bare_cast(g, node, val, before_type, cast_node->after_type, cast_node);1779 val = gen_bare_cast(g, node, val, before_type, cast_node->after_type, cast_node);
1782 before_type = cast_node->after_type;1780 before_type = cast_node->after_type;
1783 }1781 }
17841782
1785 cast_node = &node->codegen_node->expr_node.implicit_maybe_cast;1783 cast_node = &expr->implicit_maybe_cast;
1786 if (cast_node->after_type) {1784 if (cast_node->after_type) {
1787 val = gen_bare_cast(g, node, val, before_type, cast_node->after_type, cast_node);1785 val = gen_bare_cast(g, node, val, before_type, cast_node->after_type, cast_node);
1788 }1786 }
...@@ -1798,7 +1796,7 @@ static void build_label_blocks(CodeGen *g, AstNode *block_node) {...@@ -1798,7 +1796,7 @@ static void build_label_blocks(CodeGen *g, AstNode *block_node) {
1798 continue;1796 continue;
17991797
1800 Buf *name = &label_node->data.label.name;1798 Buf *name = &label_node->data.label.name;
1801 label_node->codegen_node->data.label_entry->basic_block = LLVMAppendBasicBlock(1799 label_node->data.label.label_entry->basic_block = LLVMAppendBasicBlock(
1802 g->cur_fn->fn_value, buf_ptr(name));1800 g->cur_fn->fn_value, buf_ptr(name));
1803 }1801 }
18041802
...@@ -1944,13 +1942,7 @@ static void do_code_gen(CodeGen *g) {...@@ -1944,13 +1942,7 @@ static void do_code_gen(CodeGen *g) {
1944 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn, "entry");1942 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn, "entry");
1945 LLVMPositionBuilderAtEnd(g->builder, entry_block);1943 LLVMPositionBuilderAtEnd(g->builder, entry_block);
19461944
1947 CodeGenNode *codegen_node = fn_def_node->codegen_node;1945 fn_def_node->data.fn_def.block_context->di_scope = LLVMZigSubprogramToScope(subprogram);
1948 assert(codegen_node);
1949
1950 FnDefNode *codegen_fn_def = &codegen_node->data.fn_def_node;
1951 assert(codegen_fn_def);
1952
1953 codegen_fn_def->block_context->di_scope = LLVMZigSubprogramToScope(subprogram);
19541946
1955 int non_void_param_count = count_non_void_params(g, &fn_proto->params);1947 int non_void_param_count = count_non_void_params(g, &fn_proto->params);
1956 assert(non_void_param_count == (int)LLVMCountParams(fn));1948 assert(non_void_param_count == (int)LLVMCountParams(fn));
...@@ -1963,7 +1955,7 @@ static void do_code_gen(CodeGen *g) {...@@ -1963,7 +1955,7 @@ static void do_code_gen(CodeGen *g) {
1963 assert(param_decl->type == NodeTypeParamDecl);1955 assert(param_decl->type == NodeTypeParamDecl);
1964 if (is_param_decl_type_void(g, param_decl))1956 if (is_param_decl_type_void(g, param_decl))
1965 continue;1957 continue;
1966 VariableTableEntry *parameter_variable = fn_def_node->codegen_node->data.fn_def_node.block_context->variable_table.get(&param_decl->data.param_decl.name);1958 VariableTableEntry *parameter_variable = fn_def_node->data.fn_def.block_context->variable_table.get(&param_decl->data.param_decl.name);
1967 parameter_variable->value_ref = params[non_void_index];1959 parameter_variable->value_ref = params[non_void_index];
1968 non_void_index += 1;1960 non_void_index += 1;
1969 }1961 }
...@@ -2019,14 +2011,14 @@ static void do_code_gen(CodeGen *g) {...@@ -2019,14 +2011,14 @@ static void do_code_gen(CodeGen *g) {
20192011
2020 // allocate structs which are the result of casts2012 // allocate structs which are the result of casts
2021 for (int cea_i = 0; cea_i < block_context->cast_expr_alloca_list.length; cea_i += 1) {2013 for (int cea_i = 0; cea_i < block_context->cast_expr_alloca_list.length; cea_i += 1) {
2022 CastNode *cast_node = block_context->cast_expr_alloca_list.at(cea_i);2014 Cast *cast_node = block_context->cast_expr_alloca_list.at(cea_i);
2023 add_debug_source_node(g, cast_node->source_node);2015 add_debug_source_node(g, cast_node->source_node);
2024 cast_node->ptr = LLVMBuildAlloca(g->builder, cast_node->after_type->type_ref, "");2016 cast_node->ptr = LLVMBuildAlloca(g->builder, cast_node->after_type->type_ref, "");
2025 }2017 }
20262018
2027 // allocate structs which are struct value expressions2019 // allocate structs which are struct value expressions
2028 for (int alloca_i = 0; alloca_i < block_context->struct_val_expr_alloca_list.length; alloca_i += 1) {2020 for (int alloca_i = 0; alloca_i < block_context->struct_val_expr_alloca_list.length; alloca_i += 1) {
2029 StructValExprNode *struct_val_expr_node = block_context->struct_val_expr_alloca_list.at(alloca_i);2021 StructValExprCodeGen *struct_val_expr_node = block_context->struct_val_expr_alloca_list.at(alloca_i);
2030 add_debug_source_node(g, struct_val_expr_node->source_node);2022 add_debug_source_node(g, struct_val_expr_node->source_node);
2031 struct_val_expr_node->ptr = LLVMBuildAlloca(g->builder,2023 struct_val_expr_node->ptr = LLVMBuildAlloca(g->builder,
2032 struct_val_expr_node->type_entry->type_ref, "");2024 struct_val_expr_node->type_entry->type_ref, "");
...@@ -2041,15 +2033,15 @@ static void do_code_gen(CodeGen *g) {...@@ -2041,15 +2033,15 @@ static void do_code_gen(CodeGen *g) {
2041 if (is_param_decl_type_void(g, param_decl))2033 if (is_param_decl_type_void(g, param_decl))
2042 continue;2034 continue;
20432035
2044 VariableTableEntry *variable = param_decl->codegen_node->data.param_decl_node.variable;2036 VariableTableEntry *variable = param_decl->data.param_decl.variable;
20452037
2046 LLVMZigDILocation *debug_loc = LLVMZigGetDebugLoc(param_decl->line + 1, param_decl->column + 1,2038 LLVMZigDILocation *debug_loc = LLVMZigGetDebugLoc(param_decl->line + 1, param_decl->column + 1,
2047 codegen_fn_def->block_context->di_scope);2039 fn_def_node->data.fn_def.block_context->di_scope);
2048 LLVMZigInsertDeclareAtEnd(g->dbuilder, variable->value_ref, variable->di_loc_var, debug_loc,2040 LLVMZigInsertDeclareAtEnd(g->dbuilder, variable->value_ref, variable->di_loc_var, debug_loc,
2049 entry_block);2041 entry_block);
2050 }2042 }
20512043
2052 TypeTableEntry *implicit_return_type = codegen_fn_def->implicit_return_type;2044 TypeTableEntry *implicit_return_type = fn_def_node->data.fn_def.implicit_return_type;
2053 gen_block(g, fn_def_node->data.fn_def.body, implicit_return_type);2045 gen_block(g, fn_def_node->data.fn_def.body, implicit_return_type);
20542046
2055 }2047 }
...@@ -2549,8 +2541,6 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,...@@ -2549,8 +2541,6 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
2549 Buf *import_code = buf_alloc();2541 Buf *import_code = buf_alloc();
2550 bool found_it = false;2542 bool found_it = false;
25512543
2552 alloc_codegen_node(top_level_decl);
2553
2554 for (int path_i = 0; path_i < g->lib_search_paths.length; path_i += 1) {2544 for (int path_i = 0; path_i < g->lib_search_paths.length; path_i += 1) {
2555 Buf *search_path = g->lib_search_paths.at(path_i);2545 Buf *search_path = g->lib_search_paths.at(path_i);
2556 os_path_join(search_path, import_target_path, &full_path);2546 os_path_join(search_path, import_target_path, &full_path);
...@@ -2570,7 +2560,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,...@@ -2570,7 +2560,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
2570 auto entry = g->import_table.maybe_get(abs_full_path);2560 auto entry = g->import_table.maybe_get(abs_full_path);
2571 if (entry) {2561 if (entry) {
2572 found_it = true;2562 found_it = true;
2573 top_level_decl->codegen_node->data.import_node.import = entry->value;2563 top_level_decl->data.use.import = entry->value;
2574 } else {2564 } else {
2575 if ((err = os_fetch_file_path(abs_full_path, import_code))) {2565 if ((err = os_fetch_file_path(abs_full_path, import_code))) {
2576 if (err == ErrorFileNotFound) {2566 if (err == ErrorFileNotFound) {
...@@ -2582,7 +2572,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,...@@ -2582,7 +2572,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
2582 goto done_looking_at_imports;2572 goto done_looking_at_imports;
2583 }2573 }
2584 }2574 }
2585 top_level_decl->codegen_node->data.import_node.import = codegen_add_code(g,2575 top_level_decl->data.use.import = codegen_add_code(g,
2586 abs_full_path, search_path, &top_level_decl->data.use.path, import_code);2576 abs_full_path, search_path, &top_level_decl->data.use.path, import_code);
2587 found_it = true;2577 found_it = true;
2588 }2578 }
...@@ -2682,9 +2672,8 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou...@@ -2682,9 +2672,8 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou
26822672
2683static void to_c_type(CodeGen *g, AstNode *type_node, Buf *out_buf) {2673static void to_c_type(CodeGen *g, AstNode *type_node, Buf *out_buf) {
2684 assert(type_node->type == NodeTypeType);2674 assert(type_node->type == NodeTypeType);
2685 assert(type_node->codegen_node);
26862675
2687 TypeTableEntry *type_entry = type_node->codegen_node->data.type_node.entry;2676 TypeTableEntry *type_entry = type_node->data.type.entry;
2688 assert(type_entry);2677 assert(type_entry);
26892678
2690 if (type_entry == g->builtin_types.entry_u8) {2679 if (type_entry == g->builtin_types.entry_u8) {
src/codegen.hpp-13
...@@ -11,21 +11,8 @@...@@ -11,21 +11,8 @@
11#include "parser.hpp"11#include "parser.hpp"
12#include "errmsg.hpp"12#include "errmsg.hpp"
1313
14struct CodeGen;
15
16enum OutType {
17 OutTypeUnknown,
18 OutTypeExe,
19 OutTypeLib,
20 OutTypeObj,
21};
22
23CodeGen *codegen_create(Buf *root_source_dir);14CodeGen *codegen_create(Buf *root_source_dir);
2415
25enum CodeGenBuildType {
26 CodeGenBuildTypeDebug,
27 CodeGenBuildTypeRelease,
28};
29void codegen_set_build_type(CodeGen *codegen, CodeGenBuildType build_type);16void codegen_set_build_type(CodeGen *codegen, CodeGenBuildType build_type);
30void codegen_set_is_static(CodeGen *codegen, bool is_static);17void codegen_set_is_static(CodeGen *codegen, bool is_static);
31void codegen_set_strip(CodeGen *codegen, bool strip);18void codegen_set_strip(CodeGen *codegen, bool strip);
src/parser.cpp+9-9
...@@ -356,8 +356,7 @@ void ast_print(AstNode *node, int indent) {...@@ -356,8 +356,7 @@ void ast_print(AstNode *node, int indent) {
356 fprintf(stderr, "Unreachable\n");356 fprintf(stderr, "Unreachable\n");
357 break;357 break;
358 case NodeTypeSymbol:358 case NodeTypeSymbol:
359 fprintf(stderr, "Symbol %s\n",359 fprintf(stderr, "Symbol %s\n", buf_ptr(&node->data.symbol_expr.symbol));
360 buf_ptr(&node->data.symbol));
361 break;360 break;
362 case NodeTypeUse:361 case NodeTypeUse:
363 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.use.path));362 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.use.path));
...@@ -366,7 +365,8 @@ void ast_print(AstNode *node, int indent) {...@@ -366,7 +365,8 @@ void ast_print(AstNode *node, int indent) {
366 fprintf(stderr, "%s\n", node_type_str(node->type));365 fprintf(stderr, "%s\n", node_type_str(node->type));
367 break;366 break;
368 case NodeTypeBoolLiteral:367 case NodeTypeBoolLiteral:
369 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), node->data.bool_literal ? "true" : "false");368 fprintf(stderr, "%s '%s'\n", node_type_str(node->type),
369 node->data.bool_literal.value ? "true" : "false");
370 break;370 break;
371 case NodeTypeNullLiteral:371 case NodeTypeNullLiteral:
372 fprintf(stderr, "%s\n", node_type_str(node->type));372 fprintf(stderr, "%s\n", node_type_str(node->type));
...@@ -401,7 +401,7 @@ void ast_print(AstNode *node, int indent) {...@@ -401,7 +401,7 @@ void ast_print(AstNode *node, int indent) {
401 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.label.name));401 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.label.name));
402 break;402 break;
403 case NodeTypeGoto:403 case NodeTypeGoto:
404 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.go_to.name));404 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.goto_expr.name));
405 break;405 break;
406 case NodeTypeBreak:406 case NodeTypeBreak:
407 fprintf(stderr, "%s\n", node_type_str(node->type));407 fprintf(stderr, "%s\n", node_type_str(node->type));
...@@ -1369,12 +1369,12 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool...@@ -1369,12 +1369,12 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
1369 return node;1369 return node;
1370 } else if (token->id == TokenIdKeywordTrue) {1370 } else if (token->id == TokenIdKeywordTrue) {
1371 AstNode *node = ast_create_node(pc, NodeTypeBoolLiteral, token);1371 AstNode *node = ast_create_node(pc, NodeTypeBoolLiteral, token);
1372 node->data.bool_literal = true;1372 node->data.bool_literal.value = true;
1373 *token_index += 1;1373 *token_index += 1;
1374 return node;1374 return node;
1375 } else if (token->id == TokenIdKeywordFalse) {1375 } else if (token->id == TokenIdKeywordFalse) {
1376 AstNode *node = ast_create_node(pc, NodeTypeBoolLiteral, token);1376 AstNode *node = ast_create_node(pc, NodeTypeBoolLiteral, token);
1377 node->data.bool_literal = false;1377 node->data.bool_literal.value = false;
1378 *token_index += 1;1378 *token_index += 1;
1379 return node;1379 return node;
1380 } else if (token->id == TokenIdKeywordNull) {1380 } else if (token->id == TokenIdKeywordNull) {
...@@ -1385,7 +1385,7 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool...@@ -1385,7 +1385,7 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
1385 *token_index += 1;1385 *token_index += 1;
1386 Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);1386 Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
1387 AstNode *name_node = ast_create_node(pc, NodeTypeSymbol, name_tok);1387 AstNode *name_node = ast_create_node(pc, NodeTypeSymbol, name_tok);
1388 ast_buf_from_token(pc, name_tok, &name_node->data.symbol);1388 ast_buf_from_token(pc, name_tok, &name_node->data.symbol_expr.symbol);
13891389
1390 AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, token);1390 AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, token);
1391 node->data.fn_call_expr.fn_ref_expr = name_node;1391 node->data.fn_call_expr.fn_ref_expr = name_node;
...@@ -1401,7 +1401,7 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool...@@ -1401,7 +1401,7 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
1401 } else {1401 } else {
1402 *token_index += 1;1402 *token_index += 1;
1403 AstNode *node = ast_create_node(pc, NodeTypeSymbol, token);1403 AstNode *node = ast_create_node(pc, NodeTypeSymbol, token);
1404 ast_buf_from_token(pc, token, &node->data.symbol);1404 ast_buf_from_token(pc, token, &node->data.symbol_expr.symbol);
1405 return node;1405 return node;
1406 }1406 }
1407 } else if (token->id == TokenIdKeywordGoto) {1407 } else if (token->id == TokenIdKeywordGoto) {
...@@ -1412,7 +1412,7 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool...@@ -1412,7 +1412,7 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
1412 *token_index += 1;1412 *token_index += 1;
1413 ast_expect_token(pc, dest_symbol, TokenIdSymbol);1413 ast_expect_token(pc, dest_symbol, TokenIdSymbol);
14141414
1415 ast_buf_from_token(pc, dest_symbol, &node->data.go_to.name);1415 ast_buf_from_token(pc, dest_symbol, &node->data.goto_expr.name);
1416 return node;1416 return node;
1417 } else if (token->id == TokenIdKeywordBreak) {1417 } else if (token->id == TokenIdKeywordBreak) {
1418 AstNode *node = ast_create_node(pc, NodeTypeBreak, token);1418 AstNode *node = ast_create_node(pc, NodeTypeBreak, token);
src/parser.hpp+1-441
...@@ -8,450 +8,10 @@...@@ -8,450 +8,10 @@
8#ifndef ZIG_PARSER_HPP8#ifndef ZIG_PARSER_HPP
9#define ZIG_PARSER_HPP9#define ZIG_PARSER_HPP
1010
11#include "list.hpp"11#include "all_types.hpp"
12#include "buffer.hpp"
13#include "tokenizer.hpp"12#include "tokenizer.hpp"
14#include "errmsg.hpp"13#include "errmsg.hpp"
1514
16struct AstNode;
17struct CodeGenNode;
18struct ImportTableEntry;
19struct AsmToken;
20
21enum NodeType {
22 NodeTypeRoot,
23 NodeTypeRootExportDecl,
24 NodeTypeFnProto,
25 NodeTypeFnDef,
26 NodeTypeFnDecl,
27 NodeTypeParamDecl,
28 NodeTypeType,
29 NodeTypeBlock,
30 NodeTypeExternBlock,
31 NodeTypeDirective,
32 NodeTypeReturnExpr,
33 NodeTypeVariableDeclaration,
34 NodeTypeBinOpExpr,
35 NodeTypeCastExpr,
36 NodeTypeNumberLiteral,
37 NodeTypeStringLiteral,
38 NodeTypeCharLiteral,
39 NodeTypeUnreachable,
40 NodeTypeSymbol,
41 NodeTypePrefixOpExpr,
42 NodeTypeFnCallExpr,
43 NodeTypeArrayAccessExpr,
44 NodeTypeSliceExpr,
45 NodeTypeFieldAccessExpr,
46 NodeTypeUse,
47 NodeTypeVoid,
48 NodeTypeBoolLiteral,
49 NodeTypeNullLiteral,
50 NodeTypeIfBoolExpr,
51 NodeTypeIfVarExpr,
52 NodeTypeWhileExpr,
53 NodeTypeLabel,
54 NodeTypeGoto,
55 NodeTypeBreak,
56 NodeTypeContinue,
57 NodeTypeAsmExpr,
58 NodeTypeStructDecl,
59 NodeTypeStructField,
60 NodeTypeStructValueExpr,
61 NodeTypeStructValueField,
62 NodeTypeEnumDecl,
63 NodeTypeEnumField,
64 NodeTypeCompilerFnExpr,
65 NodeTypeCompilerFnType,
66};
67
68struct AstNodeRoot {
69 ZigList<AstNode *> top_level_decls;
70};
71
72enum VisibMod {
73 VisibModPrivate,
74 VisibModPub,
75 VisibModExport,
76};
77
78struct AstNodeFnProto {
79 ZigList<AstNode *> *directives;
80 VisibMod visib_mod;
81 Buf name;
82 ZigList<AstNode *> params;
83 AstNode *return_type;
84 bool is_var_args;
85
86 // the extern block this fn proto is inside. can be null.
87 // populated by semantic analyzer.
88 AstNode *extern_node;
89 // the struct decl node this fn proto is inside. can be null.
90 // populated by semantic analyzer.
91 AstNode *struct_node;
92 // the function definition this fn proto is inside. can be null.
93 // populated by semantic analyzer.
94 AstNode *fn_def_node;
95};
96
97struct AstNodeFnDef {
98 AstNode *fn_proto;
99 AstNode *body;
100};
101
102struct AstNodeFnDecl {
103 AstNode *fn_proto;
104};
105
106struct AstNodeParamDecl {
107 Buf name;
108 AstNode *type;
109};
110
111enum AstNodeTypeType {
112 AstNodeTypeTypePrimitive,
113 AstNodeTypeTypePointer,
114 AstNodeTypeTypeArray,
115 AstNodeTypeTypeMaybe,
116 AstNodeTypeTypeCompilerExpr,
117};
118
119struct AstNodeType {
120 AstNodeTypeType type;
121 Buf primitive_name;
122 AstNode *child_type;
123 AstNode *array_size; // can be null
124 bool is_const;
125 bool is_noalias;
126 AstNode *compiler_expr;
127};
128
129struct AstNodeBlock {
130 ZigList<AstNode *> statements;
131};
132
133struct AstNodeReturnExpr {
134 // might be null in case of return void;
135 AstNode *expr;
136};
137
138struct AstNodeVariableDeclaration {
139 Buf symbol;
140 bool is_const;
141 VisibMod visib_mod;
142 // one or both of type and expr will be non null
143 AstNode *type;
144 AstNode *expr;
145};
146
147enum BinOpType {
148 BinOpTypeInvalid,
149 BinOpTypeAssign,
150 BinOpTypeAssignTimes,
151 BinOpTypeAssignDiv,
152 BinOpTypeAssignMod,
153 BinOpTypeAssignPlus,
154 BinOpTypeAssignMinus,
155 BinOpTypeAssignBitShiftLeft,
156 BinOpTypeAssignBitShiftRight,
157 BinOpTypeAssignBitAnd,
158 BinOpTypeAssignBitXor,
159 BinOpTypeAssignBitOr,
160 BinOpTypeAssignBoolAnd,
161 BinOpTypeAssignBoolOr,
162 BinOpTypeBoolOr,
163 BinOpTypeBoolAnd,
164 BinOpTypeCmpEq,
165 BinOpTypeCmpNotEq,
166 BinOpTypeCmpLessThan,
167 BinOpTypeCmpGreaterThan,
168 BinOpTypeCmpLessOrEq,
169 BinOpTypeCmpGreaterOrEq,
170 BinOpTypeBinOr,
171 BinOpTypeBinXor,
172 BinOpTypeBinAnd,
173 BinOpTypeBitShiftLeft,
174 BinOpTypeBitShiftRight,
175 BinOpTypeAdd,
176 BinOpTypeSub,
177 BinOpTypeMult,
178 BinOpTypeDiv,
179 BinOpTypeMod,
180 BinOpTypeUnwrapMaybe,
181};
182
183struct AstNodeBinOpExpr {
184 AstNode *op1;
185 BinOpType bin_op;
186 AstNode *op2;
187};
188
189struct AstNodeFnCallExpr {
190 AstNode *fn_ref_expr;
191 ZigList<AstNode *> params;
192 bool is_builtin;
193};
194
195struct AstNodeArrayAccessExpr {
196 AstNode *array_ref_expr;
197 AstNode *subscript;
198};
199
200struct AstNodeSliceExpr {
201 AstNode *array_ref_expr;
202 AstNode *start;
203 AstNode *end;
204 bool is_const;
205};
206
207struct AstNodeFieldAccessExpr {
208 AstNode *struct_expr;
209 Buf field_name;
210};
211
212struct AstNodeExternBlock {
213 ZigList<AstNode *> *directives;
214 ZigList<AstNode *> fn_decls;
215};
216
217struct AstNodeDirective {
218 Buf name;
219 Buf param;
220};
221
222struct AstNodeRootExportDecl {
223 Buf type;
224 Buf name;
225 ZigList<AstNode *> *directives;
226};
227
228struct AstNodeCastExpr {
229 AstNode *expr;
230 AstNode *type;
231};
232
233enum PrefixOp {
234 PrefixOpInvalid,
235 PrefixOpBoolNot,
236 PrefixOpBinNot,
237 PrefixOpNegation,
238 PrefixOpAddressOf,
239 PrefixOpConstAddressOf,
240 PrefixOpDereference,
241};
242
243struct AstNodePrefixOpExpr {
244 PrefixOp prefix_op;
245 AstNode *primary_expr;
246};
247
248struct AstNodeUse {
249 Buf path;
250 ZigList<AstNode *> *directives;
251};
252
253struct AstNodeIfBoolExpr {
254 AstNode *condition;
255 AstNode *then_block;
256 AstNode *else_node; // null, block node, or other if expr node
257};
258
259struct AstNodeIfVarExpr {
260 AstNodeVariableDeclaration var_decl;
261 AstNode *then_block;
262 AstNode *else_node; // null, block node, or other if expr node
263};
264
265struct AstNodeWhileExpr {
266 AstNode *condition;
267 AstNode *body;
268};
269
270struct AstNodeLabel {
271 Buf name;
272};
273
274struct AstNodeGoto {
275 Buf name;
276};
277
278struct AsmOutput {
279 Buf asm_symbolic_name;
280 Buf constraint;
281 Buf variable_name;
282 AstNode *return_type; // null unless "=r" and return
283};
284
285struct AsmInput {
286 Buf asm_symbolic_name;
287 Buf constraint;
288 AstNode *expr;
289};
290
291struct SrcPos {
292 int line;
293 int column;
294};
295
296struct AstNodeAsmExpr {
297 bool is_volatile;
298 Buf asm_template;
299 ZigList<SrcPos> offset_map;
300 ZigList<AsmToken> token_list;
301 ZigList<AsmOutput*> output_list;
302 ZigList<AsmInput*> input_list;
303 ZigList<Buf*> clobber_list;
304 int return_count; // populated by analyze
305};
306
307struct AstNodeStructDecl {
308 Buf name;
309 ZigList<AstNode *> fields;
310 ZigList<AstNode *> fns;
311 ZigList<AstNode *> *directives;
312 VisibMod visib_mod;
313};
314
315struct AstNodeStructField {
316 Buf name;
317 AstNode *type;
318 ZigList<AstNode *> *directives;
319};
320
321struct AstNodeEnumDecl {
322 Buf name;
323 ZigList<AstNode *> fields;
324 ZigList<AstNode *> *directives;
325 VisibMod visib_mod;
326};
327
328struct AstNodeEnumField {
329 Buf name;
330 ZigList<AstNode *> fields; // length 0 means simple enum
331 AstNode *val_expr;
332};
333
334struct AstNodeStringLiteral {
335 Buf buf;
336 bool c;
337};
338
339struct AstNodeCharLiteral {
340 uint8_t value;
341};
342
343enum NumLit {
344 NumLitF32,
345 NumLitF64,
346 NumLitF128,
347 NumLitU8,
348 NumLitU16,
349 NumLitU32,
350 NumLitU64,
351 NumLitI8,
352 NumLitI16,
353 NumLitI32,
354 NumLitI64,
355
356 NumLitCount
357};
358
359struct AstNodeNumberLiteral {
360 NumLit kind;
361
362 // overflow is true if when parsing the number, we discovered it would not
363 // fit without losing data in a uint64_t, int64_t, or double
364 bool overflow;
365
366 union {
367 uint64_t x_uint;
368 int64_t x_int;
369 double x_float;
370 } data;
371};
372
373struct AstNodeStructValueField {
374 Buf name;
375 AstNode *expr;
376};
377
378struct AstNodeStructValueExpr {
379 AstNode *type;
380 ZigList<AstNode *> fields;
381};
382
383struct AstNodeCompilerFnExpr {
384 Buf name;
385 AstNode *expr;
386};
387
388struct AstNodeCompilerFnType {
389 Buf name;
390 AstNode *type;
391};
392
393struct AstNode {
394 enum NodeType type;
395 int line;
396 int column;
397 uint32_t create_index; // for determinism purposes
398 CodeGenNode *codegen_node;
399 ImportTableEntry *owner;
400 union {
401 AstNodeRoot root;
402 AstNodeRootExportDecl root_export_decl;
403 AstNodeFnDef fn_def;
404 AstNodeFnDecl fn_decl;
405 AstNodeFnProto fn_proto;
406 AstNodeType type;
407 AstNodeParamDecl param_decl;
408 AstNodeBlock block;
409 AstNodeReturnExpr return_expr;
410 AstNodeVariableDeclaration variable_declaration;
411 AstNodeBinOpExpr bin_op_expr;
412 AstNodeExternBlock extern_block;
413 AstNodeDirective directive;
414 AstNodeCastExpr cast_expr;
415 AstNodePrefixOpExpr prefix_op_expr;
416 AstNodeFnCallExpr fn_call_expr;
417 AstNodeArrayAccessExpr array_access_expr;
418 AstNodeSliceExpr slice_expr;
419 AstNodeUse use;
420 AstNodeIfBoolExpr if_bool_expr;
421 AstNodeIfVarExpr if_var_expr;
422 AstNodeWhileExpr while_expr;
423 AstNodeLabel label;
424 AstNodeGoto go_to;
425 AstNodeAsmExpr asm_expr;
426 AstNodeFieldAccessExpr field_access_expr;
427 AstNodeStructDecl struct_decl;
428 AstNodeStructField struct_field;
429 AstNodeEnumDecl enum_decl;
430 AstNodeEnumField enum_field;
431 AstNodeStringLiteral string_literal;
432 AstNodeCharLiteral char_literal;
433 AstNodeNumberLiteral number_literal;
434 AstNodeStructValueExpr struct_val_expr;
435 AstNodeStructValueField struct_val_field;
436 AstNodeCompilerFnExpr compiler_fn_expr;
437 AstNodeCompilerFnType compiler_fn_type;
438 Buf symbol;
439 bool bool_literal;
440 } data;
441};
442
443enum AsmTokenId {
444 AsmTokenIdTemplate,
445 AsmTokenIdPercent,
446 AsmTokenIdVar,
447};
448
449struct AsmToken {
450 enum AsmTokenId id;
451 int start;
452 int end;
453};
454
455__attribute__ ((format (printf, 2, 3)))15__attribute__ ((format (printf, 2, 3)))
456void ast_token_error(Token *token, const char *format, ...);16void ast_token_error(Token *token, const char *format, ...);
45717