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 @@
66 */
77
88#include "analyze.hpp"
9#include "parser.hpp"
910#include "error.hpp"
1011#include "zig_llvm.hpp"
1112#include "os.hpp"
......@@ -14,7 +15,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
1415 TypeTableEntry *expected_type, AstNode *node);
1516static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,
1617 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);
1819static VariableTableEntry *analyze_variable_declaration(CodeGen *g, ImportTableEntry *import,
1920 BlockContext *context, TypeTableEntry *expected_type, AstNode *node);
2021
......@@ -317,7 +318,7 @@ static TypeTableEntry *eval_const_expr_bin_op(CodeGen *g, BlockContext *context,
317318 out_number_literal->kind = NumLitU8;
318319 out_number_literal->overflow = false;
319320 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;
321322 } else {
322323 return g->builtin_types.entry_invalid;
323324 }
......@@ -330,7 +331,7 @@ static TypeTableEntry *eval_const_expr_bin_op(CodeGen *g, BlockContext *context,
330331 out_number_literal->kind = NumLitU8;
331332 out_number_literal->overflow = false;
332333 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;
334335 } else {
335336 return g->builtin_types.entry_invalid;
336337 }
......@@ -343,7 +344,7 @@ static TypeTableEntry *eval_const_expr_bin_op(CodeGen *g, BlockContext *context,
343344 out_number_literal->kind = NumLitU64;
344345 out_number_literal->overflow = false;
345346 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;
347348 } else {
348349 return g->builtin_types.entry_invalid;
349350 }
......@@ -390,20 +391,20 @@ static TypeTableEntry *eval_const_expr(CodeGen *g, BlockContext *context,
390391 switch (node->type) {
391392 case NodeTypeNumberLiteral:
392393 *out_number_literal = node->data.number_literal;
393 return node->codegen_node->expr_node.type_entry;
394 return get_resolved_expr(node)->type_entry;
394395 case NodeTypeBoolLiteral:
395 out_number_literal->data.x_uint = node->data.bool_literal ? 1 : 0;
396 return node->codegen_node->expr_node.type_entry;
396 out_number_literal->data.x_uint = node->data.bool_literal.value ? 1 : 0;
397 return get_resolved_expr(node)->type_entry;
397398 case NodeTypeNullLiteral:
398 return node->codegen_node->expr_node.type_entry;
399 return get_resolved_expr(node)->type_entry;
399400 case NodeTypeBinOpExpr:
400401 return eval_const_expr_bin_op(g, context, node, out_number_literal);
401402 case NodeTypeCompilerFnType:
402403 {
403404 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;
405406 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;
407408 out_number_literal->overflow = false;
408409 out_number_literal->data.x_uint = target_type->size_in_bits / 8;
409410 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,
420421 }
421422 case NodeTypeSymbol:
422423 {
423 VariableTableEntry *var = find_variable(context, &node->data.symbol);
424 VariableTableEntry *var = find_variable(context, &node->data.symbol_expr.symbol);
424425 assert(var);
425426 AstNode *decl_node = var->decl_node;
426427 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;
428429 return eval_const_expr(g, next_context, expr_node, out_number_literal);
429430 }
430431 default:
......@@ -436,8 +437,6 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry
436437 BlockContext *context, bool noalias_allowed)
437438{
438439 assert(node->type == NodeTypeType);
439 alloc_codegen_node(node);
440 TypeNode *type_node = &node->codegen_node->data.type_node;
441440 switch (node->data.type.type) {
442441 case AstNodeTypeTypePrimitive:
443442 {
......@@ -447,13 +446,13 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry
447446 table_entry = g->primitive_type_table.maybe_get(name);
448447 }
449448 if (table_entry) {
450 type_node->entry = table_entry->value;
449 node->data.type.entry = table_entry->value;
451450 } else {
452451 add_node_error(g, node,
453452 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;
455454 }
456 return type_node->entry;
455 return node->data.type.entry;
457456 }
458457 case AstNodeTypeTypePointer:
459458 {
......@@ -468,19 +467,19 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry
468467 }
469468
470469 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;
472471 assert(child_type);
473472 if (child_type->id == TypeTableEntryIdUnreachable) {
474473 add_node_error(g, node,
475474 buf_create_from_str("pointer to unreachable not allowed"));
476 type_node->entry = g->builtin_types.entry_invalid;
477 return type_node->entry;
475 node->data.type.entry = g->builtin_types.entry_invalid;
476 return node->data.type.entry;
478477 } else if (child_type->id == TypeTableEntryIdInvalid) {
479 type_node->entry = child_type;
478 node->data.type.entry = child_type;
480479 return child_type;
481480 } else {
482 type_node->entry = get_pointer_to_type(g, child_type, node->data.type.is_const, use_noalias);
483 return type_node->entry;
481 node->data.type.entry = get_pointer_to_type(g, child_type, node->data.type.is_const, use_noalias);
482 return node->data.type.entry;
484483 }
485484 }
486485 case AstNodeTypeTypeArray:
......@@ -501,16 +500,16 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry
501500 if (child_type->id == TypeTableEntryIdUnreachable) {
502501 add_node_error(g, node,
503502 buf_create_from_str("array of unreachable not allowed"));
504 type_node->entry = g->builtin_types.entry_invalid;
505 return type_node->entry;
503 node->data.type.entry = g->builtin_types.entry_invalid;
504 return node->data.type.entry;
506505 }
507506
508507 if (size_node) {
509508 TypeTableEntry *size_type = analyze_expression(g, import, context,
510509 g->builtin_types.entry_usize, size_node);
511510 if (size_type->id == TypeTableEntryIdInvalid) {
512 type_node->entry = g->builtin_types.entry_invalid;
513 return type_node->entry;
511 node->data.type.entry = g->builtin_types.entry_invalid;
512 return node->data.type.entry;
514513 }
515514
516515 AstNodeNumberLiteral number_literal;
......@@ -520,27 +519,27 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry
520519 if (resolved_type->data.integral.is_signed) {
521520 add_node_error(g, size_node,
522521 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;
524523 } 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);
526525 }
527526 } else {
528527 add_node_error(g, size_node,
529528 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;
531530 }
532 return type_node->entry;
531 return node->data.type.entry;
533532 } 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,
535534 node->data.type.is_const, use_noalias);
536 return type_node->entry;
535 return node->data.type.entry;
537536 }
538537
539538 }
540539 case AstNodeTypeTypeMaybe:
541540 {
542541 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;
544543 assert(child_type);
545544 if (child_type->id == TypeTableEntryIdUnreachable) {
546545 add_node_error(g, node,
......@@ -548,22 +547,22 @@ static TypeTableEntry *resolve_type(CodeGen *g, AstNode *node, ImportTableEntry
548547 } else if (child_type->id == TypeTableEntryIdInvalid) {
549548 return child_type;
550549 }
551 type_node->entry = get_maybe_type(g, import, child_type);
552 return type_node->entry;
550 node->data.type.entry = get_maybe_type(g, import, child_type);
551 return node->data.type.entry;
553552 }
554553 case AstNodeTypeTypeCompilerExpr:
555554 {
556555 AstNode *compiler_expr_node = node->data.type.compiler_expr;
557556 Buf *fn_name = &compiler_expr_node->data.compiler_fn_expr.name;
558557 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,
560559 compiler_expr_node->data.compiler_fn_expr.expr);
561560 } else {
562561 add_node_error(g, node,
563562 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;
565564 }
566 return type_node->entry;
565 return node->data.type.entry;
567566 }
568567 }
569568 zig_unreachable();
......@@ -631,8 +630,7 @@ static void preview_function_labels(CodeGen *g, AstNode *node, FnTableEntry *fn_
631630 Buf *name = &label_node->data.label.name;
632631 fn_table_entry->label_table.put(name, label_entry);
633632
634 alloc_codegen_node(label_node);
635 label_node->codegen_node->data.label_entry = label_entry;
633 label_node->data.label.label_entry = label_entry;
636634 }
637635}
638636
......@@ -732,7 +730,8 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
732730 AstNode *struct_node = proto_node->data.fn_proto.struct_node;
733731 TypeTableEntry *struct_type;
734732 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;
736735 } else {
737736 struct_type = nullptr;
738737 }
......@@ -749,13 +748,14 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
749748 if (entry) {
750749 add_node_error(g, proto_node,
751750 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;
753752 skip = true;
754753 } else if (is_pub) {
754 // TODO is this else if branch a mistake?
755755 auto entry = fn_table->maybe_get(proto_name);
756756 if (entry) {
757757 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;
759759 skip = true;
760760 }
761761 }
......@@ -804,7 +804,7 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
804804 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
809809 if (fn_def_node) {
810810 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
888888 break;
889889 case NodeTypeStructDecl:
890890 {
891 StructDeclNode *struct_codegen = &node->codegen_node->data.struct_decl_node;
892 TypeTableEntry *type_entry = struct_codegen->type_entry;
891 TypeTableEntry *type_entry = node->data.struct_decl.type_entry;
893892
894893 resolve_struct_type(g, import, type_entry);
895894
......@@ -962,8 +961,8 @@ static TypeTableEntry *get_return_type(BlockContext *context) {
962961 AstNode *fn_proto_node = fn_entry->proto_node;
963962 assert(fn_proto_node->type == NodeTypeFnProto);
964963 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
965 assert(return_type_node->codegen_node);
966 return return_type_node->codegen_node->data.type_node.entry;
964 assert(return_type_node->type == NodeTypeType);
965 return return_type_node->data.type.entry;
967966}
968967
969968static 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,
10031002 zig_unreachable();
10041003}
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,
10071006 TypeTableEntry *non_literal_type, AstNode *literal_node, TypeTableEntry *literal_type)
10081007{
1009 assert(literal_node->codegen_node);
1010 NumberLiteralNode *codegen_num_lit = &literal_node->codegen_node->data.num_lit_node;
1008 NumLitCodeGen *num_lit_codegen = get_resolved_num_lit(literal_node);
10111009
10121010 if (non_literal_type && num_lit_fits_in_other_type(g, literal_type, non_literal_type)) {
1013 assert(!codegen_num_lit->resolved_type);
1014 codegen_num_lit->resolved_type = non_literal_type;
1011 assert(!num_lit_codegen->resolved_type);
1012 num_lit_codegen->resolved_type = non_literal_type;
10151013 return non_literal_type;
10161014 } else {
10171015 return nullptr;
......@@ -1024,11 +1022,8 @@ static TypeTableEntry * resolve_number_literals(CodeGen *g, AstNode *node1, AstN
10241022 if (type1->id == TypeTableEntryIdNumberLiteral &&
10251023 type2->id == TypeTableEntryIdNumberLiteral)
10261024 {
1027 assert(node1->codegen_node);
1028 assert(node2->codegen_node);
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;
1025 NumLitCodeGen *codegen_num_lit_1 = get_resolved_num_lit(node1);
1026 NumLitCodeGen *codegen_num_lit_2 = get_resolved_num_lit(node2);
10321027
10331028 assert(!codegen_num_lit_1->resolved_type);
10341029 assert(!codegen_num_lit_2->resolved_type);
......@@ -1113,9 +1108,10 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
11131108 if (actual_type->id == TypeTableEntryIdNumberLiteral &&
11141109 num_lit_fits_in_other_type(g, actual_type, expected_type))
11151110 {
1116 assert(!node->codegen_node->data.num_lit_node.resolved_type ||
1117 node->codegen_node->data.num_lit_node.resolved_type == expected_type);
1118 node->codegen_node->data.num_lit_node.resolved_type = expected_type;
1111 NumLitCodeGen *num_lit_code_gen = get_resolved_num_lit(node);
1112 assert(!num_lit_code_gen->resolved_type ||
1113 num_lit_code_gen->resolved_type == expected_type);
1114 num_lit_code_gen->resolved_type = expected_type;
11191115 return expected_type;
11201116 }
11211117
......@@ -1134,10 +1130,11 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
11341130 if (resolved_type->id == TypeTableEntryIdInvalid) {
11351131 return resolved_type;
11361132 }
1137 node->codegen_node->expr_node.implicit_maybe_cast.op = CastOpMaybeWrap;
1138 node->codegen_node->expr_node.implicit_maybe_cast.after_type = expected_type;
1139 node->codegen_node->expr_node.implicit_maybe_cast.source_node = node;
1140 context->cast_expr_alloca_list.append(&node->codegen_node->expr_node.implicit_maybe_cast);
1133 Expr *expr = get_resolved_expr(node);
1134 expr->implicit_maybe_cast.op = CastOpMaybeWrap;
1135 expr->implicit_maybe_cast.after_type = expected_type;
1136 expr->implicit_maybe_cast.source_node = node;
1137 context->cast_expr_alloca_list.append(&expr->implicit_maybe_cast);
11411138 return expected_type;
11421139 }
11431140
......@@ -1147,9 +1144,10 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
11471144 expected_type->data.integral.is_signed == actual_type->data.integral.is_signed &&
11481145 expected_type->size_in_bits > actual_type->size_in_bits)
11491146 {
1150 node->codegen_node->expr_node.implicit_cast.after_type = expected_type;
1151 node->codegen_node->expr_node.implicit_cast.op = CastOpIntWidenOrShorten;
1152 node->codegen_node->expr_node.implicit_cast.source_node = node;
1147 Expr *expr = get_resolved_expr(node);
1148 expr->implicit_cast.after_type = expected_type;
1149 expr->implicit_cast.op = CastOpIntWidenOrShorten;
1150 expr->implicit_cast.source_node = node;
11531151 return expected_type;
11541152 }
11551153
......@@ -1159,10 +1157,11 @@ static TypeTableEntry *resolve_type_compatibility(CodeGen *g, BlockContext *cont
11591157 actual_type->id == TypeTableEntryIdArray &&
11601158 actual_type->data.array.child_type == expected_type->data.structure.fields[0].type_entry->data.pointer.child_type)
11611159 {
1162 node->codegen_node->expr_node.implicit_cast.after_type = expected_type;
1163 node->codegen_node->expr_node.implicit_cast.op = CastOpToUnknownSizeArray;
1164 node->codegen_node->expr_node.implicit_cast.source_node = node;
1165 context->cast_expr_alloca_list.append(&node->codegen_node->expr_node.implicit_cast);
1160 Expr *expr = get_resolved_expr(node);
1161 expr->implicit_cast.after_type = expected_type;
1162 expr->implicit_cast.op = CastOpToUnknownSizeArray;
1163 expr->implicit_cast.source_node = node;
1164 context->cast_expr_alloca_list.append(&expr->implicit_cast);
11661165 return expected_type;
11671166 }
11681167
......@@ -1225,7 +1224,7 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
12251224
12261225 if (node && node->type == NodeTypeFnDef) {
12271226 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;
12291228 } else if (parent) {
12301229 context->fn_entry = parent->fn_entry;
12311230 }
......@@ -1275,6 +1274,8 @@ static void get_struct_field(TypeTableEntry *struct_type, Buf *name, TypeStructF
12751274static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
12761275 AstNode *node)
12771276{
1277 assert(node->type == NodeTypeFieldAccessExpr);
1278
12781279 TypeTableEntry *struct_type = analyze_expression(g, import, context, nullptr,
12791280 node->data.field_access_expr.struct_expr);
12801281
......@@ -1283,20 +1284,16 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
12831284 if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer &&
12841285 struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct))
12851286 {
1286 assert(node->codegen_node);
1287 FieldAccessNode *codegen_field_access = &node->codegen_node->data.field_access_node;
1288 assert(codegen_field_access);
1289
12901287 Buf *field_name = &node->data.field_access_expr.field_name;
12911288
12921289 TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ?
12931290 struct_type : struct_type->data.pointer.child_type;
12941291
12951292 get_struct_field(bare_struct_type, field_name,
1296 &codegen_field_access->type_struct_field,
1297 &codegen_field_access->field_index);
1298 if (codegen_field_access->type_struct_field) {
1299 return_type = codegen_field_access->type_struct_field->type_entry;
1293 &node->data.field_access_expr.type_struct_field,
1294 &node->data.field_access_expr.field_index);
1295 if (node->data.field_access_expr.type_struct_field) {
1296 return_type = node->data.field_access_expr.type_struct_field->type_entry;
13001297 } else {
13011298 add_node_error(g, node,
13021299 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
13291326static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
13301327 AstNode *node)
13311328{
1329 assert(node->type == NodeTypeSliceExpr);
1330
13321331 TypeTableEntry *array_type = analyze_expression(g, import, context, nullptr,
13331332 node->data.slice_expr.array_ref_expr);
13341333
......@@ -1355,10 +1354,9 @@ static TypeTableEntry *analyze_slice_expr(CodeGen *g, ImportTableEntry *import,
13551354 }
13561355
13571356 if (return_type->id != TypeTableEntryIdInvalid) {
1358 assert(node->codegen_node);
1359 node->codegen_node->data.struct_val_expr_node.type_entry = return_type;
1360 node->codegen_node->data.struct_val_expr_node.source_node = node;
1361 context->struct_val_expr_alloca_list.append(&node->codegen_node->data.struct_val_expr_node);
1357 node->data.slice_expr.resolved_struct_val_expr.type_entry = return_type;
1358 node->data.slice_expr.resolved_struct_val_expr.source_node = node;
1359 context->struct_val_expr_alloca_list.append(&node->data.slice_expr.resolved_struct_val_expr);
13621360 }
13631361
13641362 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) {
14631461static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
14641462 TypeTableEntry *expected_type, AstNode *node)
14651463{
1464 assert(node->type == NodeTypeCastExpr);
1465
14661466 TypeTableEntry *wanted_type = resolve_type(g, node->data.cast_expr.type, import, context, false);
14671467 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
14721472 return g->builtin_types.entry_invalid;
14731473 }
14741474
1475 CastNode *cast_node = &node->codegen_node->data.cast_node;
1476 cast_node->source_node = node;
1477 cast_node->after_type = wanted_type;
1475 Cast *cast = &node->data.cast_expr.cast;
1476 cast->source_node = node;
1477 cast->after_type = wanted_type;
14781478
1479 // special casing this for now, TODO think about casting and do a general solution
14801479 if ((wanted_type == g->builtin_types.entry_isize || wanted_type == g->builtin_types.entry_usize) &&
14811480 actual_type->id == TypeTableEntryIdPointer)
14821481 {
1483 cast_node->op = CastOpPtrToInt;
1482 cast->op = CastOpPtrToInt;
14841483 return wanted_type;
14851484 } else if (wanted_type->id == TypeTableEntryIdInt &&
14861485 actual_type->id == TypeTableEntryIdInt)
14871486 {
1488 cast_node->op = CastOpIntWidenOrShorten;
1487 cast->op = CastOpIntWidenOrShorten;
14891488 return wanted_type;
14901489 } else if (wanted_type->id == TypeTableEntryIdStruct &&
14911490 wanted_type->data.structure.is_unknown_size_array &&
14921491 actual_type->id == TypeTableEntryIdArray &&
14931492 actual_type->data.array.child_type == wanted_type->data.structure.fields[0].type_entry)
14941493 {
1495 cast_node->op = CastOpToUnknownSizeArray;
1496 context->cast_expr_alloca_list.append(cast_node);
1494 cast->op = CastOpToUnknownSizeArray;
1495 context->cast_expr_alloca_list.append(cast);
14971496 return wanted_type;
14981497 } else if (actual_type->id == TypeTableEntryIdNumberLiteral &&
14991498 num_lit_fits_in_other_type(g, actual_type, wanted_type))
15001499 {
15011500 AstNode *literal_node = node->data.cast_expr.expr;
1502 assert(literal_node->codegen_node);
1503 NumberLiteralNode *codegen_num_lit = &literal_node->codegen_node->data.num_lit_node;
1501 NumLitCodeGen *codegen_num_lit = get_resolved_num_lit(literal_node);
15041502 assert(!codegen_num_lit->resolved_type);
15051503 codegen_num_lit->resolved_type = wanted_type;
1506 cast_node->op = CastOpNothing;
1504 cast->op = CastOpNothing;
15071505 return wanted_type;
15081506 } else if (actual_type->id == TypeTableEntryIdPointer &&
15091507 wanted_type->id == TypeTableEntryIdPointer)
15101508 {
1511 cast_node->op = CastOpPointerReinterpret;
1509 cast->op = CastOpPointerReinterpret;
15121510 return wanted_type;
15131511 } else {
15141512 add_node_error(g, node,
......@@ -1529,7 +1527,7 @@ static TypeTableEntry *analyze_lvalue(CodeGen *g, ImportTableEntry *import, Bloc
15291527{
15301528 TypeTableEntry *expected_rhs_type = nullptr;
15311529 if (lhs_node->type == NodeTypeSymbol) {
1532 Buf *name = &lhs_node->data.symbol;
1530 Buf *name = &lhs_node->data.symbol_expr.symbol;
15331531 VariableTableEntry *var = find_variable(block_context, name);
15341532 if (var) {
15351533 if (purpose == LValPurposeAssign && var->is_const) {
......@@ -1551,7 +1549,6 @@ static TypeTableEntry *analyze_lvalue(CodeGen *g, ImportTableEntry *import, Bloc
15511549 } else if (lhs_node->type == NodeTypeArrayAccessExpr) {
15521550 expected_rhs_type = analyze_array_access_expr(g, import, block_context, lhs_node);
15531551 } else if (lhs_node->type == NodeTypeFieldAccessExpr) {
1554 alloc_codegen_node(lhs_node);
15551552 expected_rhs_type = analyze_field_access_expr(g, import, block_context, lhs_node);
15561553 } else if (lhs_node->type == NodeTypePrefixOpExpr &&
15571554 lhs_node->data.prefix_op_expr.prefix_op == PrefixOpDereference)
......@@ -1774,10 +1771,9 @@ static TypeTableEntry *analyze_null_literal_expr(CodeGen *g, ImportTableEntry *i
17741771 if (expected_type) {
17751772 assert(expected_type->id == TypeTableEntryIdMaybe);
17761773
1777 assert(node->codegen_node);
1778 node->codegen_node->data.struct_val_expr_node.type_entry = expected_type;
1779 node->codegen_node->data.struct_val_expr_node.source_node = node;
1780 block_context->struct_val_expr_alloca_list.append(&node->codegen_node->data.struct_val_expr_node);
1774 node->data.null_literal.resolved_struct_val_expr.type_entry = expected_type;
1775 node->data.null_literal.resolved_struct_val_expr.source_node = node;
1776 block_context->struct_val_expr_alloca_list.append(&node->data.null_literal.resolved_struct_val_expr);
17811777
17821778 return expected_type;
17831779 } else {
......@@ -1796,7 +1792,7 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry
17961792 buf_sprintf("number literal too large to be represented in any type"));
17971793 return g->builtin_types.entry_invalid;
17981794 } 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);
18001796 assert(!codegen_num_lit->resolved_type);
18011797 TypeTableEntry *after_implicit_cast_resolved_type =
18021798 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
18371833 return g->builtin_types.entry_invalid;
18381834 }
18391835
1840 assert(node->codegen_node);
1841 node->codegen_node->data.struct_val_expr_node.type_entry = type_entry;
1842 node->codegen_node->data.struct_val_expr_node.source_node = node;
1843 context->struct_val_expr_alloca_list.append(&node->codegen_node->data.struct_val_expr_node);
1836 node->data.struct_val_expr.codegen.type_entry = type_entry;
1837 node->data.struct_val_expr.codegen.source_node = node;
1838 context->struct_val_expr_alloca_list.append(&node->data.struct_val_expr.codegen);
18441839
18451840 int expr_field_count = struct_val_expr->fields.length;
18461841 int actual_field_count = type_entry->data.structure.field_count;
......@@ -1848,6 +1843,8 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp
18481843 int *field_use_counts = allocate<int>(actual_field_count);
18491844 for (int i = 0; i < expr_field_count; i += 1) {
18501845 AstNode *val_field_node = struct_val_expr->fields.at(i);
1846 assert(val_field_node->type == NodeTypeStructValueField);
1847
18511848 int field_index;
18521849 TypeStructField *type_field = find_struct_type_field(type_entry,
18531850 &val_field_node->data.struct_val_field.name, &field_index);
......@@ -1865,8 +1862,7 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp
18651862 continue;
18661863 }
18671864
1868 alloc_codegen_node(val_field_node);
1869 val_field_node->codegen_node->data.struct_val_field_node.index = field_index;
1865 val_field_node->data.struct_val_field.index = field_index;
18701866
18711867 analyze_expression(g, import, context, type_field->type_entry,
18721868 val_field_node->data.struct_val_field.expr);
......@@ -1885,6 +1881,8 @@ static TypeTableEntry *analyze_struct_val_expr(CodeGen *g, ImportTableEntry *imp
18851881static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
18861882 TypeTableEntry *expected_type, AstNode *node)
18871883{
1884 assert(node->type == NodeTypeWhileExpr);
1885
18881886 AstNode *condition_node = node->data.while_expr.condition;
18891887 AstNode *while_body_node = node->data.while_expr.body;
18901888 TypeTableEntry *condition_type = analyze_expression(g, import, context,
......@@ -1907,8 +1905,8 @@ static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import,
19071905 assert(resolved_type->id == TypeTableEntryIdBool);
19081906 bool constant_cond_value = number_literal.data.x_uint;
19091907 if (constant_cond_value) {
1910 node->codegen_node->data.while_node.condition_always_true = true;
1911 if (!node->codegen_node->data.while_node.contains_break) {
1908 node->data.while_expr.condition_always_true = true;
1909 if (!node->data.while_expr.contains_break) {
19121910 expr_return_type = g->builtin_types.entry_unreachable;
19131911 }
19141912 }
......@@ -1921,12 +1919,14 @@ static TypeTableEntry *analyze_while_expr(CodeGen *g, ImportTableEntry *import,
19211919static TypeTableEntry *analyze_break_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
19221920 TypeTableEntry *expected_type, AstNode *node)
19231921{
1922 assert(node->type == NodeTypeBreak);
1923
19241924 AstNode *loop_node = context->parent_loop_node;
19251925 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;
19271928 } else {
1928 add_node_error(g, node,
1929 buf_sprintf("'break' expression outside loop"));
1929 add_node_error(g, node, buf_sprintf("'break' expression outside loop"));
19301930 }
19311931 return g->builtin_types.entry_unreachable;
19321932}
......@@ -1935,8 +1935,7 @@ static TypeTableEntry *analyze_continue_expr(CodeGen *g, ImportTableEntry *impor
19351935 TypeTableEntry *expected_type, AstNode *node)
19361936{
19371937 if (!context->parent_loop_node) {
1938 add_node_error(g, node,
1939 buf_sprintf("'continue' expression outside loop"));
1938 add_node_error(g, node, buf_sprintf("'continue' expression outside loop"));
19401939 }
19411940 return g->builtin_types.entry_unreachable;
19421941}
......@@ -1981,7 +1980,7 @@ static TypeTableEntry *analyze_if_var_expr(CodeGen *g, ImportTableEntry *import,
19811980 assert(node->type == NodeTypeIfVarExpr);
19821981
19831982 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
19861985 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
20322031static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
20332032 TypeTableEntry *expected_type, AstNode *node)
20342033{
2034 assert(node->type == NodeTypeFnCallExpr);
2035
20352036 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
20382039 auto entry = g->builtin_fn_table.maybe_get(name);
20392040
......@@ -2041,8 +2042,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
20412042 BuiltinFnEntry *builtin_fn = entry->value;
20422043 int actual_param_count = node->data.fn_call_expr.params.length;
20432044
2044 assert(node->codegen_node);
2045 node->codegen_node->data.fn_call_node.builtin_fn = builtin_fn;
2045 node->data.fn_call_expr.builtin_fn = builtin_fn;
20462046
20472047 if (builtin_fn->param_count != actual_param_count) {
20482048 add_node_error(g, node,
......@@ -2155,7 +2155,7 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
21552155 if (node->data.fn_call_expr.is_builtin) {
21562156 return analyze_builtin_fn_call_expr(g, import, context, expected_type, node);
21572157 }
2158 name = &fn_ref_expr->data.symbol;
2158 name = &fn_ref_expr->data.symbol_expr.symbol;
21592159 } else {
21602160 add_node_error(g, node,
21612161 buf_sprintf("function pointers not yet supported"));
......@@ -2210,13 +2210,15 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
22102210 AstNode *param_decl_node = fn_proto->params.at(fn_proto_i);
22112211 assert(param_decl_node->type == NodeTypeParamDecl);
22122212 AstNode *param_type_node = param_decl_node->data.param_decl.type;
2213 if (param_type_node->codegen_node)
2214 expected_param_type = param_type_node->codegen_node->data.type_node.entry;
2213 assert(param_type_node->type == NodeTypeType);
2214 if (param_type_node->data.type.entry) {
2215 expected_param_type = param_type_node->data.type.entry;
2216 }
22152217 }
22162218 analyze_expression(g, import, context, expected_param_type, child);
22172219 }
22182220
2219 return fn_proto->return_type->codegen_node->data.type_node.entry;
2221 return fn_proto->return_type->data.type.entry;
22202222 }
22212223}
22222224
......@@ -2224,18 +2226,17 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
22242226 TypeTableEntry *expected_type, AstNode *node)
22252227{
22262228 TypeTableEntry *return_type = nullptr;
2227 alloc_codegen_node(node);
22282229 switch (node->type) {
22292230 case NodeTypeBlock:
22302231 {
22312232 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;
22332234 return_type = g->builtin_types.entry_void;
22342235
22352236 for (int i = 0; i < node->data.block.statements.length; i += 1) {
22362237 AstNode *child = node->data.block.statements.at(i);
22372238 if (child->type == NodeTypeLabel) {
2238 LabelTableEntry *label_entry = child->codegen_node->data.label_entry;
2239 LabelTableEntry *label_entry = child->data.label.label_entry;
22392240 assert(label_entry);
22402241 label_entry->entered_from_fallthrough = (return_type->id != TypeTableEntryIdUnreachable);
22412242 return_type = g->builtin_types.entry_void;
......@@ -2288,13 +2289,13 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
22882289 case NodeTypeGoto:
22892290 {
22902291 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);
22922293 if (table_entry) {
2293 node->codegen_node->data.label_entry = table_entry->value;
2294 node->data.goto_expr.label_entry = table_entry->value;
22942295 table_entry->value->used = true;
22952296 } else {
22962297 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)));
22982299 }
22992300 return_type = g->builtin_types.entry_unreachable;
23002301 break;
......@@ -2380,7 +2381,7 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
23802381
23812382 case NodeTypeSymbol:
23822383 {
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);
23842385 break;
23852386 }
23862387 case NodeTypeCastExpr:
......@@ -2507,8 +2508,8 @@ static TypeTableEntry * analyze_expression(CodeGen *g, ImportTableEntry *import,
25072508 assert(return_type);
25082509 resolve_type_compatibility(g, context, node, expected_type, return_type);
25092510
2510 node->codegen_node->expr_node.type_entry = return_type;
2511 node->codegen_node->expr_node.block_context = context;
2511 get_resolved_expr(node)->type_entry = return_type;
2512 get_resolved_expr(node)->block_context = context;
25122513
25132514 return return_type;
25142515}
......@@ -2519,15 +2520,14 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo
25192520 AstNode *fn_proto_node = node->data.fn_def.fn_proto;
25202521 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) {
25232524 // we detected an error with this function definition which prevents us
25242525 // from further analyzing it.
25252526 return;
25262527 }
25272528
2528 alloc_codegen_node(node);
25292529 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
25322532 AstNodeFnProto *fn_proto = &fn_proto_node->data.fn_proto;
25332533 bool is_exported = (fn_proto->visib_mod == VisibModExport);
......@@ -2538,7 +2538,7 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo
25382538 // define local variables for parameters
25392539 AstNodeParamDecl *param_decl = &param_decl_node->data.param_decl;
25402540 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
25432543 if (is_exported && type->id == TypeTableEntryIdStruct) {
25442544 add_node_error(g, param_decl_node,
......@@ -2552,8 +2552,7 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo
25522552 variable_entry->decl_node = param_decl_node;
25532553 variable_entry->arg_index = i;
25542554
2555 alloc_codegen_node(param_decl_node);
2556 param_decl_node->codegen_node->data.param_decl_node.variable = variable_entry;
2555 param_decl_node->data.param_decl.variable = variable_entry;
25572556
25582557 VariableTableEntry *existing_entry = find_local_variable(context, &variable_entry->name);
25592558 if (!existing_entry) {
......@@ -2571,13 +2570,13 @@ static void analyze_top_level_fn_def(CodeGen *g, ImportTableEntry *import, AstNo
25712570 }
25722571 }
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;
25752574 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
25792578 {
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;
25812580 auto it = fn_table_entry->label_table.entry_iterator();
25822581 for (;;) {
25832582 auto *entry = it.next();
......@@ -2656,7 +2655,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode
26562655}
26572656
26582657static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *expr_node,
2659 DeclNode *decl_node)
2658 TopLevelDecl *decl_node)
26602659{
26612660 switch (expr_node->type) {
26622661 case NodeTypeNumberLiteral:
......@@ -2672,7 +2671,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode
26722671 // no dependencies on other top level declarations
26732672 break;
26742673 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);
26762675 break;
26772676 case NodeTypeBinOpExpr:
26782677 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
27872786 }
27882787}
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) {
27912790 assert(type_node->type == NodeTypeType);
27922791 switch (type_node->data.type.type) {
27932792 case AstNodeTypeTypePrimitive:
......@@ -2824,16 +2823,13 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
28242823 switch (node->type) {
28252824 case NodeTypeStructDecl:
28262825 {
2827 alloc_codegen_node(node);
2828 StructDeclNode *struct_codegen = &node->codegen_node->data.struct_decl_node;
2829
28302826 Buf *name = &node->data.struct_decl.name;
28312827 auto table_entry = g->primitive_type_table.maybe_get(name);
28322828 if (!table_entry) {
28332829 table_entry = import->type_table.maybe_get(name);
28342830 }
28352831 if (table_entry) {
2836 struct_codegen->type_entry = table_entry->value;
2832 node->data.struct_decl.type_entry = table_entry->value;
28372833 add_node_error(g, node,
28382834 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
28392835 } else {
......@@ -2848,7 +2844,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
28482844 // put off adding the debug type until we do the full struct body
28492845 // this type is incomplete until we do another pass
28502846 import->type_table.put(&entry->name, entry);
2851 struct_codegen->type_entry = entry;
2847 node->data.struct_decl.type_entry = entry;
28522848
28532849 bool is_pub = (node->data.struct_decl.visib_mod != VisibModPrivate);
28542850 if (is_pub) {
......@@ -2867,14 +2863,15 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
28672863 }
28682864
28692865 // 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);
28712868 for (int i = 0; i < node->data.struct_decl.fields.length; i += 1) {
28722869 AstNode *field_node = node->data.struct_decl.fields.at(i);
28732870 AstNode *type_node = field_node->data.struct_field.type;
28742871 collect_type_decl_deps(g, import, type_node, decl_node);
28752872 }
2876 node->codegen_node->decl_node.name = name;
2877 node->codegen_node->decl_node.import = import;
2873 decl_node->name = name;
2874 decl_node->import = import;
28782875 if (decl_node->deps.size() > 0) {
28792876 g->unresolved_top_level_decls.put(name, node);
28802877 } else {
......@@ -2913,8 +2910,8 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
29132910 case NodeTypeVariableDeclaration:
29142911 {
29152912 // determine which other top level declarations this variable declaration depends on.
2916 alloc_codegen_node(node);
2917 DeclNode *decl_node = &node->codegen_node->decl_node;
2913 TopLevelDecl *decl_node = &node->data.variable_declaration.top_level_decl;
2914 decl_node->deps.init(1);
29182915 if (node->data.variable_declaration.type) {
29192916 collect_type_decl_deps(g, import, node->data.variable_declaration.type, decl_node);
29202917 }
......@@ -2922,8 +2919,8 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
29222919 collect_expr_decl_deps(g, import, node->data.variable_declaration.expr, decl_node);
29232920 }
29242921 Buf *name = &node->data.variable_declaration.symbol;
2925 node->codegen_node->decl_node.name = name;
2926 node->codegen_node->decl_node.import = import;
2922 decl_node->name = name;
2923 decl_node->import = import;
29272924 if (decl_node->deps.size() > 0) {
29282925 g->unresolved_top_level_decls.put(name, node);
29292926 } else {
......@@ -2934,8 +2931,8 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
29342931 case NodeTypeFnProto:
29352932 {
29362933 // determine which other top level declarations this function prototype depends on.
2937 alloc_codegen_node(node);
2938 DeclNode *decl_node = &node->codegen_node->decl_node;
2934 TopLevelDecl *decl_node = &node->data.fn_proto.top_level_decl;
2935 decl_node->deps.init(1);
29392936 for (int i = 0; i < node->data.fn_proto.params.length; i += 1) {
29402937 AstNode *param_node = node->data.fn_proto.params.at(i);
29412938 assert(param_node->type == NodeTypeParamDecl);
......@@ -2943,8 +2940,8 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
29432940 }
29442941
29452942 Buf *name = &node->data.fn_proto.name;
2946 node->codegen_node->decl_node.name = name;
2947 node->codegen_node->decl_node.import = import;
2943 decl_node->name = name;
2944 decl_node->import = import;
29482945 if (decl_node->deps.size() > 0) {
29492946 g->unresolved_top_level_decls.put(name, node);
29502947 } else {
......@@ -2999,7 +2996,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
29992996}
30002997
30012998static 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();
30033000 for (;;) {
30043001 auto *entry = it.next();
30053002 if (!entry)
......@@ -3012,23 +3009,24 @@ static void recursive_resolve_decl(CodeGen *g, ImportTableEntry *import, AstNode
30123009
30133010 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) {
30163013 // dependency loop. we'll let the fact that it's not in the respective
30173014 // table cause an error in resolve_top_level_decl.
30183015 continue;
30193016 }
30203017
30213018 // 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
30263024 // unset temporary flag
3027 child_node->codegen_node->decl_node.in_current_deps = false;
3025 top_level_decl->in_current_deps = false;
30283026 }
30293027
30303028 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);
30323030}
30333031
30343032static 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
30513049
30523050 }
30533051 // 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
30583057 // unset temporary flag
3059 decl_node->codegen_node->decl_node.in_current_deps = false;
3058 top_level_decl->in_current_deps = false;
30603059 }
30613060}
30623061
......@@ -3089,7 +3088,7 @@ void semantic_analyze(CodeGen *g) {
30893088 buf_sprintf("invalid directive: '%s'", buf_ptr(name)));
30903089 }
30913090
3092 ImportTableEntry *target_import = child->codegen_node->data.import_node.import;
3091 ImportTableEntry *target_import = child->data.use.import;
30933092 assert(target_import);
30943093
30953094 target_import->importers.append({import, child});
......@@ -3144,9 +3143,186 @@ void semantic_analyze(CodeGen *g) {
31443143 }
31453144}
31463145
3147void alloc_codegen_node(AstNode *node) {
3148 assert(!node->codegen_node);
3149 node->codegen_node = allocate<CodeGenNode>(1);
3150 node->codegen_node->decl_node.deps.init(1);
3146Expr *get_resolved_expr(AstNode *node) {
3147 switch (node->type) {
3148 case NodeTypeReturnExpr:
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 }
31513275}
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 @@
88#ifndef ZIG_ANALYZE_HPP
99#define ZIG_ANALYZE_HPP
1010
11#include "codegen.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};
11#include "all_types.hpp"
41212
41313void semantic_analyze(CodeGen *g);
41414void add_node_error(CodeGen *g, AstNode *node, Buf *msg);
415void alloc_codegen_node(AstNode *node);
41615TypeTableEntry *new_type_table_entry(TypeTableEntryId id);
41716TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const, bool is_noalias);
41817VariableTableEntry *find_variable(BlockContext *context, Buf *name);
41918BlockContext *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
42123#endif
src/codegen.cpp+50-61
......@@ -75,9 +75,7 @@ static LLVMValueRef gen_assign_raw(CodeGen *g, AstNode *source_node, BinOpType b
7575
7676static TypeTableEntry *get_type_for_type_node(CodeGen *g, AstNode *type_node) {
7777 assert(type_node->type == NodeTypeType);
78 assert(type_node->codegen_node);
79 assert(type_node->codegen_node->data.type_node.entry);
80 return type_node->codegen_node->data.type_node.entry;
78 return type_node->data.type.entry;
8179}
8280
8381static 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) {
138136}
139137
140138static TypeTableEntry *get_expr_type(AstNode *node) {
141 TypeTableEntry *cast_type = node->codegen_node->expr_node.implicit_cast.after_type;
142 return cast_type ? cast_type : node->codegen_node->expr_node.type_entry;
139 Expr *expr = get_resolved_expr(node);
140 TypeTableEntry *cast_type = expr->implicit_cast.after_type;
141 return cast_type ? cast_type : expr->type_entry;
143142}
144143
145144static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
146145 assert(node->type == NodeTypeFnCallExpr);
147146 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
148147 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
151150 switch (builtin_fn->id) {
152151 case BuiltinFnIdInvalid:
......@@ -265,7 +264,7 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
265264 // Assume that the expression evaluates to a simple name and return the buf
266265 // TODO after we support function pointers we can make this generic
267266 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
270269 struct_type = nullptr;
271270 first_param_expr = nullptr;
......@@ -388,8 +387,8 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou
388387
389388 LLVMValueRef struct_ptr;
390389 if (struct_expr_node->type == NodeTypeSymbol) {
391 VariableTableEntry *var = find_variable(struct_expr_node->codegen_node->expr_node.block_context,
392 &struct_expr_node->data.symbol);
390 VariableTableEntry *var = find_variable(get_resolved_expr(struct_expr_node)->block_context,
391 &struct_expr_node->data.symbol_expr.symbol);
393392 assert(var);
394393
395394 if (var->is_ptr && var->type->id == TypeTableEntryIdPointer) {
......@@ -413,14 +412,12 @@ static LLVMValueRef gen_field_ptr(CodeGen *g, AstNode *node, TypeTableEntry **ou
413412 assert(LLVMGetTypeKind(LLVMTypeOf(struct_ptr)) == LLVMPointerTypeKind);
414413 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);
419
420 *out_type_entry = codegen_field_access->type_struct_field->type_entry;
417 *out_type_entry = node->data.field_access_expr.type_struct_field->type_entry;
421418
422419 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, "");
424421}
425422
426423static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {
......@@ -429,7 +426,7 @@ static LLVMValueRef gen_slice_expr(CodeGen *g, AstNode *node) {
429426 AstNode *array_ref_node = node->data.slice_expr.array_ref_expr;
430427 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;
433430 LLVMValueRef array_ptr = gen_array_base_ptr(g, array_ref_node);
434431
435432 if (array_type->id == TypeTableEntryIdArray) {
......@@ -545,8 +542,8 @@ static LLVMValueRef gen_lvalue(CodeGen *g, AstNode *expr_node, AstNode *node,
545542 LLVMValueRef target_ref;
546543
547544 if (node->type == NodeTypeSymbol) {
548 VariableTableEntry *var = find_variable(expr_node->codegen_node->expr_node.block_context,
549 &node->data.symbol);
545 VariableTableEntry *var = find_variable(get_resolved_expr(expr_node)->block_context,
546 &node->data.symbol_expr.symbol);
550547 assert(var);
551548 // semantic checking ensures no variables are constant
552549 assert(!var->is_const);
......@@ -630,7 +627,7 @@ static LLVMValueRef gen_prefix_op_expr(CodeGen *g, AstNode *node) {
630627}
631628
632629static 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)
634631{
635632 switch (cast_node->op) {
636633 case CastOpNothing:
......@@ -705,7 +702,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
705702 TypeTableEntry *actual_type = get_expr_type(node->data.cast_expr.expr);
706703 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
710707 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) {
12181215 assert(node->data.if_var_expr.var_decl.expr);
12191216
12201217 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
12231220 LLVMValueRef init_val;
12241221 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
12421239 assert(block_node->type == NodeTypeBlock);
12431240
12441241 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
12471244 LLVMValueRef return_value;
12481245 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) {
13471344
13481345 if (!is_return) {
13491346 VariableTableEntry *variable = find_variable(
1350 node->codegen_node->expr_node.block_context,
1347 get_resolved_expr(node)->block_context,
13511348 &asm_output->variable_name);
13521349 assert(variable);
13531350 param_types[param_index] = LLVMTypeOf(variable->value_ref);
......@@ -1396,7 +1393,7 @@ static LLVMValueRef gen_null_literal(CodeGen *g, AstNode *node) {
13961393 TypeTableEntry *type_entry = get_expr_type(node);
13971394 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
14011398 add_debug_source_node(g, node);
14021399 LLVMValueRef field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 1, "");
......@@ -1416,12 +1413,13 @@ static LLVMValueRef gen_struct_val_expr(CodeGen *g, AstNode *node) {
14161413 int field_count = type_entry->data.structure.field_count;
14171414 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;
14201417 LLVMValueRef tmp_struct_ptr = struct_val_expr_node->ptr;
14211418
14221419 for (int i = 0; i < field_count; i += 1) {
14231420 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;
14251423 TypeStructField *type_struct_field = &type_entry->data.structure.fields[index];
14261424 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) {
14391437 assert(node->data.while_expr.condition);
14401438 assert(node->data.while_expr.body);
14411439
1442 bool condition_always_true = node->codegen_node->data.while_node.condition_always_true;
1443 bool contains_break = node->codegen_node->data.while_node.contains_break;
1440 bool condition_always_true = node->data.while_expr.condition_always_true;
1441 bool contains_break = node->data.while_expr.contains_break;
14441442 if (condition_always_true) {
14451443 // generate a forever loop
14461444
......@@ -1559,17 +1557,17 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
15591557static LLVMValueRef gen_var_decl_expr(CodeGen *g, AstNode *node) {
15601558 LLVMValueRef init_val;
15611559 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);
15631561}
15641562
15651563static 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)
15671565{
15681566 TypeTableEntry *type_entry = codegen_num_lit->resolved_type;
15691567 assert(type_entry);
15701568
15711569 // 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
15741572 if (type_entry->id == TypeTableEntryIdInt) {
15751573 // 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) {
15941592 Buf *name = &node->data.compiler_fn_type.name;
15951593 TypeTableEntry *type_entry = get_type_for_type_node(g, node->data.compiler_fn_type.type);
15961594 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);
15981596 AstNodeNumberLiteral num_lit_node;
15991597 num_lit_node.kind = type_entry->data.num_lit.kind;
16001598 num_lit_node.overflow = false;
......@@ -1632,7 +1630,7 @@ static LLVMValueRef gen_compiler_fn_type(CodeGen *g, AstNode *node) {
16321630static LLVMValueRef gen_number_literal(CodeGen *g, AstNode *node) {
16331631 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);
16361634 assert(codegen_num_lit);
16371635
16381636 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) {
16641662 case NodeTypeVoid:
16651663 return nullptr;
16661664 case NodeTypeBoolLiteral:
1667 if (node->data.bool_literal)
1665 if (node->data.bool_literal.value)
16681666 return LLVMConstAllOnes(LLVMInt1Type());
16691667 else
16701668 return LLVMConstNull(LLVMInt1Type());
......@@ -1696,8 +1694,8 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {
16961694 case NodeTypeSymbol:
16971695 {
16981696 VariableTableEntry *variable = find_variable(
1699 node->codegen_node->expr_node.block_context,
1700 &node->data.symbol);
1697 get_resolved_expr(node)->block_context,
1698 &node->data.symbol_expr.symbol);
17011699 assert(variable);
17021700 if (variable->type->id == TypeTableEntryIdVoid) {
17031701 return nullptr;
......@@ -1721,14 +1719,14 @@ static LLVMValueRef gen_expr_no_cast(CodeGen *g, AstNode *node) {
17211719 return gen_block(g, node, nullptr);
17221720 case NodeTypeGoto:
17231721 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);
17251723 case NodeTypeBreak:
17261724 return gen_break(g, node);
17271725 case NodeTypeContinue:
17281726 return gen_continue(g, node);
17291727 case NodeTypeLabel:
17301728 {
1731 LabelTableEntry *label_entry = node->codegen_node->data.label_entry;
1729 LabelTableEntry *label_entry = node->data.label.label_entry;
17321730 assert(label_entry);
17331731 LLVMBasicBlockRef basic_block = label_entry->basic_block;
17341732 if (label_entry->entered_from_fallthrough) {
......@@ -1770,19 +1768,19 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
17701768 return val;
17711769 }
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;
17761774 if (before_type && before_type->id == TypeTableEntryIdUnreachable) {
17771775 return val;
17781776 }
1779 CastNode *cast_node = &node->codegen_node->expr_node.implicit_cast;
1777 Cast *cast_node = &expr->implicit_cast;
17801778 if (cast_node->after_type) {
17811779 val = gen_bare_cast(g, node, val, before_type, cast_node->after_type, cast_node);
17821780 before_type = cast_node->after_type;
17831781 }
17841782
1785 cast_node = &node->codegen_node->expr_node.implicit_maybe_cast;
1783 cast_node = &expr->implicit_maybe_cast;
17861784 if (cast_node->after_type) {
17871785 val = gen_bare_cast(g, node, val, before_type, cast_node->after_type, cast_node);
17881786 }
......@@ -1798,7 +1796,7 @@ static void build_label_blocks(CodeGen *g, AstNode *block_node) {
17981796 continue;
17991797
18001798 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(
18021800 g->cur_fn->fn_value, buf_ptr(name));
18031801 }
18041802
......@@ -1944,13 +1942,7 @@ static void do_code_gen(CodeGen *g) {
19441942 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn, "entry");
19451943 LLVMPositionBuilderAtEnd(g->builder, entry_block);
19461944
1947 CodeGenNode *codegen_node = fn_def_node->codegen_node;
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);
1945 fn_def_node->data.fn_def.block_context->di_scope = LLVMZigSubprogramToScope(subprogram);
19541946
19551947 int non_void_param_count = count_non_void_params(g, &fn_proto->params);
19561948 assert(non_void_param_count == (int)LLVMCountParams(fn));
......@@ -1963,7 +1955,7 @@ static void do_code_gen(CodeGen *g) {
19631955 assert(param_decl->type == NodeTypeParamDecl);
19641956 if (is_param_decl_type_void(g, param_decl))
19651957 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);
19671959 parameter_variable->value_ref = params[non_void_index];
19681960 non_void_index += 1;
19691961 }
......@@ -2019,14 +2011,14 @@ static void do_code_gen(CodeGen *g) {
20192011
20202012 // allocate structs which are the result of casts
20212013 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);
20232015 add_debug_source_node(g, cast_node->source_node);
20242016 cast_node->ptr = LLVMBuildAlloca(g->builder, cast_node->after_type->type_ref, "");
20252017 }
20262018
20272019 // allocate structs which are struct value expressions
20282020 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);
20302022 add_debug_source_node(g, struct_val_expr_node->source_node);
20312023 struct_val_expr_node->ptr = LLVMBuildAlloca(g->builder,
20322024 struct_val_expr_node->type_entry->type_ref, "");
......@@ -2041,15 +2033,15 @@ static void do_code_gen(CodeGen *g) {
20412033 if (is_param_decl_type_void(g, param_decl))
20422034 continue;
20432035
2044 VariableTableEntry *variable = param_decl->codegen_node->data.param_decl_node.variable;
2036 VariableTableEntry *variable = param_decl->data.param_decl.variable;
20452037
20462038 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);
20482040 LLVMZigInsertDeclareAtEnd(g->dbuilder, variable->value_ref, variable->di_loc_var, debug_loc,
20492041 entry_block);
20502042 }
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;
20532045 gen_block(g, fn_def_node->data.fn_def.body, implicit_return_type);
20542046
20552047 }
......@@ -2549,8 +2541,6 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
25492541 Buf *import_code = buf_alloc();
25502542 bool found_it = false;
25512543
2552 alloc_codegen_node(top_level_decl);
2553
25542544 for (int path_i = 0; path_i < g->lib_search_paths.length; path_i += 1) {
25552545 Buf *search_path = g->lib_search_paths.at(path_i);
25562546 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,
25702560 auto entry = g->import_table.maybe_get(abs_full_path);
25712561 if (entry) {
25722562 found_it = true;
2573 top_level_decl->codegen_node->data.import_node.import = entry->value;
2563 top_level_decl->data.use.import = entry->value;
25742564 } else {
25752565 if ((err = os_fetch_file_path(abs_full_path, import_code))) {
25762566 if (err == ErrorFileNotFound) {
......@@ -2582,7 +2572,7 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *abs_full_path,
25822572 goto done_looking_at_imports;
25832573 }
25842574 }
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,
25862576 abs_full_path, search_path, &top_level_decl->data.use.path, import_code);
25872577 found_it = true;
25882578 }
......@@ -2682,9 +2672,8 @@ void codegen_add_root_code(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf *sou
26822672
26832673static void to_c_type(CodeGen *g, AstNode *type_node, Buf *out_buf) {
26842674 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;
26882677 assert(type_entry);
26892678
26902679 if (type_entry == g->builtin_types.entry_u8) {
src/codegen.hpp-13
......@@ -11,21 +11,8 @@
1111#include "parser.hpp"
1212#include "errmsg.hpp"
1313
14struct CodeGen;
15
16enum OutType {
17 OutTypeUnknown,
18 OutTypeExe,
19 OutTypeLib,
20 OutTypeObj,
21};
22
2314CodeGen *codegen_create(Buf *root_source_dir);
2415
25enum CodeGenBuildType {
26 CodeGenBuildTypeDebug,
27 CodeGenBuildTypeRelease,
28};
2916void codegen_set_build_type(CodeGen *codegen, CodeGenBuildType build_type);
3017void codegen_set_is_static(CodeGen *codegen, bool is_static);
3118void codegen_set_strip(CodeGen *codegen, bool strip);
src/parser.cpp+9-9
......@@ -356,8 +356,7 @@ void ast_print(AstNode *node, int indent) {
356356 fprintf(stderr, "Unreachable\n");
357357 break;
358358 case NodeTypeSymbol:
359 fprintf(stderr, "Symbol %s\n",
360 buf_ptr(&node->data.symbol));
359 fprintf(stderr, "Symbol %s\n", buf_ptr(&node->data.symbol_expr.symbol));
361360 break;
362361 case NodeTypeUse:
363362 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) {
366365 fprintf(stderr, "%s\n", node_type_str(node->type));
367366 break;
368367 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");
370370 break;
371371 case NodeTypeNullLiteral:
372372 fprintf(stderr, "%s\n", node_type_str(node->type));
......@@ -401,7 +401,7 @@ void ast_print(AstNode *node, int indent) {
401401 fprintf(stderr, "%s '%s'\n", node_type_str(node->type), buf_ptr(&node->data.label.name));
402402 break;
403403 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));
405405 break;
406406 case NodeTypeBreak:
407407 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
13691369 return node;
13701370 } else if (token->id == TokenIdKeywordTrue) {
13711371 AstNode *node = ast_create_node(pc, NodeTypeBoolLiteral, token);
1372 node->data.bool_literal = true;
1372 node->data.bool_literal.value = true;
13731373 *token_index += 1;
13741374 return node;
13751375 } else if (token->id == TokenIdKeywordFalse) {
13761376 AstNode *node = ast_create_node(pc, NodeTypeBoolLiteral, token);
1377 node->data.bool_literal = false;
1377 node->data.bool_literal.value = false;
13781378 *token_index += 1;
13791379 return node;
13801380 } else if (token->id == TokenIdKeywordNull) {
......@@ -1385,7 +1385,7 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
13851385 *token_index += 1;
13861386 Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
13871387 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
13901390 AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, token);
13911391 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
14011401 } else {
14021402 *token_index += 1;
14031403 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);
14051405 return node;
14061406 }
14071407 } else if (token->id == TokenIdKeywordGoto) {
......@@ -1412,7 +1412,7 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
14121412 *token_index += 1;
14131413 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);
14161416 return node;
14171417 } else if (token->id == TokenIdKeywordBreak) {
14181418 AstNode *node = ast_create_node(pc, NodeTypeBreak, token);
src/parser.hpp+1-441
......@@ -8,450 +8,10 @@
88#ifndef ZIG_PARSER_HPP
99#define ZIG_PARSER_HPP
1010
11#include "list.hpp"
12#include "buffer.hpp"
11#include "all_types.hpp"
1312#include "tokenizer.hpp"
1413#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
45515__attribute__ ((format (printf, 2, 3)))
45616void ast_token_error(Token *token, const char *format, ...);
45717