authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-28 21:54:01-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-05-28 21:54:01-04:00
logc12704a3395a11c28569ebb160e6ac33091d983a
treecf2e0055c53eac499b1fb66e2472a2036286afd6
parent3f5ca3920a58d44a018ff2a2e277e60813e20d5a
parentd888fa12a88ae7e5332de669b3c3a1dac57f5c19
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #8918 from ziglang/stage1-tokenizer

stage1: rework tokenizer to match stage2

28 files changed, 11675 insertions(+), 12678 deletions(-)

CMakeLists.txt+2-2
......@@ -292,7 +292,7 @@ set(ZIG0_SOURCES
292292
293293set(STAGE1_SOURCES
294294 "${CMAKE_SOURCE_DIR}/src/stage1/analyze.cpp"
295 "${CMAKE_SOURCE_DIR}/src/stage1/ast_render.cpp"
295 "${CMAKE_SOURCE_DIR}/src/stage1/astgen.cpp"
296296 "${CMAKE_SOURCE_DIR}/src/stage1/bigfloat.cpp"
297297 "${CMAKE_SOURCE_DIR}/src/stage1/bigint.cpp"
298298 "${CMAKE_SOURCE_DIR}/src/stage1/buffer.cpp"
......@@ -307,11 +307,11 @@ set(STAGE1_SOURCES
307307 "${CMAKE_SOURCE_DIR}/src/stage1/os.cpp"
308308 "${CMAKE_SOURCE_DIR}/src/stage1/parser.cpp"
309309 "${CMAKE_SOURCE_DIR}/src/stage1/range_set.cpp"
310 "${CMAKE_SOURCE_DIR}/src/stage1/softfloat_ext.cpp"
310311 "${CMAKE_SOURCE_DIR}/src/stage1/stage1.cpp"
311312 "${CMAKE_SOURCE_DIR}/src/stage1/target.cpp"
312313 "${CMAKE_SOURCE_DIR}/src/stage1/tokenizer.cpp"
313314 "${CMAKE_SOURCE_DIR}/src/stage1/util.cpp"
314 "${CMAKE_SOURCE_DIR}/src/stage1/softfloat_ext.cpp"
315315)
316316set(OPTIMIZED_C_SOURCES
317317 "${CMAKE_SOURCE_DIR}/src/stage1/parse_f128.c"
lib/std/zig/string_literal.zig+1
......@@ -107,6 +107,7 @@ pub fn parseAppend(buf: *std.ArrayList(u8), bytes: []const u8) error{OutOfMemory
107107 const hex_str = slice[index + 2 .. index_end];
108108 if (std.fmt.parseUnsigned(u32, hex_str, 16)) |uint| {
109109 if (uint <= 0x10ffff) {
110 // TODO this incorrectly depends on endianness
110111 try buf.appendSlice(std.mem.toBytes(uint)[0..]);
111112 state = State.Start;
112113 index = index_end; // loop-header increments
src/stage1.zig+2
......@@ -252,6 +252,8 @@ const Error = extern enum {
252252 ZigIsTheCCompiler,
253253 FileBusy,
254254 Locked,
255 InvalidCharacter,
256 UnicodePointTooLarge,
255257};
256258
257259// ABI warning
src/stage1/all_types.hpp+60-118
......@@ -38,7 +38,7 @@ struct IrInstGenCast;
3838struct IrInstGenAlloca;
3939struct IrInstGenCall;
4040struct IrInstGenAwait;
41struct IrBasicBlockSrc;
41struct Stage1ZirBasicBlock;
4242struct IrBasicBlockGen;
4343struct ScopeDecls;
4444struct ZigWindowsSDK;
......@@ -51,7 +51,7 @@ struct ResultLocPeerParent;
5151struct ResultLocBitCast;
5252struct ResultLocCast;
5353struct ResultLocReturn;
54struct IrExecutableGen;
54struct Stage1Air;
5555
5656enum FileExt {
5757 FileExtUnknown,
......@@ -110,51 +110,33 @@ enum X64CABIClass {
110110 X64CABIClass_SSE,
111111};
112112
113struct IrExecutableSrc {
114 ZigList<IrBasicBlockSrc *> basic_block_list;
113struct Stage1Zir {
114 ZigList<Stage1ZirBasicBlock *> basic_block_list;
115115 Buf *name;
116116 ZigFn *name_fn;
117 size_t mem_slot_count;
118 size_t next_debug_id;
119 size_t *backward_branch_count;
120 size_t *backward_branch_quota;
121 ZigFn *fn_entry;
122 Buf *c_import_buf;
123 AstNode *source_node;
124 IrExecutableGen *parent_exec;
125 IrAnalyze *analysis;
126117 Scope *begin_scope;
127118 ErrorMsg *first_err_trace_msg;
128119 ZigList<Tld *> tld_list;
129120
130121 bool is_inline;
131 bool is_generic_instantiation;
132122 bool need_err_code_spill;
133
134 // This is a function for use in the debugger to print
135 // the source location.
136 void src();
137123};
138124
139struct IrExecutableGen {
125struct Stage1Air {
140126 ZigList<IrBasicBlockGen *> basic_block_list;
141127 Buf *name;
142128 ZigFn *name_fn;
143129 size_t mem_slot_count;
144130 size_t next_debug_id;
145 size_t *backward_branch_count;
146 size_t *backward_branch_quota;
147 ZigFn *fn_entry;
148131 Buf *c_import_buf;
149132 AstNode *source_node;
150 IrExecutableGen *parent_exec;
151 IrExecutableSrc *source_exec;
133 Stage1Air *parent_exec;
134 Stage1Zir *source_exec;
152135 Scope *begin_scope;
153136 ErrorMsg *first_err_trace_msg;
154137 ZigList<Tld *> tld_list;
155138
156139 bool is_inline;
157 bool is_generic_instantiation;
158140 bool need_err_code_spill;
159141
160142 // This is a function for use in the debugger to print
......@@ -670,7 +652,7 @@ enum NodeType {
670652 NodeTypeIntLiteral,
671653 NodeTypeStringLiteral,
672654 NodeTypeCharLiteral,
673 NodeTypeSymbol,
655 NodeTypeIdentifier,
674656 NodeTypePrefixOpExpr,
675657 NodeTypePointerType,
676658 NodeTypeFnCallExpr,
......@@ -710,6 +692,7 @@ enum NodeType {
710692 NodeTypeAwaitExpr,
711693 NodeTypeSuspend,
712694 NodeTypeAnyFrameType,
695 // main_token points to the identifier.
713696 NodeTypeEnumLiteral,
714697 NodeTypeAnyTypeField,
715698};
......@@ -733,7 +716,8 @@ struct AstNodeFnProto {
733716 AstNode *section_expr;
734717 // populated if the "callconv(S)" is present
735718 AstNode *callconv_expr;
736 Buf doc_comments;
719
720 TokenIndex doc_comments;
737721
738722 // This is set based only on the existence of a noinline or inline keyword.
739723 // This is then resolved to an is_noinline bool and (potentially .Inline)
......@@ -755,8 +739,8 @@ struct AstNodeFnDef {
755739struct AstNodeParamDecl {
756740 Buf *name;
757741 AstNode *type;
758 Token *anytype_token;
759 Buf doc_comments;
742 TokenIndex doc_comments;
743 TokenIndex anytype_token;
760744 bool is_noalias;
761745 bool is_comptime;
762746 bool is_var_args;
......@@ -799,9 +783,9 @@ struct AstNodeVariableDeclaration {
799783 AstNode *align_expr;
800784 // populated if the "section(S)" is present
801785 AstNode *section_expr;
802 Token *threadlocal_tok;
803 Buf doc_comments;
786 TokenIndex doc_comments;
804787
788 TokenIndex threadlocal_tok;
805789 VisibMod visib_mod;
806790 bool is_const;
807791 bool is_comptime;
......@@ -935,13 +919,14 @@ struct AstNodePrefixOpExpr {
935919};
936920
937921struct AstNodePointerType {
938 Token *star_token;
922 TokenIndex star_token;
923 TokenIndex allow_zero_token;
924 TokenIndex bit_offset_start;
925 TokenIndex host_int_bytes;
926
939927 AstNode *sentinel;
940928 AstNode *align_expr;
941 BigInt *bit_offset_start;
942 BigInt *host_int_bytes;
943929 AstNode *op_expr;
944 Token *allow_zero_token;
945930 bool is_const;
946931 bool is_volatile;
947932};
......@@ -956,7 +941,7 @@ struct AstNodeArrayType {
956941 AstNode *sentinel;
957942 AstNode *child_type;
958943 AstNode *align_expr;
959 Token *allow_zero_token;
944 TokenIndex allow_zero_token;
960945 bool is_const;
961946 bool is_volatile;
962947};
......@@ -974,11 +959,11 @@ struct AstNodeIfBoolExpr {
974959
975960struct AstNodeTryExpr {
976961 Buf *var_symbol;
977 bool var_is_ptr;
978962 AstNode *target_node;
979963 AstNode *then_node;
980964 AstNode *else_node;
981965 Buf *err_symbol;
966 bool var_is_ptr;
982967};
983968
984969struct AstNodeTestExpr {
......@@ -993,12 +978,12 @@ struct AstNodeWhileExpr {
993978 Buf *name;
994979 AstNode *condition;
995980 Buf *var_symbol;
996 bool var_is_ptr;
997981 AstNode *continue_expr;
998982 AstNode *body;
999983 AstNode *else_node;
1000984 Buf *err_symbol;
1001985 bool is_inline;
986 bool var_is_ptr;
1002987};
1003988
1004989struct AstNodeForExpr {
......@@ -1070,7 +1055,7 @@ struct AsmToken {
10701055};
10711056
10721057struct AstNodeAsmExpr {
1073 Token *volatile_token;
1058 TokenIndex volatile_token;
10741059 AstNode *asm_template;
10751060 ZigList<AsmOutput*> output_list;
10761061 ZigList<AsmInput*> input_list;
......@@ -1094,7 +1079,7 @@ struct AstNodeContainerDecl {
10941079 AstNode *init_arg_expr; // enum(T), struct(endianness), or union(T), or union(enum(T))
10951080 ZigList<AstNode *> fields;
10961081 ZigList<AstNode *> decls;
1097 Buf doc_comments;
1082 TokenIndex doc_comments;
10981083
10991084 ContainerKind kind;
11001085 ContainerLayout layout;
......@@ -1103,7 +1088,7 @@ struct AstNodeContainerDecl {
11031088};
11041089
11051090struct AstNodeErrorSetField {
1106 Buf doc_comments;
1091 TokenIndex doc_comments;
11071092 AstNode *field_name;
11081093};
11091094
......@@ -1118,28 +1103,8 @@ struct AstNodeStructField {
11181103 AstNode *value;
11191104 // populated if the "align(A)" is present
11201105 AstNode *align_expr;
1121 Buf doc_comments;
1122 Token *comptime_token;
1123};
1124
1125struct AstNodeStringLiteral {
1126 Buf *buf;
1127};
1128
1129struct AstNodeCharLiteral {
1130 uint32_t value;
1131};
1132
1133struct AstNodeFloatLiteral {
1134 BigFloat *bigfloat;
1135
1136 // overflow is true if when parsing the number, we discovered it would not
1137 // fit without losing data in a double
1138 bool overflow;
1139};
1140
1141struct AstNodeIntLiteral {
1142 BigInt *bigint;
1106 TokenIndex doc_comments;
1107 TokenIndex comptime_token;
11431108};
11441109
11451110struct AstNodeStructValueField {
......@@ -1158,17 +1123,12 @@ struct AstNodeContainerInitExpr {
11581123 ContainerInitKind kind;
11591124};
11601125
1161struct AstNodeNullLiteral {
1162};
1163
1164struct AstNodeUndefinedLiteral {
1165};
1166
1167struct AstNodeThisLiteral {
1126struct AstNodeIdentifier {
1127 Buf *name;
11681128};
11691129
1170struct AstNodeSymbolExpr {
1171 Buf *symbol;
1130struct AstNodeEnumLiteral {
1131 Buf *name;
11721132};
11731133
11741134struct AstNodeBoolLiteral {
......@@ -1188,13 +1148,6 @@ struct AstNodeContinueExpr {
11881148 Buf *name;
11891149};
11901150
1191struct AstNodeUnreachableExpr {
1192};
1193
1194
1195struct AstNodeErrorType {
1196};
1197
11981151struct AstNodeAwaitExpr {
11991152 AstNode *expr;
12001153};
......@@ -1207,16 +1160,10 @@ struct AstNodeAnyFrameType {
12071160 AstNode *payload_type; // can be NULL
12081161};
12091162
1210struct AstNodeEnumLiteral {
1211 Token *period;
1212 Token *identifier;
1213};
1214
12151163struct AstNode {
12161164 enum NodeType type;
1165 TokenIndex main_token;
12171166 bool already_traced_this_node;
1218 size_t line;
1219 size_t column;
12201167 ZigType *owner;
12211168 union {
12221169 AstNodeFnDef fn_def;
......@@ -1252,29 +1199,24 @@ struct AstNode {
12521199 AstNodePtrDerefExpr ptr_deref_expr;
12531200 AstNodeContainerDecl container_decl;
12541201 AstNodeStructField struct_field;
1255 AstNodeStringLiteral string_literal;
1256 AstNodeCharLiteral char_literal;
1257 AstNodeFloatLiteral float_literal;
1258 AstNodeIntLiteral int_literal;
12591202 AstNodeContainerInitExpr container_init_expr;
12601203 AstNodeStructValueField struct_val_field;
1261 AstNodeNullLiteral null_literal;
1262 AstNodeUndefinedLiteral undefined_literal;
1263 AstNodeThisLiteral this_literal;
1264 AstNodeSymbolExpr symbol_expr;
12651204 AstNodeBoolLiteral bool_literal;
12661205 AstNodeBreakExpr break_expr;
12671206 AstNodeContinueExpr continue_expr;
1268 AstNodeUnreachableExpr unreachable_expr;
12691207 AstNodeArrayType array_type;
12701208 AstNodeInferredArrayType inferred_array_type;
1271 AstNodeErrorType error_type;
12721209 AstNodeErrorSetDecl err_set_decl;
12731210 AstNodeErrorSetField err_set_field;
12741211 AstNodeResumeExpr resume_expr;
12751212 AstNodeAwaitExpr await_expr;
12761213 AstNodeSuspend suspend;
12771214 AstNodeAnyFrameType anyframe_type;
1215
1216 // These are part of an astgen workaround to use less memory by
1217 // memoizing into the AST. Once astgen is modified to only run once
1218 // per corresponding source, this workaround can be removed.
1219 AstNodeIdentifier identifier;
12781220 AstNodeEnumLiteral enum_literal;
12791221 } data;
12801222
......@@ -1409,9 +1351,11 @@ struct ZigPackage {
14091351struct RootStruct {
14101352 ZigPackage *package;
14111353 Buf *path; // relative to root_package->root_src_dir
1412 ZigList<size_t> *line_offsets;
14131354 Buf *source_code;
14141355 ZigLLVMDIFile *di_file;
1356 size_t token_count;
1357 TokenId *token_ids;
1358 TokenLoc *token_locs;
14151359};
14161360
14171361enum StructSpecial {
......@@ -1703,10 +1647,9 @@ struct ZigFn {
17031647 // in the case of async functions this is the implicit return type according to the
17041648 // zig source code, not according to zig ir
17051649 ZigType *src_implicit_return_type;
1706 IrExecutableSrc *ir_executable;
1707 IrExecutableGen analyzed_executable;
1708 size_t prealloc_bbc;
1709 size_t prealloc_backward_branch_quota;
1650 Stage1Zir *stage1_zir;
1651 Stage1Air analyzed_executable;
1652 size_t branch_quota;
17101653 AstNode **param_source_nodes;
17111654 Buf **param_names;
17121655 IrInstGen *err_code_spill;
......@@ -2326,11 +2269,11 @@ struct ScopeBlock {
23262269 Scope base;
23272270
23282271 Buf *name;
2329 IrBasicBlockSrc *end_block;
2272 Stage1ZirBasicBlock *end_block;
23302273 IrInstSrc *is_comptime;
23312274 ResultLocPeerParent *peer_parent;
23322275 ZigList<IrInstSrc *> *incoming_values;
2333 ZigList<IrBasicBlockSrc *> *incoming_blocks;
2276 ZigList<Stage1ZirBasicBlock *> *incoming_blocks;
23342277
23352278 AstNode *safety_set_node;
23362279 AstNode *fast_math_set_node;
......@@ -2382,11 +2325,11 @@ struct ScopeLoop {
23822325
23832326 LVal lval;
23842327 Buf *name;
2385 IrBasicBlockSrc *break_block;
2386 IrBasicBlockSrc *continue_block;
2328 Stage1ZirBasicBlock *break_block;
2329 Stage1ZirBasicBlock *continue_block;
23872330 IrInstSrc *is_comptime;
23882331 ZigList<IrInstSrc *> *incoming_values;
2389 ZigList<IrBasicBlockSrc *> *incoming_blocks;
2332 ZigList<Stage1ZirBasicBlock *> *incoming_blocks;
23902333 ResultLocPeerParent *peer_parent;
23912334 ScopeExpr *spill_scope;
23922335
......@@ -2497,7 +2440,7 @@ enum AtomicRmwOp {
24972440// to another basic block.
24982441// Phi instructions must be first in a basic block.
24992442// The last instruction in a basic block must be of type unreachable.
2500struct IrBasicBlockSrc {
2443struct Stage1ZirBasicBlock {
25012444 ZigList<IrInstSrc *> instruction_list;
25022445 IrBasicBlockGen *child;
25032446 Scope *scope;
......@@ -2772,8 +2715,7 @@ enum IrInstGenId {
27722715 IrInstGenIdExtern,
27732716};
27742717
2775// Common fields between IrInstSrc and IrInstGen. This allows future passes
2776// after pass2 to be added to zig.
2718// Common fields between IrInstSrc and IrInstGen.
27772719struct IrInst {
27782720 // if ref_count is zero and the instruction has no side effects,
27792721 // the instruction can be omitted in codegen
......@@ -2801,7 +2743,7 @@ struct IrInstSrc {
28012743 // can find the instruction that corresponds to this value in the "new ir"
28022744 // with this child field.
28032745 IrInstGen *child;
2804 IrBasicBlockSrc *owner_bb;
2746 Stage1ZirBasicBlock *owner_bb;
28052747
28062748 // for debugging purposes, these are useful to call to inspect the instruction
28072749 void dump();
......@@ -2846,8 +2788,8 @@ struct IrInstSrcCondBr {
28462788 IrInstSrc base;
28472789
28482790 IrInstSrc *condition;
2849 IrBasicBlockSrc *then_block;
2850 IrBasicBlockSrc *else_block;
2791 Stage1ZirBasicBlock *then_block;
2792 Stage1ZirBasicBlock *else_block;
28512793 IrInstSrc *is_comptime;
28522794 ResultLoc *result_loc;
28532795};
......@@ -2863,7 +2805,7 @@ struct IrInstGenCondBr {
28632805struct IrInstSrcBr {
28642806 IrInstSrc base;
28652807
2866 IrBasicBlockSrc *dest_block;
2808 Stage1ZirBasicBlock *dest_block;
28672809 IrInstSrc *is_comptime;
28682810};
28692811
......@@ -2875,14 +2817,14 @@ struct IrInstGenBr {
28752817
28762818struct IrInstSrcSwitchBrCase {
28772819 IrInstSrc *value;
2878 IrBasicBlockSrc *block;
2820 Stage1ZirBasicBlock *block;
28792821};
28802822
28812823struct IrInstSrcSwitchBr {
28822824 IrInstSrc base;
28832825
28842826 IrInstSrc *target_value;
2885 IrBasicBlockSrc *else_block;
2827 Stage1ZirBasicBlock *else_block;
28862828 size_t case_count;
28872829 IrInstSrcSwitchBrCase *cases;
28882830 IrInstSrc *is_comptime;
......@@ -2928,7 +2870,7 @@ struct IrInstSrcPhi {
29282870 IrInstSrc base;
29292871
29302872 size_t incoming_count;
2931 IrBasicBlockSrc **incoming_blocks;
2873 Stage1ZirBasicBlock **incoming_blocks;
29322874 IrInstSrc **incoming_values;
29332875 ResultLocPeerParent *peer_parent;
29342876};
......@@ -4592,7 +4534,7 @@ struct ResultLocPeerParent {
45924534
45934535 bool skipped;
45944536 bool done_resuming;
4595 IrBasicBlockSrc *end_bb;
4537 Stage1ZirBasicBlock *end_bb;
45964538 ResultLoc *parent;
45974539 ZigList<ResultLocPeer *> peers;
45984540 ZigType *resolved_type;
......@@ -4603,7 +4545,7 @@ struct ResultLocPeer {
46034545 ResultLoc base;
46044546
46054547 ResultLocPeerParent *parent;
4606 IrBasicBlockSrc *next_bb;
4548 Stage1ZirBasicBlock *next_bb;
46074549 IrSuspendPosition suspend_pos;
46084550};
46094551
src/stage1/analyze.cpp+97-91
......@@ -6,9 +6,9 @@
66 */
77
88#include "analyze.hpp"
9#include "ast_render.hpp"
109#include "codegen.hpp"
1110#include "error.hpp"
11#include "astgen.hpp"
1212#include "ir.hpp"
1313#include "ir_print.hpp"
1414#include "os.hpp"
......@@ -41,41 +41,44 @@ static bool is_top_level_struct(ZigType *import) {
4141 return import->id == ZigTypeIdStruct && import->data.structure.root_struct != nullptr;
4242}
4343
44static ErrorMsg *add_error_note_token(CodeGen *g, ErrorMsg *parent_msg, ZigType *owner, Token *token, Buf *msg) {
44static ErrorMsg *add_error_note_token(CodeGen *g, ErrorMsg *parent_msg, ZigType *owner,
45 TokenIndex token, Buf *msg)
46{
4547 assert(is_top_level_struct(owner));
4648 RootStruct *root_struct = owner->data.structure.root_struct;
47
48 ErrorMsg *err = err_msg_create_with_line(root_struct->path, token->start_line, token->start_column,
49 root_struct->source_code, root_struct->line_offsets, msg);
49 uint32_t byte_offset = root_struct->token_locs[token].offset;
50 ErrorMsg *err = err_msg_create_with_offset(root_struct->path, byte_offset,
51 buf_ptr(root_struct->source_code), msg);
5052
5153 err_msg_add_note(parent_msg, err);
5254 return err;
5355}
5456
55ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg) {
57ErrorMsg *add_token_error_offset(CodeGen *g, ZigType *owner, TokenIndex token, Buf *msg,
58 uint32_t bad_index)
59{
5660 assert(is_top_level_struct(owner));
5761 RootStruct *root_struct = owner->data.structure.root_struct;
58 ErrorMsg *err = err_msg_create_with_line(root_struct->path, token->start_line, token->start_column,
59 root_struct->source_code, root_struct->line_offsets, msg);
62 uint32_t byte_offset = root_struct->token_locs[token].offset + bad_index;
63 ErrorMsg *err = err_msg_create_with_offset(root_struct->path, byte_offset,
64 buf_ptr(root_struct->source_code), msg);
6065
6166 g->errors.append(err);
6267 g->trace_err = err;
6368 return err;
6469}
6570
71ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, TokenIndex token, Buf *msg) {
72 return add_token_error_offset(g, owner, token, msg, 0);
73}
74
6675ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
67 Token fake_token;
68 fake_token.start_line = node->line;
69 fake_token.start_column = node->column;
7076 node->already_traced_this_node = true;
71 return add_token_error(g, node->owner, &fake_token, msg);
77 return add_token_error(g, node->owner, node->main_token, msg);
7278}
7379
7480ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg) {
75 Token fake_token;
76 fake_token.start_line = node->line;
77 fake_token.start_column = node->column;
78 return add_error_note_token(g, parent_msg, node->owner, &fake_token, msg);
81 return add_error_note_token(g, parent_msg, node->owner, node->main_token, msg);
7982}
8083
8184ZigType *new_type_table_entry(ZigTypeId id) {
......@@ -913,13 +916,27 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
913916 return entry;
914917}
915918
916ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name) {
919static uint32_t node_line_onebased(AstNode *node) {
920 RootStruct *root_struct = node->owner->data.structure.root_struct;
921 assert(node->main_token < root_struct->token_count);
922 return root_struct->token_locs[node->main_token].line + 1;
923}
924
925static uint32_t node_column_onebased(AstNode *node) {
926 RootStruct *root_struct = node->owner->data.structure.root_struct;
927 assert(node->main_token < root_struct->token_count);
928 return root_struct->token_locs[node->main_token].column + 1;
929}
930
931ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name,
932 Buf *bare_name)
933{
917934 ZigType *entry = new_type_table_entry(ZigTypeIdOpaque);
918935
919936 buf_init_from_str(&entry->name, full_name);
920937
921938 ZigType *import = scope ? get_scope_import(scope) : nullptr;
922 unsigned line = source_node ? (unsigned)(source_node->line + 1) : 0;
939 unsigned line = source_node ? node_line_onebased(source_node) : 0;
923940
924941 // Note: duplicated in get_partial_container_type
925942 entry->llvm_type = LLVMInt8Type();
......@@ -1142,7 +1159,7 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind
11421159 break;
11431160 case ContainerKindOpaque: {
11441161 ZigType *import = scope ? get_scope_import(scope) : nullptr;
1145 unsigned line = decl_node ? (unsigned)(decl_node->line + 1) : 0;
1162 unsigned line = decl_node ? node_line_onebased(decl_node) : 0;
11461163 // Note: duplicated in get_opaque_type
11471164 entry->llvm_type = LLVMInt8Type();
11481165 entry->llvm_di_type = ZigLLVMCreateDebugForwardDeclType(g->dbuilder,
......@@ -1584,8 +1601,9 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
15841601ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
15851602 Error err;
15861603 // Hot path for simple identifiers, to avoid unnecessary memory allocations.
1587 if (node->type == NodeTypeSymbol) {
1588 Buf *variable_name = node->data.symbol_expr.symbol;
1604 if (node->type == NodeTypeIdentifier) {
1605 RootStruct *root_struct = node->owner->data.structure.root_struct;
1606 Buf *variable_name = token_identifier_buf(root_struct, node->main_token);
15891607 if (buf_eql_str(variable_name, "_"))
15901608 goto abort_hot_path;
15911609 ZigType *primitive_type;
......@@ -2034,7 +2052,7 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
20342052 buf_sprintf("var args only allowed in functions with C calling convention"));
20352053 return g->builtin_types.entry_invalid;
20362054 }
2037 } else if (param_node->data.param_decl.anytype_token != nullptr) {
2055 } else if (param_node->data.param_decl.anytype_token != 0) {
20382056 if (!calling_convention_allows_zig_types(fn_type_id.cc)) {
20392057 add_node_error(g, param_node,
20402058 buf_sprintf("parameter of type 'anytype' not allowed in function with calling convention '%s'",
......@@ -3021,7 +3039,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
30213039 field_node = decl_node->data.container_decl.fields.at(i);
30223040 type_struct_field->name = field_node->data.struct_field.name;
30233041 type_struct_field->decl_node = field_node;
3024 if (field_node->data.struct_field.comptime_token != nullptr) {
3042 if (field_node->data.struct_field.comptime_token != 0) {
30253043 if (field_node->data.struct_field.value == nullptr) {
30263044 add_token_error(g, field_node->owner,
30273045 field_node->data.struct_field.comptime_token,
......@@ -3635,14 +3653,7 @@ static void get_fully_qualified_decl_name(CodeGen *g, Buf *buf, Tld *tld, bool i
36353653
36363654static ZigFn *create_fn_raw(CodeGen *g, bool is_noinline) {
36373655 ZigFn *fn_entry = heap::c_allocator.create<ZigFn>();
3638 fn_entry->ir_executable = heap::c_allocator.create<IrExecutableSrc>();
3639
3640 fn_entry->prealloc_backward_branch_quota = default_backward_branch_quota;
3641
3642 fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;
3643 fn_entry->analyzed_executable.backward_branch_quota = &fn_entry->prealloc_backward_branch_quota;
3644 fn_entry->analyzed_executable.fn_entry = fn_entry;
3645 fn_entry->ir_executable->fn_entry = fn_entry;
3656 fn_entry->stage1_zir = heap::c_allocator.create<Stage1Zir>();
36463657 fn_entry->is_noinline = is_noinline;
36473658
36483659 return fn_entry;
......@@ -4042,7 +4053,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
40424053 case NodeTypeBoolLiteral:
40434054 case NodeTypeNullLiteral:
40444055 case NodeTypeUndefinedLiteral:
4045 case NodeTypeSymbol:
4056 case NodeTypeIdentifier:
40464057 case NodeTypePrefixOpExpr:
40474058 case NodeTypePointerType:
40484059 case NodeTypeIfBoolExpr:
......@@ -4238,7 +4249,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var, bool allow_lazy) {
42384249 bool is_const = var_decl->is_const;
42394250 bool is_extern = var_decl->is_extern;
42404251 bool is_export = var_decl->is_export;
4241 bool is_thread_local = var_decl->threadlocal_tok != nullptr;
4252 bool is_thread_local = var_decl->threadlocal_tok != 0;
42424253
42434254 ZigType *explicit_type = nullptr;
42444255 if (var_decl->type) {
......@@ -5116,8 +5127,11 @@ static void analyze_fn_ir(CodeGen *g, ZigFn *fn, AstNode *return_type_node) {
51165127 if (fn->analyzed_executable.source_node == nullptr) {
51175128 fn->analyzed_executable.source_node = fn->body_node;
51185129 }
5119 ZigType *block_return_type = ir_analyze(g, fn->ir_executable,
5120 &fn->analyzed_executable, fn_type_id->return_type, return_type_node, nullptr);
5130 size_t backward_branch_count = 0;
5131 size_t backward_branch_quota = max(fn->branch_quota, default_backward_branch_quota);
5132 ZigType *block_return_type = ir_analyze(g, fn->stage1_zir, &fn->analyzed_executable,
5133 &backward_branch_count, &backward_branch_quota,
5134 fn_type_id->return_type, return_type_node, nullptr, fn);
51215135 fn->src_implicit_return_type = block_return_type;
51225136
51235137 if (type_is_invalid(block_return_type) || fn->analyzed_executable.first_err_trace_msg != nullptr) {
......@@ -5214,21 +5228,19 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
52145228 ZigType *fn_type = fn_table_entry->type_entry;
52155229 assert(!fn_type->data.fn.is_generic);
52165230
5217 if (!ir_gen_fn(g, fn_table_entry)) {
5231 if (!stage1_astgen_fn(g, fn_table_entry)) {
52185232 fn_table_entry->anal_state = FnAnalStateInvalid;
52195233 return;
52205234 }
52215235
5222 if (fn_table_entry->ir_executable->first_err_trace_msg != nullptr) {
5236 if (fn_table_entry->stage1_zir->first_err_trace_msg != nullptr) {
52235237 fn_table_entry->anal_state = FnAnalStateInvalid;
52245238 return;
52255239 }
52265240
52275241 if (g->verbose_ir) {
5228 fprintf(stderr, "\n");
5229 ast_render(stderr, fn_table_entry->body_node, 4);
52305242 fprintf(stderr, "\nfn %s() { // (IR)\n", buf_ptr(&fn_table_entry->symbol_name));
5231 ir_print_src(g, stderr, fn_table_entry->ir_executable, 4);
5243 ir_print_src(g, stderr, fn_table_entry->stage1_zir, 4);
52325244 fprintf(stderr, "}\n");
52335245 }
52345246
......@@ -5238,33 +5250,17 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
52385250ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Buf *source_code,
52395251 SourceKind source_kind)
52405252{
5241 if (g->verbose_tokenize) {
5242 fprintf(stderr, "\nOriginal Source (%s):\n", buf_ptr(resolved_path));
5243 fprintf(stderr, "----------------\n");
5244 fprintf(stderr, "%s\n", buf_ptr(source_code));
5245
5246 fprintf(stderr, "\nTokens:\n");
5247 fprintf(stderr, "---------\n");
5248 }
5249
52505253 Tokenization tokenization = {0};
5251 tokenize(source_code, &tokenization);
5254 tokenize(buf_ptr(source_code), &tokenization);
52525255
52535256 if (tokenization.err) {
5254 ErrorMsg *err = err_msg_create_with_line(resolved_path, tokenization.err_line, tokenization.err_column,
5255 source_code, tokenization.line_offsets, tokenization.err);
5257 ErrorMsg *err = err_msg_create_with_offset(resolved_path, tokenization.err_byte_offset,
5258 buf_ptr(source_code), tokenization.err);
52565259
52575260 print_err_msg(err, g->err_color);
52585261 exit(1);
52595262 }
52605263
5261 if (g->verbose_tokenize) {
5262 print_tokens(source_code, tokenization.tokens);
5263
5264 fprintf(stderr, "\nAST:\n");
5265 fprintf(stderr, "------\n");
5266 }
5267
52685264 Buf *src_dirname = buf_alloc();
52695265 Buf *src_basename = buf_alloc();
52705266 os_path_split(resolved_path, src_dirname, src_basename);
......@@ -5297,9 +5293,20 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
52975293 RootStruct *root_struct = heap::c_allocator.create<RootStruct>();
52985294 root_struct->package = package;
52995295 root_struct->source_code = source_code;
5300 root_struct->line_offsets = tokenization.line_offsets;
53015296 root_struct->path = resolved_path;
53025297 root_struct->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname));
5298
5299 assert(tokenization.ids.length == tokenization.locs.length);
5300 size_t token_count = tokenization.ids.length;
5301 root_struct->token_count = token_count;
5302 root_struct->token_ids = g->pass1_arena->allocate<TokenId>(token_count);
5303 memcpy(root_struct->token_ids, tokenization.ids.items, token_count * sizeof(TokenId));
5304 root_struct->token_locs = g->pass1_arena->allocate<TokenLoc>(token_count);
5305 memcpy(root_struct->token_locs, tokenization.locs.items, token_count * sizeof(TokenLoc));
5306
5307 tokenization.ids.deinit();
5308 tokenization.locs.deinit();
5309
53035310 ZigType *import_entry = get_root_container_type(g, buf_ptr(namespace_name), bare_name, root_struct);
53045311 if (source_kind == SourceKindRoot) {
53055312 assert(g->root_import == nullptr);
......@@ -5307,14 +5314,11 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
53075314 }
53085315 g->import_table.put(resolved_path, import_entry);
53095316
5310 AstNode *root_node = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color);
5317 AstNode *root_node = ast_parse(source_code, import_entry, g->err_color);
53115318 assert(root_node != nullptr);
53125319 assert(root_node->type == NodeTypeContainerDecl);
53135320 import_entry->data.structure.decl_node = root_node;
53145321 import_entry->data.structure.decls_scope->base.source_node = root_node;
5315 if (g->verbose_ast) {
5316 ast_print(stderr, root_node, 0);
5317 }
53185322
53195323 for (size_t decl_i = 0; decl_i < root_node->data.container_decl.decls.length; decl_i += 1) {
53205324 AstNode *top_level_decl = root_node->data.container_decl.decls.at(decl_i);
......@@ -6254,9 +6258,12 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty) {
62546258 zig_unreachable();
62556259}
62566260
6257void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str) {
6261void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str, bool move_str) {
62586262 auto entry = g->string_literals_table.maybe_get(str);
62596263 if (entry != nullptr) {
6264 if (move_str) {
6265 buf_destroy(str);
6266 }
62606267 memcpy(const_val, entry->value, sizeof(ZigValue));
62616268 return;
62626269 }
......@@ -6280,7 +6287,7 @@ void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str) {
62806287
62816288ZigValue *create_const_str_lit(CodeGen *g, Buf *str) {
62826289 ZigValue *const_val = g->pass1_arena->create<ZigValue>();
6283 init_const_str_lit(g, const_val, str);
6290 init_const_str_lit(g, const_val, str, false);
62846291 return const_val;
62856292}
62866293
......@@ -8626,7 +8633,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
86268633 ZigType *import = get_scope_import(scope);
86278634 di_file = import->data.structure.root_struct->di_file;
86288635 di_scope = ZigLLVMFileToScope(di_file);
8629 line = decl_node->line + 1;
8636 line = node_line_onebased(decl_node);
86308637 } else {
86318638 di_file = nullptr;
86328639 di_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
......@@ -8830,7 +8837,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
88308837 unsigned line;
88318838 if (decl_node != nullptr) {
88328839 AstNode *field_node = field->decl_node;
8833 line = field_node->line + 1;
8840 line = node_line_onebased(field_node);
88348841 } else {
88358842 line = 0;
88368843 }
......@@ -8881,7 +8888,7 @@ static ZigLLVMDIType *make_empty_namespace_llvm_di_type(CodeGen *g, ZigType *imp
88818888 return ZigLLVMCreateDebugStructType(g->dbuilder,
88828889 ZigLLVMFileToScope(import->data.structure.root_struct->di_file),
88838890 name,
8884 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
8891 import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
88858892 debug_size_in_bits,
88868893 debug_align_in_bits,
88878894 ZigLLVM_DIFlags_Zero,
......@@ -8926,7 +8933,7 @@ static void resolve_llvm_types_enum(CodeGen *g, ZigType *enum_type, ResolveStatu
89268933 uint64_t tag_debug_align_in_bits = 8*tag_int_type->abi_align;
89278934 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
89288935 ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&enum_type->name),
8929 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
8936 import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
89308937 tag_debug_size_in_bits,
89318938 tag_debug_align_in_bits,
89328939 di_enumerators, field_count,
......@@ -8966,12 +8973,12 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
89668973
89678974 if (union_type->data.unionation.resolve_status < ResolveStatusLLVMFwdDecl) {
89688975 union_type->llvm_type = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&union_type->name));
8969 size_t line = decl_node ? decl_node->line : 0;
8976 unsigned line = decl_node ? node_line_onebased(decl_node) : 0;
89708977 unsigned dwarf_kind = ZigLLVMTag_DW_structure_type();
89718978 union_type->llvm_di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
89728979 dwarf_kind, buf_ptr(&union_type->name),
89738980 ZigLLVMFileToScope(import->data.structure.root_struct->di_file),
8974 import->data.structure.root_struct->di_file, (unsigned)(line + 1));
8981 import->data.structure.root_struct->di_file, line);
89758982
89768983 union_type->data.unionation.resolve_status = ResolveStatusLLVMFwdDecl;
89778984 if (ResolveStatusLLVMFwdDecl >= wanted_resolve_status) return;
......@@ -8992,7 +8999,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
89928999 AstNode *field_node = union_field->decl_node;
89939000 union_inner_di_types[union_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
89949001 ZigLLVMTypeToScope(union_type->llvm_di_type), buf_ptr(union_field->enum_field->name),
8995 import->data.structure.root_struct->di_file, (unsigned)(field_node->line + 1),
9002 import->data.structure.root_struct->di_file, node_line_onebased(field_node),
89969003 store_size_in_bits,
89979004 abi_align_in_bits,
89989005 0,
......@@ -9022,7 +9029,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
90229029 // create debug type for union
90239030 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
90249031 ZigLLVMFileToScope(import->data.structure.root_struct->di_file), buf_ptr(&union_type->name),
9025 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
9032 import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
90269033 union_type->data.unionation.union_abi_size * 8,
90279034 most_aligned_union_member->align * 8,
90289035 ZigLLVM_DIFlags_Zero, union_inner_di_types,
......@@ -9057,7 +9064,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
90579064 // create debug type for union
90589065 ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder,
90599066 ZigLLVMTypeToScope(union_type->llvm_di_type), "AnonUnion",
9060 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
9067 import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
90619068 most_aligned_union_member->type_entry->size_in_bits, 8*most_aligned_union_member->align,
90629069 ZigLLVM_DIFlags_Zero, union_inner_di_types, gen_field_count, 0, "");
90639070
......@@ -9068,7 +9075,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
90689075
90699076 ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
90709077 ZigLLVMTypeToScope(union_type->llvm_di_type), "payload",
9071 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
9078 import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
90729079 most_aligned_union_member->type_entry->size_in_bits,
90739080 8*most_aligned_union_member->align,
90749081 union_offset_in_bits,
......@@ -9079,7 +9086,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
90799086
90809087 ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder,
90819088 ZigLLVMTypeToScope(union_type->llvm_di_type), "tag",
9082 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
9089 import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
90839090 tag_debug_size_in_bits,
90849091 tag_debug_align_in_bits,
90859092 tag_offset_in_bits,
......@@ -9094,7 +9101,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
90949101 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
90959102 ZigLLVMFileToScope(import->data.structure.root_struct->di_file),
90969103 buf_ptr(&union_type->name),
9097 import->data.structure.root_struct->di_file, (unsigned)(decl_node->line + 1),
9104 import->data.structure.root_struct->di_file, node_line_onebased(decl_node),
90989105 debug_size_in_bits,
90999106 debug_align_in_bits,
91009107 ZigLLVM_DIFlags_Zero, nullptr, di_root_members, 2, 0, nullptr, "");
......@@ -9774,9 +9781,9 @@ void src_assert_impl(bool ok, AstNode *source_node, char const *file, unsigned i
97749781 if (source_node == nullptr) {
97759782 fprintf(stderr, "when analyzing (unknown source location) ");
97769783 } else {
9777 fprintf(stderr, "when analyzing %s:%u:%u ",
9778 buf_ptr(source_node->owner->data.structure.root_struct->path),
9779 (unsigned)source_node->line + 1, (unsigned)source_node->column + 1);
9784 RootStruct *root_struct = source_node->owner->data.structure.root_struct;
9785 fprintf(stderr, "when analyzing %s:%u:%u ", buf_ptr(root_struct->path),
9786 node_line_onebased(source_node), node_column_onebased(source_node));
97809787 }
97819788 fprintf(stderr, "in compiler source at %s:%u: ", file, line);
97829789 const char *msg = "assertion failed. This is a bug in the Zig compiler.";
......@@ -9842,18 +9849,17 @@ Error analyze_import(CodeGen *g, ZigType *source_import, Buf *import_target_str,
98429849 return ErrorNone;
98439850}
98449851
9845
9846void IrExecutableSrc::src() {
9847 if (this->source_node != nullptr) {
9848 this->source_node->src();
9849 }
9850 if (this->parent_exec != nullptr) {
9851 this->parent_exec->src();
9852 }
9852void AstNode::src() {
9853 RootStruct *root_struct = this->owner->data.structure.root_struct;
9854 uint32_t line = root_struct->token_locs[this->main_token].line + 1;
9855 uint32_t column = root_struct->token_locs[this->main_token].column + 1;
9856 fprintf(stderr, "%s:%" PRIu32 ":%" PRIu32 "\n",
9857 buf_ptr(root_struct->path),
9858 line, column);
98539859}
98549860
9855void IrExecutableGen::src() {
9856 IrExecutableGen *it;
9861void Stage1Air::src() {
9862 Stage1Air *it;
98579863 for (it = this; it != nullptr && it->source_node != nullptr; it = it->parent_exec) {
98589864 it->source_node->src();
98599865 }
src/stage1/analyze.hpp+4-2
......@@ -12,7 +12,9 @@
1212
1313void semantic_analyze(CodeGen *g);
1414ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg);
15ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, Token *token, Buf *msg);
15ErrorMsg *add_token_error(CodeGen *g, ZigType *owner, TokenIndex token, Buf *msg);
16ErrorMsg *add_token_error_offset(CodeGen *g, ZigType *owner, TokenIndex token, Buf *msg,
17 uint32_t bad_index);
1618ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, const AstNode *node, Buf *msg);
1719ZigType *new_type_table_entry(ZigTypeId id);
1820ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn);
......@@ -140,7 +142,7 @@ Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc
140142Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent);
141143ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent);
142144
143void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str);
145void init_const_str_lit(CodeGen *g, ZigValue *const_val, Buf *str, bool move_str);
144146ZigValue *create_const_str_lit(CodeGen *g, Buf *str);
145147
146148void init_const_bigint(ZigValue *const_val, ZigType *type, const BigInt *bigint);
src/stage1/ast_render.cpp deleted-1241
......@@ -1,1241 +0,0 @@
1/*
2 * Copyright (c) 2016 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#include "analyze.hpp"
9#include "ast_render.hpp"
10#include "os.hpp"
11
12#include <stdio.h>
13
14static const char *bin_op_str(BinOpType bin_op) {
15 switch (bin_op) {
16 case BinOpTypeInvalid: return "(invalid)";
17 case BinOpTypeBoolOr: return "or";
18 case BinOpTypeBoolAnd: return "and";
19 case BinOpTypeCmpEq: return "==";
20 case BinOpTypeCmpNotEq: return "!=";
21 case BinOpTypeCmpLessThan: return "<";
22 case BinOpTypeCmpGreaterThan: return ">";
23 case BinOpTypeCmpLessOrEq: return "<=";
24 case BinOpTypeCmpGreaterOrEq: return ">=";
25 case BinOpTypeBinOr: return "|";
26 case BinOpTypeBinXor: return "^";
27 case BinOpTypeBinAnd: return "&";
28 case BinOpTypeBitShiftLeft: return "<<";
29 case BinOpTypeBitShiftRight: return ">>";
30 case BinOpTypeAdd: return "+";
31 case BinOpTypeAddWrap: return "+%";
32 case BinOpTypeSub: return "-";
33 case BinOpTypeSubWrap: return "-%";
34 case BinOpTypeMult: return "*";
35 case BinOpTypeMultWrap: return "*%";
36 case BinOpTypeDiv: return "/";
37 case BinOpTypeMod: return "%";
38 case BinOpTypeAssign: return "=";
39 case BinOpTypeAssignTimes: return "*=";
40 case BinOpTypeAssignTimesWrap: return "*%=";
41 case BinOpTypeAssignDiv: return "/=";
42 case BinOpTypeAssignMod: return "%=";
43 case BinOpTypeAssignPlus: return "+=";
44 case BinOpTypeAssignPlusWrap: return "+%=";
45 case BinOpTypeAssignMinus: return "-=";
46 case BinOpTypeAssignMinusWrap: return "-%=";
47 case BinOpTypeAssignBitShiftLeft: return "<<=";
48 case BinOpTypeAssignBitShiftRight: return ">>=";
49 case BinOpTypeAssignBitAnd: return "&=";
50 case BinOpTypeAssignBitXor: return "^=";
51 case BinOpTypeAssignBitOr: return "|=";
52 case BinOpTypeUnwrapOptional: return "orelse";
53 case BinOpTypeArrayCat: return "++";
54 case BinOpTypeArrayMult: return "**";
55 case BinOpTypeErrorUnion: return "!";
56 case BinOpTypeMergeErrorSets: return "||";
57 }
58 zig_unreachable();
59}
60
61static const char *prefix_op_str(PrefixOp prefix_op) {
62 switch (prefix_op) {
63 case PrefixOpInvalid: return "(invalid)";
64 case PrefixOpNegation: return "-";
65 case PrefixOpNegationWrap: return "-%";
66 case PrefixOpBoolNot: return "!";
67 case PrefixOpBinNot: return "~";
68 case PrefixOpOptional: return "?";
69 case PrefixOpAddrOf: return "&";
70 }
71 zig_unreachable();
72}
73
74static const char *visib_mod_string(VisibMod mod) {
75 switch (mod) {
76 case VisibModPub: return "pub ";
77 case VisibModPrivate: return "";
78 }
79 zig_unreachable();
80}
81
82static const char *return_string(ReturnKind kind) {
83 switch (kind) {
84 case ReturnKindUnconditional: return "return";
85 case ReturnKindError: return "try";
86 }
87 zig_unreachable();
88}
89
90static const char *defer_string(ReturnKind kind) {
91 switch (kind) {
92 case ReturnKindUnconditional: return "defer";
93 case ReturnKindError: return "errdefer";
94 }
95 zig_unreachable();
96}
97
98static const char *layout_string(ContainerLayout layout) {
99 switch (layout) {
100 case ContainerLayoutAuto: return "";
101 case ContainerLayoutExtern: return "extern ";
102 case ContainerLayoutPacked: return "packed ";
103 }
104 zig_unreachable();
105}
106
107static const char *extern_string(bool is_extern) {
108 return is_extern ? "extern " : "";
109}
110
111static const char *export_string(bool is_export) {
112 return is_export ? "export " : "";
113}
114
115//static const char *calling_convention_string(CallingConvention cc) {
116// switch (cc) {
117// case CallingConventionUnspecified: return "";
118// case CallingConventionC: return "extern ";
119// case CallingConventionCold: return "coldcc ";
120// case CallingConventionNaked: return "nakedcc ";
121// case CallingConventionStdcall: return "stdcallcc ";
122// }
123// zig_unreachable();
124//}
125
126static const char *inline_string(FnInline fn_inline) {
127 switch (fn_inline) {
128 case FnInlineAlways: return "inline ";
129 case FnInlineNever: return "noinline ";
130 case FnInlineAuto: return "";
131 }
132 zig_unreachable();
133}
134
135static const char *const_or_var_string(bool is_const) {
136 return is_const ? "const" : "var";
137}
138
139static const char *thread_local_string(Token *tok) {
140 return (tok == nullptr) ? "" : "threadlocal ";
141}
142
143static const char *token_to_ptr_len_str(Token *tok) {
144 assert(tok != nullptr);
145 switch (tok->id) {
146 case TokenIdStar:
147 case TokenIdStarStar:
148 return "*";
149 case TokenIdLBracket:
150 return "[*]";
151 case TokenIdSymbol:
152 return "[*c]";
153 default:
154 zig_unreachable();
155 }
156}
157
158static const char *node_type_str(NodeType node_type) {
159 switch (node_type) {
160 case NodeTypeFnDef:
161 return "FnDef";
162 case NodeTypeFnProto:
163 return "FnProto";
164 case NodeTypeParamDecl:
165 return "ParamDecl";
166 case NodeTypeBlock:
167 return "Block";
168 case NodeTypeGroupedExpr:
169 return "Parens";
170 case NodeTypeBinOpExpr:
171 return "BinOpExpr";
172 case NodeTypeCatchExpr:
173 return "CatchExpr";
174 case NodeTypeFnCallExpr:
175 return "FnCallExpr";
176 case NodeTypeArrayAccessExpr:
177 return "ArrayAccessExpr";
178 case NodeTypeSliceExpr:
179 return "SliceExpr";
180 case NodeTypeReturnExpr:
181 return "ReturnExpr";
182 case NodeTypeDefer:
183 return "Defer";
184 case NodeTypeVariableDeclaration:
185 return "VariableDeclaration";
186 case NodeTypeTestDecl:
187 return "TestDecl";
188 case NodeTypeIntLiteral:
189 return "IntLiteral";
190 case NodeTypeFloatLiteral:
191 return "FloatLiteral";
192 case NodeTypeStringLiteral:
193 return "StringLiteral";
194 case NodeTypeCharLiteral:
195 return "CharLiteral";
196 case NodeTypeSymbol:
197 return "Symbol";
198 case NodeTypePrefixOpExpr:
199 return "PrefixOpExpr";
200 case NodeTypeUsingNamespace:
201 return "UsingNamespace";
202 case NodeTypeBoolLiteral:
203 return "BoolLiteral";
204 case NodeTypeNullLiteral:
205 return "NullLiteral";
206 case NodeTypeUndefinedLiteral:
207 return "UndefinedLiteral";
208 case NodeTypeIfBoolExpr:
209 return "IfBoolExpr";
210 case NodeTypeWhileExpr:
211 return "WhileExpr";
212 case NodeTypeForExpr:
213 return "ForExpr";
214 case NodeTypeSwitchExpr:
215 return "SwitchExpr";
216 case NodeTypeSwitchProng:
217 return "SwitchProng";
218 case NodeTypeSwitchRange:
219 return "SwitchRange";
220 case NodeTypeCompTime:
221 return "CompTime";
222 case NodeTypeNoSuspend:
223 return "NoSuspend";
224 case NodeTypeBreak:
225 return "Break";
226 case NodeTypeContinue:
227 return "Continue";
228 case NodeTypeUnreachable:
229 return "Unreachable";
230 case NodeTypeAsmExpr:
231 return "AsmExpr";
232 case NodeTypeFieldAccessExpr:
233 return "FieldAccessExpr";
234 case NodeTypePtrDeref:
235 return "PtrDerefExpr";
236 case NodeTypeUnwrapOptional:
237 return "UnwrapOptional";
238 case NodeTypeContainerDecl:
239 return "ContainerDecl";
240 case NodeTypeStructField:
241 return "StructField";
242 case NodeTypeStructValueField:
243 return "StructValueField";
244 case NodeTypeContainerInitExpr:
245 return "ContainerInitExpr";
246 case NodeTypeArrayType:
247 return "ArrayType";
248 case NodeTypeInferredArrayType:
249 return "InferredArrayType";
250 case NodeTypeErrorType:
251 return "ErrorType";
252 case NodeTypeIfErrorExpr:
253 return "IfErrorExpr";
254 case NodeTypeIfOptional:
255 return "IfOptional";
256 case NodeTypeErrorSetDecl:
257 return "ErrorSetDecl";
258 case NodeTypeResume:
259 return "Resume";
260 case NodeTypeAwaitExpr:
261 return "AwaitExpr";
262 case NodeTypeSuspend:
263 return "Suspend";
264 case NodeTypePointerType:
265 return "PointerType";
266 case NodeTypeAnyFrameType:
267 return "AnyFrameType";
268 case NodeTypeEnumLiteral:
269 return "EnumLiteral";
270 case NodeTypeErrorSetField:
271 return "ErrorSetField";
272 case NodeTypeAnyTypeField:
273 return "AnyTypeField";
274 }
275 zig_unreachable();
276}
277
278struct AstPrint {
279 int indent;
280 FILE *f;
281};
282
283static void ast_print_visit(AstNode **node_ptr, void *context) {
284 AstNode *node = *node_ptr;
285 AstPrint *ap = (AstPrint *)context;
286
287 for (int i = 0; i < ap->indent; i += 1) {
288 fprintf(ap->f, " ");
289 }
290
291 fprintf(ap->f, "%s\n", node_type_str(node->type));
292
293 AstPrint new_ap;
294 new_ap.indent = ap->indent + 2;
295 new_ap.f = ap->f;
296
297 ast_visit_node_children(node, ast_print_visit, &new_ap);
298}
299
300void ast_print(FILE *f, AstNode *node, int indent) {
301 AstPrint ap;
302 ap.indent = indent;
303 ap.f = f;
304 ast_visit_node_children(node, ast_print_visit, &ap);
305}
306
307
308struct AstRender {
309 int indent;
310 int indent_size;
311 FILE *f;
312};
313
314static void print_indent(AstRender *ar) {
315 for (int i = 0; i < ar->indent; i += 1) {
316 fprintf(ar->f, " ");
317 }
318}
319
320static bool is_alpha_under(uint8_t c) {
321 return (c >= 'a' && c <= 'z') ||
322 (c >= 'A' && c <= 'Z') || c == '_';
323}
324
325static bool is_digit(uint8_t c) {
326 return (c >= '0' && c <= '9');
327}
328
329static bool is_printable(uint8_t c) {
330 if (c == 0) {
331 return false;
332 }
333 static const uint8_t printables[] =
334 " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.~`!@#$%^&*()_-+=\\{}[];'\"?/<>,:";
335 for (size_t i = 0; i < array_length(printables); i += 1) {
336 if (c == printables[i]) return true;
337 }
338 return false;
339}
340
341static void string_literal_escape(Buf *source, Buf *dest) {
342 buf_resize(dest, 0);
343 for (size_t i = 0; i < buf_len(source); i += 1) {
344 uint8_t c = *((uint8_t*)buf_ptr(source) + i);
345 if (c == '\'') {
346 buf_append_str(dest, "\\'");
347 } else if (c == '"') {
348 buf_append_str(dest, "\\\"");
349 } else if (c == '\\') {
350 buf_append_str(dest, "\\\\");
351 } else if (c == '\n') {
352 buf_append_str(dest, "\\n");
353 } else if (c == '\r') {
354 buf_append_str(dest, "\\r");
355 } else if (c == '\t') {
356 buf_append_str(dest, "\\t");
357 } else if (is_printable(c)) {
358 buf_append_char(dest, c);
359 } else {
360 buf_appendf(dest, "\\x%02x", (int)c);
361 }
362 }
363}
364
365static bool is_valid_bare_symbol(Buf *symbol) {
366 if (buf_len(symbol) == 0) {
367 return false;
368 }
369 uint8_t first_char = *buf_ptr(symbol);
370 if (!is_alpha_under(first_char)) {
371 return false;
372 }
373 for (size_t i = 1; i < buf_len(symbol); i += 1) {
374 uint8_t c = *((uint8_t*)buf_ptr(symbol) + i);
375 if (!is_alpha_under(c) && !is_digit(c)) {
376 return false;
377 }
378 }
379 return true;
380}
381
382static void print_symbol(AstRender *ar, Buf *symbol) {
383 if (is_zig_keyword(symbol)) {
384 fprintf(ar->f, "@\"%s\"", buf_ptr(symbol));
385 return;
386 }
387 if (is_valid_bare_symbol(symbol)) {
388 fprintf(ar->f, "%s", buf_ptr(symbol));
389 return;
390 }
391 Buf escaped = BUF_INIT;
392 string_literal_escape(symbol, &escaped);
393 fprintf(ar->f, "@\"%s\"", buf_ptr(&escaped));
394}
395
396static bool statement_terminates_without_semicolon(AstNode *node) {
397 switch (node->type) {
398 case NodeTypeIfBoolExpr:
399 if (node->data.if_bool_expr.else_node)
400 return statement_terminates_without_semicolon(node->data.if_bool_expr.else_node);
401 return node->data.if_bool_expr.then_block->type == NodeTypeBlock;
402 case NodeTypeIfErrorExpr:
403 if (node->data.if_err_expr.else_node)
404 return statement_terminates_without_semicolon(node->data.if_err_expr.else_node);
405 return node->data.if_err_expr.then_node->type == NodeTypeBlock;
406 case NodeTypeIfOptional:
407 if (node->data.test_expr.else_node)
408 return statement_terminates_without_semicolon(node->data.test_expr.else_node);
409 return node->data.test_expr.then_node->type == NodeTypeBlock;
410 case NodeTypeWhileExpr:
411 return node->data.while_expr.body->type == NodeTypeBlock;
412 case NodeTypeForExpr:
413 return node->data.for_expr.body->type == NodeTypeBlock;
414 case NodeTypeCompTime:
415 return node->data.comptime_expr.expr->type == NodeTypeBlock;
416 case NodeTypeDefer:
417 return node->data.defer.expr->type == NodeTypeBlock;
418 case NodeTypeSuspend:
419 return node->data.suspend.block != nullptr && node->data.suspend.block->type == NodeTypeBlock;
420 case NodeTypeSwitchExpr:
421 case NodeTypeBlock:
422 return true;
423 default:
424 return false;
425 }
426}
427
428static void render_node_extra(AstRender *ar, AstNode *node, bool grouped);
429
430static void render_node_grouped(AstRender *ar, AstNode *node) {
431 return render_node_extra(ar, node, true);
432}
433
434static void render_node_ungrouped(AstRender *ar, AstNode *node) {
435 return render_node_extra(ar, node, false);
436}
437
438static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
439 switch (node->type) {
440 case NodeTypeSwitchProng:
441 case NodeTypeSwitchRange:
442 case NodeTypeStructValueField:
443 zig_unreachable();
444 case NodeTypeFnProto:
445 {
446 const char *pub_str = visib_mod_string(node->data.fn_proto.visib_mod);
447 const char *extern_str = extern_string(node->data.fn_proto.is_extern);
448 const char *export_str = export_string(node->data.fn_proto.is_export);
449 const char *inline_str = inline_string(node->data.fn_proto.fn_inline);
450 fprintf(ar->f, "%s%s%s%sfn ", pub_str, inline_str, export_str, extern_str);
451 if (node->data.fn_proto.name != nullptr) {
452 print_symbol(ar, node->data.fn_proto.name);
453 }
454 fprintf(ar->f, "(");
455 size_t arg_count = node->data.fn_proto.params.length;
456 for (size_t arg_i = 0; arg_i < arg_count; arg_i += 1) {
457 AstNode *param_decl = node->data.fn_proto.params.at(arg_i);
458 assert(param_decl->type == NodeTypeParamDecl);
459 if (param_decl->data.param_decl.name != nullptr) {
460 const char *noalias_str = param_decl->data.param_decl.is_noalias ? "noalias " : "";
461 const char *inline_str = param_decl->data.param_decl.is_comptime ? "comptime " : "";
462 fprintf(ar->f, "%s%s", noalias_str, inline_str);
463 print_symbol(ar, param_decl->data.param_decl.name);
464 fprintf(ar->f, ": ");
465 }
466 if (param_decl->data.param_decl.is_var_args) {
467 fprintf(ar->f, "...");
468 } else if (param_decl->data.param_decl.anytype_token != nullptr) {
469 fprintf(ar->f, "anytype");
470 } else {
471 render_node_grouped(ar, param_decl->data.param_decl.type);
472 }
473
474 if (arg_i + 1 < arg_count) {
475 fprintf(ar->f, ", ");
476 }
477 }
478 if (node->data.fn_proto.is_var_args) {
479 fprintf(ar->f, ", ...");
480 }
481 fprintf(ar->f, ")");
482 if (node->data.fn_proto.align_expr) {
483 fprintf(ar->f, " align(");
484 render_node_grouped(ar, node->data.fn_proto.align_expr);
485 fprintf(ar->f, ")");
486 }
487 if (node->data.fn_proto.section_expr) {
488 fprintf(ar->f, " section(");
489 render_node_grouped(ar, node->data.fn_proto.section_expr);
490 fprintf(ar->f, ")");
491 }
492 if (node->data.fn_proto.callconv_expr) {
493 fprintf(ar->f, " callconv(");
494 render_node_grouped(ar, node->data.fn_proto.callconv_expr);
495 fprintf(ar->f, ")");
496 }
497
498 AstNode *return_type_node = node->data.fn_proto.return_type;
499 assert(return_type_node != nullptr);
500 fprintf(ar->f, " ");
501 if (node->data.fn_proto.auto_err_set) {
502 fprintf(ar->f, "!");
503 }
504 render_node_grouped(ar, return_type_node);
505 break;
506 }
507 case NodeTypeFnDef:
508 {
509 render_node_grouped(ar, node->data.fn_def.fn_proto);
510 fprintf(ar->f, " ");
511 render_node_grouped(ar, node->data.fn_def.body);
512 break;
513 }
514 case NodeTypeBlock:
515 if (node->data.block.name != nullptr) {
516 fprintf(ar->f, "%s: ", buf_ptr(node->data.block.name));
517 }
518 if (node->data.block.statements.length == 0) {
519 fprintf(ar->f, "{}");
520 break;
521 }
522 fprintf(ar->f, "{\n");
523 ar->indent += ar->indent_size;
524 for (size_t i = 0; i < node->data.block.statements.length; i += 1) {
525 AstNode *statement = node->data.block.statements.at(i);
526 print_indent(ar);
527 render_node_grouped(ar, statement);
528
529 if (!statement_terminates_without_semicolon(statement))
530 fprintf(ar->f, ";");
531
532 fprintf(ar->f, "\n");
533 }
534 ar->indent -= ar->indent_size;
535 print_indent(ar);
536 fprintf(ar->f, "}");
537 break;
538 case NodeTypeGroupedExpr:
539 fprintf(ar->f, "(");
540 render_node_ungrouped(ar, node->data.grouped_expr);
541 fprintf(ar->f, ")");
542 break;
543 case NodeTypeReturnExpr:
544 {
545 const char *return_str = return_string(node->data.return_expr.kind);
546 fprintf(ar->f, "%s", return_str);
547 if (node->data.return_expr.expr) {
548 fprintf(ar->f, " ");
549 render_node_grouped(ar, node->data.return_expr.expr);
550 }
551 break;
552 }
553 case NodeTypeBreak:
554 {
555 fprintf(ar->f, "break");
556 if (node->data.break_expr.name != nullptr) {
557 fprintf(ar->f, " :%s", buf_ptr(node->data.break_expr.name));
558 }
559 if (node->data.break_expr.expr) {
560 fprintf(ar->f, " ");
561 render_node_grouped(ar, node->data.break_expr.expr);
562 }
563 break;
564 }
565 case NodeTypeDefer:
566 {
567 const char *defer_str = defer_string(node->data.defer.kind);
568 fprintf(ar->f, "%s ", defer_str);
569 render_node_grouped(ar, node->data.defer.expr);
570 break;
571 }
572 case NodeTypeVariableDeclaration:
573 {
574 const char *pub_str = visib_mod_string(node->data.variable_declaration.visib_mod);
575 const char *extern_str = extern_string(node->data.variable_declaration.is_extern);
576 const char *thread_local_str = thread_local_string(node->data.variable_declaration.threadlocal_tok);
577 const char *const_or_var = const_or_var_string(node->data.variable_declaration.is_const);
578 fprintf(ar->f, "%s%s%s%s ", pub_str, extern_str, thread_local_str, const_or_var);
579 print_symbol(ar, node->data.variable_declaration.symbol);
580
581 if (node->data.variable_declaration.type) {
582 fprintf(ar->f, ": ");
583 render_node_grouped(ar, node->data.variable_declaration.type);
584 }
585 if (node->data.variable_declaration.align_expr) {
586 fprintf(ar->f, "align(");
587 render_node_grouped(ar, node->data.variable_declaration.align_expr);
588 fprintf(ar->f, ") ");
589 }
590 if (node->data.variable_declaration.section_expr) {
591 fprintf(ar->f, "section(");
592 render_node_grouped(ar, node->data.variable_declaration.section_expr);
593 fprintf(ar->f, ") ");
594 }
595 if (node->data.variable_declaration.expr) {
596 fprintf(ar->f, " = ");
597 render_node_grouped(ar, node->data.variable_declaration.expr);
598 }
599 break;
600 }
601 case NodeTypeBinOpExpr:
602 if (!grouped) fprintf(ar->f, "(");
603 render_node_ungrouped(ar, node->data.bin_op_expr.op1);
604 fprintf(ar->f, " %s ", bin_op_str(node->data.bin_op_expr.bin_op));
605 render_node_ungrouped(ar, node->data.bin_op_expr.op2);
606 if (!grouped) fprintf(ar->f, ")");
607 break;
608 case NodeTypeFloatLiteral:
609 {
610 Buf rendered_buf = BUF_INIT;
611 buf_resize(&rendered_buf, 0);
612 bigfloat_append_buf(&rendered_buf, node->data.float_literal.bigfloat);
613 fprintf(ar->f, "%s", buf_ptr(&rendered_buf));
614 }
615 break;
616 case NodeTypeIntLiteral:
617 {
618 Buf rendered_buf = BUF_INIT;
619 buf_resize(&rendered_buf, 0);
620 bigint_append_buf(&rendered_buf, node->data.int_literal.bigint, 10);
621 fprintf(ar->f, "%s", buf_ptr(&rendered_buf));
622 }
623 break;
624 case NodeTypeStringLiteral:
625 {
626 Buf tmp_buf = BUF_INIT;
627 string_literal_escape(node->data.string_literal.buf, &tmp_buf);
628 fprintf(ar->f, "\"%s\"", buf_ptr(&tmp_buf));
629 }
630 break;
631 case NodeTypeCharLiteral:
632 {
633 uint8_t c = node->data.char_literal.value;
634 if (c == '\'') {
635 fprintf(ar->f, "'\\''");
636 } else if (c == '\"') {
637 fprintf(ar->f, "'\\\"'");
638 } else if (c == '\\') {
639 fprintf(ar->f, "'\\\\'");
640 } else if (c == '\n') {
641 fprintf(ar->f, "'\\n'");
642 } else if (c == '\r') {
643 fprintf(ar->f, "'\\r'");
644 } else if (c == '\t') {
645 fprintf(ar->f, "'\\t'");
646 } else if (is_printable(c)) {
647 fprintf(ar->f, "'%c'", c);
648 } else {
649 fprintf(ar->f, "'\\x%02x'", (int)c);
650 }
651 break;
652 }
653 case NodeTypeSymbol:
654 print_symbol(ar, node->data.symbol_expr.symbol);
655 break;
656 case NodeTypePrefixOpExpr:
657 {
658 if (!grouped) fprintf(ar->f, "(");
659 PrefixOp op = node->data.prefix_op_expr.prefix_op;
660 fprintf(ar->f, "%s", prefix_op_str(op));
661
662 AstNode *child_node = node->data.prefix_op_expr.primary_expr;
663 bool new_grouped = child_node->type == NodeTypePrefixOpExpr || child_node->type == NodeTypePointerType;
664 render_node_extra(ar, child_node, new_grouped);
665 if (!grouped) fprintf(ar->f, ")");
666 break;
667 }
668 case NodeTypePointerType:
669 {
670 if (!grouped) fprintf(ar->f, "(");
671 const char *ptr_len_str = token_to_ptr_len_str(node->data.pointer_type.star_token);
672 fprintf(ar->f, "%s", ptr_len_str);
673 if (node->data.pointer_type.align_expr != nullptr) {
674 fprintf(ar->f, "align(");
675 render_node_grouped(ar, node->data.pointer_type.align_expr);
676 if (node->data.pointer_type.bit_offset_start != nullptr) {
677 assert(node->data.pointer_type.host_int_bytes != nullptr);
678
679 Buf offset_start_buf = BUF_INIT;
680 buf_resize(&offset_start_buf, 0);
681 bigint_append_buf(&offset_start_buf, node->data.pointer_type.bit_offset_start, 10);
682
683 Buf offset_end_buf = BUF_INIT;
684 buf_resize(&offset_end_buf, 0);
685 bigint_append_buf(&offset_end_buf, node->data.pointer_type.host_int_bytes, 10);
686
687 fprintf(ar->f, ":%s:%s ", buf_ptr(&offset_start_buf), buf_ptr(&offset_end_buf));
688 }
689 fprintf(ar->f, ") ");
690 }
691 if (node->data.pointer_type.is_const) {
692 fprintf(ar->f, "const ");
693 }
694 if (node->data.pointer_type.is_volatile) {
695 fprintf(ar->f, "volatile ");
696 }
697
698 render_node_ungrouped(ar, node->data.pointer_type.op_expr);
699 if (!grouped) fprintf(ar->f, ")");
700 break;
701 }
702 case NodeTypeFnCallExpr:
703 {
704 switch (node->data.fn_call_expr.modifier) {
705 case CallModifierNone:
706 break;
707 case CallModifierNoSuspend:
708 fprintf(ar->f, "nosuspend ");
709 break;
710 case CallModifierAsync:
711 fprintf(ar->f, "async ");
712 break;
713 case CallModifierNeverTail:
714 fprintf(ar->f, "notail ");
715 break;
716 case CallModifierNeverInline:
717 fprintf(ar->f, "noinline ");
718 break;
719 case CallModifierAlwaysTail:
720 fprintf(ar->f, "tail ");
721 break;
722 case CallModifierAlwaysInline:
723 fprintf(ar->f, "inline ");
724 break;
725 case CallModifierCompileTime:
726 fprintf(ar->f, "comptime ");
727 break;
728 case CallModifierBuiltin:
729 fprintf(ar->f, "@");
730 break;
731 }
732 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
733 bool grouped = (fn_ref_node->type != NodeTypePrefixOpExpr && fn_ref_node->type != NodeTypePointerType);
734 render_node_extra(ar, fn_ref_node, grouped);
735 fprintf(ar->f, "(");
736 for (size_t i = 0; i < node->data.fn_call_expr.params.length; i += 1) {
737 AstNode *param = node->data.fn_call_expr.params.at(i);
738 if (i != 0) {
739 fprintf(ar->f, ", ");
740 }
741 render_node_grouped(ar, param);
742 }
743 fprintf(ar->f, ")");
744 break;
745 }
746 case NodeTypeArrayAccessExpr:
747 render_node_ungrouped(ar, node->data.array_access_expr.array_ref_expr);
748 fprintf(ar->f, "[");
749 render_node_grouped(ar, node->data.array_access_expr.subscript);
750 fprintf(ar->f, "]");
751 break;
752 case NodeTypeFieldAccessExpr:
753 {
754 AstNode *lhs = node->data.field_access_expr.struct_expr;
755 Buf *rhs = node->data.field_access_expr.field_name;
756 if (lhs->type == NodeTypeErrorType) {
757 fprintf(ar->f, "error");
758 } else {
759 render_node_ungrouped(ar, lhs);
760 }
761 fprintf(ar->f, ".");
762 print_symbol(ar, rhs);
763 break;
764 }
765 case NodeTypePtrDeref:
766 {
767 AstNode *lhs = node->data.ptr_deref_expr.target;
768 render_node_ungrouped(ar, lhs);
769 fprintf(ar->f, ".*");
770 break;
771 }
772 case NodeTypeUnwrapOptional:
773 {
774 AstNode *lhs = node->data.unwrap_optional.expr;
775 render_node_ungrouped(ar, lhs);
776 fprintf(ar->f, ".?");
777 break;
778 }
779 case NodeTypeUndefinedLiteral:
780 fprintf(ar->f, "undefined");
781 break;
782 case NodeTypeContainerDecl:
783 {
784 if (!node->data.container_decl.is_root) {
785 const char *layout_str = layout_string(node->data.container_decl.layout);
786 const char *container_str = container_string(node->data.container_decl.kind);
787 fprintf(ar->f, "%s%s", layout_str, container_str);
788 if (node->data.container_decl.auto_enum) {
789 fprintf(ar->f, "(enum");
790 }
791 if (node->data.container_decl.init_arg_expr != nullptr) {
792 fprintf(ar->f, "(");
793 render_node_grouped(ar, node->data.container_decl.init_arg_expr);
794 fprintf(ar->f, ")");
795 }
796 if (node->data.container_decl.auto_enum) {
797 fprintf(ar->f, ")");
798 }
799
800 fprintf(ar->f, " {\n");
801 ar->indent += ar->indent_size;
802 }
803 for (size_t field_i = 0; field_i < node->data.container_decl.fields.length; field_i += 1) {
804 AstNode *field_node = node->data.container_decl.fields.at(field_i);
805 assert(field_node->type == NodeTypeStructField);
806 print_indent(ar);
807 print_symbol(ar, field_node->data.struct_field.name);
808 if (field_node->data.struct_field.type != nullptr) {
809 fprintf(ar->f, ": ");
810 render_node_grouped(ar, field_node->data.struct_field.type);
811 }
812 if (field_node->data.struct_field.value != nullptr) {
813 fprintf(ar->f, " = ");
814 render_node_grouped(ar, field_node->data.struct_field.value);
815 }
816 fprintf(ar->f, ",\n");
817 }
818
819 for (size_t decl_i = 0; decl_i < node->data.container_decl.decls.length; decl_i += 1) {
820 AstNode *decls_node = node->data.container_decl.decls.at(decl_i);
821 render_node_grouped(ar, decls_node);
822
823 if (decls_node->type == NodeTypeUsingNamespace ||
824 decls_node->type == NodeTypeVariableDeclaration ||
825 decls_node->type == NodeTypeFnProto)
826 {
827 fprintf(ar->f, ";");
828 }
829 fprintf(ar->f, "\n");
830 }
831
832 if (!node->data.container_decl.is_root) {
833 ar->indent -= ar->indent_size;
834 print_indent(ar);
835 fprintf(ar->f, "}");
836 }
837 break;
838 }
839 case NodeTypeContainerInitExpr:
840 if (node->data.container_init_expr.type != nullptr) {
841 render_node_ungrouped(ar, node->data.container_init_expr.type);
842 }
843 if (node->data.container_init_expr.kind == ContainerInitKindStruct) {
844 fprintf(ar->f, "{\n");
845 ar->indent += ar->indent_size;
846 } else {
847 fprintf(ar->f, "{");
848 }
849 for (size_t i = 0; i < node->data.container_init_expr.entries.length; i += 1) {
850 AstNode *entry = node->data.container_init_expr.entries.at(i);
851 if (entry->type == NodeTypeStructValueField) {
852 Buf *name = entry->data.struct_val_field.name;
853 AstNode *expr = entry->data.struct_val_field.expr;
854 print_indent(ar);
855 fprintf(ar->f, ".%s = ", buf_ptr(name));
856 render_node_grouped(ar, expr);
857 fprintf(ar->f, ",\n");
858 } else {
859 if (i != 0)
860 fprintf(ar->f, ", ");
861 render_node_grouped(ar, entry);
862 }
863 }
864 if (node->data.container_init_expr.kind == ContainerInitKindStruct) {
865 ar->indent -= ar->indent_size;
866 }
867 print_indent(ar);
868 fprintf(ar->f, "}");
869 break;
870 case NodeTypeArrayType:
871 {
872 fprintf(ar->f, "[");
873 if (node->data.array_type.size) {
874 render_node_grouped(ar, node->data.array_type.size);
875 }
876 fprintf(ar->f, "]");
877 if (node->data.array_type.is_const) {
878 fprintf(ar->f, "const ");
879 }
880 render_node_ungrouped(ar, node->data.array_type.child_type);
881 break;
882 }
883 case NodeTypeInferredArrayType:
884 {
885 fprintf(ar->f, "[_]");
886 render_node_ungrouped(ar, node->data.inferred_array_type.child_type);
887 break;
888 }
889 case NodeTypeAnyFrameType: {
890 fprintf(ar->f, "anyframe");
891 if (node->data.anyframe_type.payload_type != nullptr) {
892 fprintf(ar->f, "->");
893 render_node_grouped(ar, node->data.anyframe_type.payload_type);
894 }
895 break;
896 }
897 case NodeTypeErrorType:
898 fprintf(ar->f, "anyerror");
899 break;
900 case NodeTypeAsmExpr:
901 {
902 AstNodeAsmExpr *asm_expr = &node->data.asm_expr;
903 const char *volatile_str = (asm_expr->volatile_token != nullptr) ? " volatile" : "";
904 fprintf(ar->f, "asm%s (", volatile_str);
905 render_node_ungrouped(ar, asm_expr->asm_template);
906 fprintf(ar->f, ")");
907 print_indent(ar);
908 fprintf(ar->f, ": ");
909 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) {
910 AsmOutput *asm_output = asm_expr->output_list.at(i);
911
912 if (i != 0) {
913 fprintf(ar->f, ",\n");
914 print_indent(ar);
915 }
916
917 fprintf(ar->f, "[%s] \"%s\" (",
918 buf_ptr(asm_output->asm_symbolic_name),
919 buf_ptr(asm_output->constraint));
920 if (asm_output->return_type) {
921 fprintf(ar->f, "-> ");
922 render_node_grouped(ar, asm_output->return_type);
923 } else {
924 fprintf(ar->f, "%s", buf_ptr(asm_output->variable_name));
925 }
926 fprintf(ar->f, ")");
927 }
928 fprintf(ar->f, "\n");
929 print_indent(ar);
930 fprintf(ar->f, ": ");
931 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) {
932 AsmInput *asm_input = asm_expr->input_list.at(i);
933
934 if (i != 0) {
935 fprintf(ar->f, ",\n");
936 print_indent(ar);
937 }
938
939 fprintf(ar->f, "[%s] \"%s\" (",
940 buf_ptr(asm_input->asm_symbolic_name),
941 buf_ptr(asm_input->constraint));
942 render_node_grouped(ar, asm_input->expr);
943 fprintf(ar->f, ")");
944 }
945 fprintf(ar->f, "\n");
946 print_indent(ar);
947 fprintf(ar->f, ": ");
948 for (size_t i = 0; i < asm_expr->clobber_list.length; i += 1) {
949 Buf *reg_name = asm_expr->clobber_list.at(i);
950 if (i != 0) fprintf(ar->f, ", ");
951 fprintf(ar->f, "\"%s\"", buf_ptr(reg_name));
952 }
953 fprintf(ar->f, ")");
954 break;
955 }
956 case NodeTypeWhileExpr:
957 {
958 if (node->data.while_expr.name != nullptr) {
959 fprintf(ar->f, "%s: ", buf_ptr(node->data.while_expr.name));
960 }
961 const char *inline_str = node->data.while_expr.is_inline ? "inline " : "";
962 fprintf(ar->f, "%swhile (", inline_str);
963 render_node_grouped(ar, node->data.while_expr.condition);
964 fprintf(ar->f, ") ");
965 if (node->data.while_expr.var_symbol) {
966 fprintf(ar->f, "|%s| ", buf_ptr(node->data.while_expr.var_symbol));
967 }
968 if (node->data.while_expr.continue_expr) {
969 fprintf(ar->f, ": (");
970 render_node_grouped(ar, node->data.while_expr.continue_expr);
971 fprintf(ar->f, ") ");
972 }
973 render_node_grouped(ar, node->data.while_expr.body);
974 if (node->data.while_expr.else_node) {
975 fprintf(ar->f, " else ");
976 if (node->data.while_expr.err_symbol) {
977 fprintf(ar->f, "|%s| ", buf_ptr(node->data.while_expr.err_symbol));
978 }
979 render_node_grouped(ar, node->data.while_expr.else_node);
980 }
981 break;
982 }
983 case NodeTypeBoolLiteral:
984 {
985 const char *bool_str = node->data.bool_literal.value ? "true" : "false";
986 fprintf(ar->f, "%s", bool_str);
987 break;
988 }
989 case NodeTypeIfBoolExpr:
990 {
991 fprintf(ar->f, "if (");
992 render_node_grouped(ar, node->data.if_bool_expr.condition);
993 fprintf(ar->f, ") ");
994 render_node_grouped(ar, node->data.if_bool_expr.then_block);
995 if (node->data.if_bool_expr.else_node) {
996 fprintf(ar->f, " else ");
997 render_node_grouped(ar, node->data.if_bool_expr.else_node);
998 }
999 break;
1000 }
1001 case NodeTypeNullLiteral:
1002 {
1003 fprintf(ar->f, "null");
1004 break;
1005 }
1006 case NodeTypeIfErrorExpr:
1007 {
1008 fprintf(ar->f, "if (");
1009 render_node_grouped(ar, node->data.if_err_expr.target_node);
1010 fprintf(ar->f, ") ");
1011 if (node->data.if_err_expr.var_symbol) {
1012 const char *ptr_str = node->data.if_err_expr.var_is_ptr ? "*" : "";
1013 const char *var_name = buf_ptr(node->data.if_err_expr.var_symbol);
1014 fprintf(ar->f, "|%s%s| ", ptr_str, var_name);
1015 }
1016 render_node_grouped(ar, node->data.if_err_expr.then_node);
1017 if (node->data.if_err_expr.else_node) {
1018 fprintf(ar->f, " else ");
1019 if (node->data.if_err_expr.err_symbol) {
1020 fprintf(ar->f, "|%s| ", buf_ptr(node->data.if_err_expr.err_symbol));
1021 }
1022 render_node_grouped(ar, node->data.if_err_expr.else_node);
1023 }
1024 break;
1025 }
1026 case NodeTypeIfOptional:
1027 {
1028 fprintf(ar->f, "if (");
1029 render_node_grouped(ar, node->data.test_expr.target_node);
1030 fprintf(ar->f, ") ");
1031 if (node->data.test_expr.var_symbol) {
1032 const char *ptr_str = node->data.test_expr.var_is_ptr ? "*" : "";
1033 const char *var_name = buf_ptr(node->data.test_expr.var_symbol);
1034 fprintf(ar->f, "|%s%s| ", ptr_str, var_name);
1035 }
1036 render_node_grouped(ar, node->data.test_expr.then_node);
1037 if (node->data.test_expr.else_node) {
1038 fprintf(ar->f, " else ");
1039 render_node_grouped(ar, node->data.test_expr.else_node);
1040 }
1041 break;
1042 }
1043 case NodeTypeSwitchExpr:
1044 {
1045 AstNodeSwitchExpr *switch_expr = &node->data.switch_expr;
1046 fprintf(ar->f, "switch (");
1047 render_node_grouped(ar, switch_expr->expr);
1048 fprintf(ar->f, ") {\n");
1049 ar->indent += ar->indent_size;
1050
1051 for (size_t prong_i = 0; prong_i < switch_expr->prongs.length; prong_i += 1) {
1052 AstNode *prong_node = switch_expr->prongs.at(prong_i);
1053 AstNodeSwitchProng *switch_prong = &prong_node->data.switch_prong;
1054 print_indent(ar);
1055 for (size_t item_i = 0; item_i < switch_prong->items.length; item_i += 1) {
1056 AstNode *item_node = switch_prong->items.at(item_i);
1057 if (item_i != 0)
1058 fprintf(ar->f, ", ");
1059 if (item_node->type == NodeTypeSwitchRange) {
1060 AstNode *start_node = item_node->data.switch_range.start;
1061 AstNode *end_node = item_node->data.switch_range.end;
1062 render_node_grouped(ar, start_node);
1063 fprintf(ar->f, "...");
1064 render_node_grouped(ar, end_node);
1065 } else {
1066 render_node_grouped(ar, item_node);
1067 }
1068 }
1069 const char *else_str = (switch_prong->items.length == 0) ? "else" : "";
1070 fprintf(ar->f, "%s => ", else_str);
1071 if (switch_prong->var_symbol) {
1072 const char *star_str = switch_prong->var_is_ptr ? "*" : "";
1073 Buf *var_name = switch_prong->var_symbol->data.symbol_expr.symbol;
1074 fprintf(ar->f, "|%s%s| ", star_str, buf_ptr(var_name));
1075 }
1076 render_node_grouped(ar, switch_prong->expr);
1077 fprintf(ar->f, ",\n");
1078 }
1079
1080 ar->indent -= ar->indent_size;
1081 print_indent(ar);
1082 fprintf(ar->f, "}");
1083 break;
1084 }
1085 case NodeTypeCompTime:
1086 {
1087 fprintf(ar->f, "comptime ");
1088 render_node_grouped(ar, node->data.comptime_expr.expr);
1089 break;
1090 }
1091 case NodeTypeNoSuspend:
1092 {
1093 fprintf(ar->f, "nosuspend ");
1094 render_node_grouped(ar, node->data.nosuspend_expr.expr);
1095 break;
1096 }
1097 case NodeTypeForExpr:
1098 {
1099 if (node->data.for_expr.name != nullptr) {
1100 fprintf(ar->f, "%s: ", buf_ptr(node->data.for_expr.name));
1101 }
1102 const char *inline_str = node->data.for_expr.is_inline ? "inline " : "";
1103 fprintf(ar->f, "%sfor (", inline_str);
1104 render_node_grouped(ar, node->data.for_expr.array_expr);
1105 fprintf(ar->f, ") ");
1106 if (node->data.for_expr.elem_node) {
1107 fprintf(ar->f, "|");
1108 if (node->data.for_expr.elem_is_ptr)
1109 fprintf(ar->f, "*");
1110 render_node_grouped(ar, node->data.for_expr.elem_node);
1111 if (node->data.for_expr.index_node) {
1112 fprintf(ar->f, ", ");
1113 render_node_grouped(ar, node->data.for_expr.index_node);
1114 }
1115 fprintf(ar->f, "| ");
1116 }
1117 render_node_grouped(ar, node->data.for_expr.body);
1118 if (node->data.for_expr.else_node) {
1119 fprintf(ar->f, " else");
1120 render_node_grouped(ar, node->data.for_expr.else_node);
1121 }
1122 break;
1123 }
1124 case NodeTypeContinue:
1125 {
1126 fprintf(ar->f, "continue");
1127 if (node->data.continue_expr.name != nullptr) {
1128 fprintf(ar->f, " :%s", buf_ptr(node->data.continue_expr.name));
1129 }
1130 break;
1131 }
1132 case NodeTypeUnreachable:
1133 {
1134 fprintf(ar->f, "unreachable");
1135 break;
1136 }
1137 case NodeTypeSliceExpr:
1138 {
1139 render_node_ungrouped(ar, node->data.slice_expr.array_ref_expr);
1140 fprintf(ar->f, "[");
1141 render_node_grouped(ar, node->data.slice_expr.start);
1142 fprintf(ar->f, "..");
1143 if (node->data.slice_expr.end)
1144 render_node_grouped(ar, node->data.slice_expr.end);
1145 fprintf(ar->f, "]");
1146 break;
1147 }
1148 case NodeTypeCatchExpr:
1149 {
1150 render_node_ungrouped(ar, node->data.unwrap_err_expr.op1);
1151 fprintf(ar->f, " catch ");
1152 if (node->data.unwrap_err_expr.symbol) {
1153 Buf *var_name = node->data.unwrap_err_expr.symbol->data.symbol_expr.symbol;
1154 fprintf(ar->f, "|%s| ", buf_ptr(var_name));
1155 }
1156 render_node_ungrouped(ar, node->data.unwrap_err_expr.op2);
1157 break;
1158 }
1159 case NodeTypeErrorSetDecl:
1160 {
1161 fprintf(ar->f, "error {\n");
1162 ar->indent += ar->indent_size;
1163
1164 for (size_t i = 0; i < node->data.err_set_decl.decls.length; i += 1) {
1165 AstNode *field_node = node->data.err_set_decl.decls.at(i);
1166 switch (field_node->type) {
1167 case NodeTypeSymbol:
1168 print_indent(ar);
1169 print_symbol(ar, field_node->data.symbol_expr.symbol);
1170 fprintf(ar->f, ",\n");
1171 break;
1172 case NodeTypeErrorSetField:
1173 print_indent(ar);
1174 print_symbol(ar, field_node->data.err_set_field.field_name->data.symbol_expr.symbol);
1175 fprintf(ar->f, ",\n");
1176 break;
1177 default:
1178 zig_unreachable();
1179 }
1180 }
1181
1182 ar->indent -= ar->indent_size;
1183 print_indent(ar);
1184 fprintf(ar->f, "}");
1185 break;
1186 }
1187 case NodeTypeResume:
1188 {
1189 fprintf(ar->f, "resume ");
1190 render_node_grouped(ar, node->data.resume_expr.expr);
1191 break;
1192 }
1193 case NodeTypeAwaitExpr:
1194 {
1195 fprintf(ar->f, "await ");
1196 render_node_grouped(ar, node->data.await_expr.expr);
1197 break;
1198 }
1199 case NodeTypeSuspend:
1200 {
1201 if (node->data.suspend.block != nullptr) {
1202 fprintf(ar->f, "suspend ");
1203 render_node_grouped(ar, node->data.suspend.block);
1204 } else {
1205 fprintf(ar->f, "suspend\n");
1206 }
1207 break;
1208 }
1209 case NodeTypeEnumLiteral:
1210 {
1211 fprintf(ar->f, ".%s", buf_ptr(&node->data.enum_literal.identifier->data.str_lit.str));
1212 break;
1213 }
1214 case NodeTypeAnyTypeField: {
1215 fprintf(ar->f, "anytype");
1216 break;
1217 }
1218 case NodeTypeParamDecl:
1219 case NodeTypeTestDecl:
1220 case NodeTypeStructField:
1221 case NodeTypeUsingNamespace:
1222 case NodeTypeErrorSetField:
1223 zig_panic("TODO more ast rendering");
1224 }
1225}
1226
1227
1228void ast_render(FILE *f, AstNode *node, int indent_size) {
1229 AstRender ar = {0};
1230 ar.f = f;
1231 ar.indent_size = indent_size;
1232 ar.indent = 0;
1233
1234 render_node_grouped(&ar, node);
1235}
1236
1237void AstNode::src() {
1238 fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize "\n",
1239 buf_ptr(this->owner->data.structure.root_struct->path),
1240 this->line + 1, this->column + 1);
1241}
src/stage1/ast_render.hpp deleted-20
......@@ -1,20 +0,0 @@
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_AST_RENDER_HPP
9#define ZIG_AST_RENDER_HPP
10
11#include "all_types.hpp"
12#include "parser.hpp"
13
14#include <stdio.h>
15
16void ast_print(FILE *f, AstNode *node, int indent);
17
18void ast_render(FILE *f, AstNode *node, int indent_size);
19
20#endif
src/stage1/astgen.cpp created+8119
......@@ -0,0 +1,8119 @@
1/*
2 * Copyright (c) 2021 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#include "astgen.hpp"
9#include "analyze.hpp"
10#include "util.hpp"
11#include "os.hpp"
12#include "parser.hpp"
13
14struct Stage1AstGen {
15 CodeGen *codegen;
16 Stage1Zir *exec;
17 Stage1ZirBasicBlock *current_basic_block;
18 AstNode *main_block_node;
19 size_t next_debug_id;
20 ZigFn *fn;
21 bool in_c_import_scope;
22};
23
24static IrInstSrc *astgen_node(Stage1AstGen *ag, AstNode *node, Scope *scope);
25static IrInstSrc *astgen_node_extra(Stage1AstGen *ag, AstNode *node, Scope *scope, LVal lval,
26 ResultLoc *result_loc);
27
28static IrInstSrc *ir_lval_wrap(Stage1AstGen *ag, Scope *scope, IrInstSrc *value, LVal lval,
29 ResultLoc *result_loc);
30static IrInstSrc *ir_expr_wrap(Stage1AstGen *ag, Scope *scope, IrInstSrc *inst,
31 ResultLoc *result_loc);
32static IrInstSrc *astgen_union_init_expr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
33 IrInstSrc *union_type, IrInstSrc *field_name, AstNode *expr_node,
34 LVal lval, ResultLoc *parent_result_loc);
35static ResultLocCast *ir_build_cast_result_loc(Stage1AstGen *ag, IrInstSrc *dest_type,
36 ResultLoc *parent_result_loc);
37static ZigVar *ir_create_var(Stage1AstGen *ag, AstNode *node, Scope *scope, Buf *name,
38 bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime);
39static void build_decl_var_and_init(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
40 ZigVar *var, IrInstSrc *init, const char *name_hint, IrInstSrc *is_comptime);
41
42static void ir_assert_impl(bool ok, IrInst *source_instruction, char const *file, unsigned int line) {
43 if (ok) return;
44 src_assert_impl(ok, source_instruction->source_node, file, line);
45}
46
47static ErrorMsg *exec_add_error_node(CodeGen *codegen, Stage1Zir *exec, AstNode *source_node, Buf *msg) {
48 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);
49 invalidate_exec(exec, err_msg);
50 return err_msg;
51}
52
53
54#define ir_assert(OK, SOURCE_INSTRUCTION) ir_assert_impl((OK), (SOURCE_INSTRUCTION), __FILE__, __LINE__)
55
56
57static bool instr_is_unreachable(IrInstSrc *instruction) {
58 return instruction->is_noreturn;
59}
60
61void destroy_instruction_src(IrInstSrc *inst) {
62 switch (inst->id) {
63 case IrInstSrcIdInvalid:
64 zig_unreachable();
65 case IrInstSrcIdReturn:
66 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcReturn *>(inst));
67 case IrInstSrcIdConst:
68 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcConst *>(inst));
69 case IrInstSrcIdBinOp:
70 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBinOp *>(inst));
71 case IrInstSrcIdMergeErrSets:
72 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMergeErrSets *>(inst));
73 case IrInstSrcIdDeclVar:
74 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcDeclVar *>(inst));
75 case IrInstSrcIdCall:
76 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCall *>(inst));
77 case IrInstSrcIdCallExtra:
78 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallExtra *>(inst));
79 case IrInstSrcIdAsyncCallExtra:
80 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAsyncCallExtra *>(inst));
81 case IrInstSrcIdUnOp:
82 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnOp *>(inst));
83 case IrInstSrcIdCondBr:
84 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCondBr *>(inst));
85 case IrInstSrcIdBr:
86 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBr *>(inst));
87 case IrInstSrcIdPhi:
88 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPhi *>(inst));
89 case IrInstSrcIdContainerInitList:
90 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcContainerInitList *>(inst));
91 case IrInstSrcIdContainerInitFields:
92 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcContainerInitFields *>(inst));
93 case IrInstSrcIdUnreachable:
94 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnreachable *>(inst));
95 case IrInstSrcIdElemPtr:
96 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcElemPtr *>(inst));
97 case IrInstSrcIdVarPtr:
98 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVarPtr *>(inst));
99 case IrInstSrcIdLoadPtr:
100 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcLoadPtr *>(inst));
101 case IrInstSrcIdStorePtr:
102 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcStorePtr *>(inst));
103 case IrInstSrcIdTypeOf:
104 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeOf *>(inst));
105 case IrInstSrcIdFieldPtr:
106 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFieldPtr *>(inst));
107 case IrInstSrcIdSetCold:
108 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetCold *>(inst));
109 case IrInstSrcIdSetRuntimeSafety:
110 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetRuntimeSafety *>(inst));
111 case IrInstSrcIdSetFloatMode:
112 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetFloatMode *>(inst));
113 case IrInstSrcIdArrayType:
114 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcArrayType *>(inst));
115 case IrInstSrcIdSliceType:
116 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSliceType *>(inst));
117 case IrInstSrcIdAnyFrameType:
118 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAnyFrameType *>(inst));
119 case IrInstSrcIdAsm:
120 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAsm *>(inst));
121 case IrInstSrcIdSizeOf:
122 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSizeOf *>(inst));
123 case IrInstSrcIdTestNonNull:
124 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestNonNull *>(inst));
125 case IrInstSrcIdOptionalUnwrapPtr:
126 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOptionalUnwrapPtr *>(inst));
127 case IrInstSrcIdPopCount:
128 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPopCount *>(inst));
129 case IrInstSrcIdClz:
130 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcClz *>(inst));
131 case IrInstSrcIdCtz:
132 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCtz *>(inst));
133 case IrInstSrcIdBswap:
134 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBswap *>(inst));
135 case IrInstSrcIdBitReverse:
136 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitReverse *>(inst));
137 case IrInstSrcIdSwitchBr:
138 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchBr *>(inst));
139 case IrInstSrcIdSwitchVar:
140 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchVar *>(inst));
141 case IrInstSrcIdSwitchElseVar:
142 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchElseVar *>(inst));
143 case IrInstSrcIdSwitchTarget:
144 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchTarget *>(inst));
145 case IrInstSrcIdImport:
146 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcImport *>(inst));
147 case IrInstSrcIdRef:
148 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcRef *>(inst));
149 case IrInstSrcIdCompileErr:
150 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCompileErr *>(inst));
151 case IrInstSrcIdCompileLog:
152 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCompileLog *>(inst));
153 case IrInstSrcIdErrName:
154 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrName *>(inst));
155 case IrInstSrcIdCImport:
156 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCImport *>(inst));
157 case IrInstSrcIdCInclude:
158 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCInclude *>(inst));
159 case IrInstSrcIdCDefine:
160 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCDefine *>(inst));
161 case IrInstSrcIdCUndef:
162 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCUndef *>(inst));
163 case IrInstSrcIdEmbedFile:
164 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEmbedFile *>(inst));
165 case IrInstSrcIdCmpxchg:
166 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCmpxchg *>(inst));
167 case IrInstSrcIdFence:
168 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFence *>(inst));
169 case IrInstSrcIdReduce:
170 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcReduce *>(inst));
171 case IrInstSrcIdTruncate:
172 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTruncate *>(inst));
173 case IrInstSrcIdIntCast:
174 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntCast *>(inst));
175 case IrInstSrcIdFloatCast:
176 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst));
177 case IrInstSrcIdErrSetCast:
178 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst));
179 case IrInstSrcIdIntToFloat:
180 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst));
181 case IrInstSrcIdFloatToInt:
182 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatToInt *>(inst));
183 case IrInstSrcIdBoolToInt:
184 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolToInt *>(inst));
185 case IrInstSrcIdVectorType:
186 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVectorType *>(inst));
187 case IrInstSrcIdShuffleVector:
188 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcShuffleVector *>(inst));
189 case IrInstSrcIdSplat:
190 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSplat *>(inst));
191 case IrInstSrcIdBoolNot:
192 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolNot *>(inst));
193 case IrInstSrcIdMemset:
194 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemset *>(inst));
195 case IrInstSrcIdMemcpy:
196 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemcpy *>(inst));
197 case IrInstSrcIdSlice:
198 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSlice *>(inst));
199 case IrInstSrcIdBreakpoint:
200 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBreakpoint *>(inst));
201 case IrInstSrcIdReturnAddress:
202 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcReturnAddress *>(inst));
203 case IrInstSrcIdFrameAddress:
204 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameAddress *>(inst));
205 case IrInstSrcIdFrameHandle:
206 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameHandle *>(inst));
207 case IrInstSrcIdFrameType:
208 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameType *>(inst));
209 case IrInstSrcIdFrameSize:
210 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameSize *>(inst));
211 case IrInstSrcIdAlignOf:
212 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlignOf *>(inst));
213 case IrInstSrcIdOverflowOp:
214 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOverflowOp *>(inst));
215 case IrInstSrcIdTestErr:
216 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestErr *>(inst));
217 case IrInstSrcIdUnwrapErrCode:
218 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnwrapErrCode *>(inst));
219 case IrInstSrcIdUnwrapErrPayload:
220 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnwrapErrPayload *>(inst));
221 case IrInstSrcIdFnProto:
222 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFnProto *>(inst));
223 case IrInstSrcIdTestComptime:
224 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestComptime *>(inst));
225 case IrInstSrcIdPtrCast:
226 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrCast *>(inst));
227 case IrInstSrcIdBitCast:
228 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitCast *>(inst));
229 case IrInstSrcIdPtrToInt:
230 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrToInt *>(inst));
231 case IrInstSrcIdIntToPtr:
232 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToPtr *>(inst));
233 case IrInstSrcIdIntToEnum:
234 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToEnum *>(inst));
235 case IrInstSrcIdIntToErr:
236 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToErr *>(inst));
237 case IrInstSrcIdErrToInt:
238 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrToInt *>(inst));
239 case IrInstSrcIdCheckSwitchProngsUnderNo:
240 case IrInstSrcIdCheckSwitchProngsUnderYes:
241 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckSwitchProngs *>(inst));
242 case IrInstSrcIdCheckStatementIsVoid:
243 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckStatementIsVoid *>(inst));
244 case IrInstSrcIdTypeName:
245 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeName *>(inst));
246 case IrInstSrcIdTagName:
247 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTagName *>(inst));
248 case IrInstSrcIdPtrType:
249 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrType *>(inst));
250 case IrInstSrcIdPtrTypeSimple:
251 case IrInstSrcIdPtrTypeSimpleConst:
252 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrTypeSimple *>(inst));
253 case IrInstSrcIdDeclRef:
254 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcDeclRef *>(inst));
255 case IrInstSrcIdPanic:
256 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPanic *>(inst));
257 case IrInstSrcIdFieldParentPtr:
258 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFieldParentPtr *>(inst));
259 case IrInstSrcIdByteOffsetOf:
260 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcByteOffsetOf *>(inst));
261 case IrInstSrcIdBitOffsetOf:
262 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitOffsetOf *>(inst));
263 case IrInstSrcIdTypeInfo:
264 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeInfo *>(inst));
265 case IrInstSrcIdType:
266 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcType *>(inst));
267 case IrInstSrcIdHasField:
268 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasField *>(inst));
269 case IrInstSrcIdSetEvalBranchQuota:
270 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetEvalBranchQuota *>(inst));
271 case IrInstSrcIdAlignCast:
272 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlignCast *>(inst));
273 case IrInstSrcIdImplicitCast:
274 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcImplicitCast *>(inst));
275 case IrInstSrcIdResolveResult:
276 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResolveResult *>(inst));
277 case IrInstSrcIdResetResult:
278 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResetResult *>(inst));
279 case IrInstSrcIdSetAlignStack:
280 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetAlignStack *>(inst));
281 case IrInstSrcIdArgTypeAllowVarFalse:
282 case IrInstSrcIdArgTypeAllowVarTrue:
283 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcArgType *>(inst));
284 case IrInstSrcIdExport:
285 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcExport *>(inst));
286 case IrInstSrcIdExtern:
287 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcExtern *>(inst));
288 case IrInstSrcIdErrorReturnTrace:
289 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrorReturnTrace *>(inst));
290 case IrInstSrcIdErrorUnion:
291 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrorUnion *>(inst));
292 case IrInstSrcIdAtomicRmw:
293 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicRmw *>(inst));
294 case IrInstSrcIdSaveErrRetAddr:
295 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSaveErrRetAddr *>(inst));
296 case IrInstSrcIdAddImplicitReturnType:
297 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAddImplicitReturnType *>(inst));
298 case IrInstSrcIdFloatOp:
299 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatOp *>(inst));
300 case IrInstSrcIdMulAdd:
301 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMulAdd *>(inst));
302 case IrInstSrcIdAtomicLoad:
303 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicLoad *>(inst));
304 case IrInstSrcIdAtomicStore:
305 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicStore *>(inst));
306 case IrInstSrcIdEnumToInt:
307 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEnumToInt *>(inst));
308 case IrInstSrcIdCheckRuntimeScope:
309 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckRuntimeScope *>(inst));
310 case IrInstSrcIdHasDecl:
311 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasDecl *>(inst));
312 case IrInstSrcIdUndeclaredIdent:
313 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUndeclaredIdent *>(inst));
314 case IrInstSrcIdAlloca:
315 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlloca *>(inst));
316 case IrInstSrcIdEndExpr:
317 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEndExpr *>(inst));
318 case IrInstSrcIdUnionInitNamedField:
319 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnionInitNamedField *>(inst));
320 case IrInstSrcIdSuspendBegin:
321 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSuspendBegin *>(inst));
322 case IrInstSrcIdSuspendFinish:
323 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSuspendFinish *>(inst));
324 case IrInstSrcIdResume:
325 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResume *>(inst));
326 case IrInstSrcIdAwait:
327 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAwait *>(inst));
328 case IrInstSrcIdSpillBegin:
329 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSpillBegin *>(inst));
330 case IrInstSrcIdSpillEnd:
331 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSpillEnd *>(inst));
332 case IrInstSrcIdCallArgs:
333 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallArgs *>(inst));
334 case IrInstSrcIdWasmMemorySize:
335 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcWasmMemorySize *>(inst));
336 case IrInstSrcIdWasmMemoryGrow:
337 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcWasmMemoryGrow *>(inst));
338 case IrInstSrcIdSrc:
339 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSrc *>(inst));
340 }
341 zig_unreachable();
342}
343
344
345bool ir_should_inline(Stage1Zir *exec, Scope *scope) {
346 if (exec->is_inline)
347 return true;
348
349 while (scope != nullptr) {
350 if (scope->id == ScopeIdCompTime)
351 return true;
352 if (scope->id == ScopeIdTypeOf)
353 return false;
354 if (scope->id == ScopeIdFnDef)
355 break;
356 scope = scope->parent;
357 }
358 return false;
359}
360
361static void ir_instruction_append(Stage1ZirBasicBlock *basic_block, IrInstSrc *instruction) {
362 assert(basic_block);
363 assert(instruction);
364 basic_block->instruction_list.append(instruction);
365}
366
367static size_t irb_next_debug_id(Stage1AstGen *ag) {
368 size_t result = ag->next_debug_id;
369 ag->next_debug_id += 1;
370 return result;
371}
372
373static void ir_ref_bb(Stage1ZirBasicBlock *bb) {
374 bb->ref_count += 1;
375}
376
377static void ir_ref_instruction(IrInstSrc *instruction, Stage1ZirBasicBlock *cur_bb) {
378 assert(instruction->id != IrInstSrcIdInvalid);
379 instruction->base.ref_count += 1;
380 if (instruction->owner_bb != cur_bb && !instr_is_unreachable(instruction)
381 && instruction->id != IrInstSrcIdConst)
382 {
383 ir_ref_bb(instruction->owner_bb);
384 }
385}
386
387static Stage1ZirBasicBlock *ir_create_basic_block(Stage1AstGen *ag, Scope *scope, const char *name_hint) {
388 Stage1ZirBasicBlock *result = heap::c_allocator.create<Stage1ZirBasicBlock>();
389 result->scope = scope;
390 result->name_hint = name_hint;
391 result->debug_id = irb_next_debug_id(ag);
392 result->index = UINT32_MAX; // set later
393 return result;
394}
395
396static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclVar *) {
397 return IrInstSrcIdDeclVar;
398}
399
400static constexpr IrInstSrcId ir_inst_id(IrInstSrcBr *) {
401 return IrInstSrcIdBr;
402}
403
404static constexpr IrInstSrcId ir_inst_id(IrInstSrcCondBr *) {
405 return IrInstSrcIdCondBr;
406}
407
408static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchBr *) {
409 return IrInstSrcIdSwitchBr;
410}
411
412static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchVar *) {
413 return IrInstSrcIdSwitchVar;
414}
415
416static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchElseVar *) {
417 return IrInstSrcIdSwitchElseVar;
418}
419
420static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchTarget *) {
421 return IrInstSrcIdSwitchTarget;
422}
423
424static constexpr IrInstSrcId ir_inst_id(IrInstSrcPhi *) {
425 return IrInstSrcIdPhi;
426}
427
428static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnOp *) {
429 return IrInstSrcIdUnOp;
430}
431
432static constexpr IrInstSrcId ir_inst_id(IrInstSrcBinOp *) {
433 return IrInstSrcIdBinOp;
434}
435
436static constexpr IrInstSrcId ir_inst_id(IrInstSrcMergeErrSets *) {
437 return IrInstSrcIdMergeErrSets;
438}
439
440static constexpr IrInstSrcId ir_inst_id(IrInstSrcLoadPtr *) {
441 return IrInstSrcIdLoadPtr;
442}
443
444static constexpr IrInstSrcId ir_inst_id(IrInstSrcStorePtr *) {
445 return IrInstSrcIdStorePtr;
446}
447
448static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldPtr *) {
449 return IrInstSrcIdFieldPtr;
450}
451
452static constexpr IrInstSrcId ir_inst_id(IrInstSrcElemPtr *) {
453 return IrInstSrcIdElemPtr;
454}
455
456static constexpr IrInstSrcId ir_inst_id(IrInstSrcVarPtr *) {
457 return IrInstSrcIdVarPtr;
458}
459
460static constexpr IrInstSrcId ir_inst_id(IrInstSrcCall *) {
461 return IrInstSrcIdCall;
462}
463
464static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallArgs *) {
465 return IrInstSrcIdCallArgs;
466}
467
468static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallExtra *) {
469 return IrInstSrcIdCallExtra;
470}
471
472static constexpr IrInstSrcId ir_inst_id(IrInstSrcAsyncCallExtra *) {
473 return IrInstSrcIdAsyncCallExtra;
474}
475
476static constexpr IrInstSrcId ir_inst_id(IrInstSrcConst *) {
477 return IrInstSrcIdConst;
478}
479
480static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturn *) {
481 return IrInstSrcIdReturn;
482}
483
484static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitList *) {
485 return IrInstSrcIdContainerInitList;
486}
487
488static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitFields *) {
489 return IrInstSrcIdContainerInitFields;
490}
491
492static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnreachable *) {
493 return IrInstSrcIdUnreachable;
494}
495
496static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeOf *) {
497 return IrInstSrcIdTypeOf;
498}
499
500static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetCold *) {
501 return IrInstSrcIdSetCold;
502}
503
504static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetRuntimeSafety *) {
505 return IrInstSrcIdSetRuntimeSafety;
506}
507
508static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetFloatMode *) {
509 return IrInstSrcIdSetFloatMode;
510}
511
512static constexpr IrInstSrcId ir_inst_id(IrInstSrcArrayType *) {
513 return IrInstSrcIdArrayType;
514}
515
516static constexpr IrInstSrcId ir_inst_id(IrInstSrcAnyFrameType *) {
517 return IrInstSrcIdAnyFrameType;
518}
519
520static constexpr IrInstSrcId ir_inst_id(IrInstSrcSliceType *) {
521 return IrInstSrcIdSliceType;
522}
523
524static constexpr IrInstSrcId ir_inst_id(IrInstSrcAsm *) {
525 return IrInstSrcIdAsm;
526}
527
528static constexpr IrInstSrcId ir_inst_id(IrInstSrcSizeOf *) {
529 return IrInstSrcIdSizeOf;
530}
531
532static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestNonNull *) {
533 return IrInstSrcIdTestNonNull;
534}
535
536static constexpr IrInstSrcId ir_inst_id(IrInstSrcOptionalUnwrapPtr *) {
537 return IrInstSrcIdOptionalUnwrapPtr;
538}
539
540static constexpr IrInstSrcId ir_inst_id(IrInstSrcClz *) {
541 return IrInstSrcIdClz;
542}
543
544static constexpr IrInstSrcId ir_inst_id(IrInstSrcCtz *) {
545 return IrInstSrcIdCtz;
546}
547
548static constexpr IrInstSrcId ir_inst_id(IrInstSrcPopCount *) {
549 return IrInstSrcIdPopCount;
550}
551
552static constexpr IrInstSrcId ir_inst_id(IrInstSrcBswap *) {
553 return IrInstSrcIdBswap;
554}
555
556static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitReverse *) {
557 return IrInstSrcIdBitReverse;
558}
559
560static constexpr IrInstSrcId ir_inst_id(IrInstSrcImport *) {
561 return IrInstSrcIdImport;
562}
563
564static constexpr IrInstSrcId ir_inst_id(IrInstSrcCImport *) {
565 return IrInstSrcIdCImport;
566}
567
568static constexpr IrInstSrcId ir_inst_id(IrInstSrcCInclude *) {
569 return IrInstSrcIdCInclude;
570}
571
572static constexpr IrInstSrcId ir_inst_id(IrInstSrcCDefine *) {
573 return IrInstSrcIdCDefine;
574}
575
576static constexpr IrInstSrcId ir_inst_id(IrInstSrcCUndef *) {
577 return IrInstSrcIdCUndef;
578}
579
580static constexpr IrInstSrcId ir_inst_id(IrInstSrcRef *) {
581 return IrInstSrcIdRef;
582}
583
584static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileErr *) {
585 return IrInstSrcIdCompileErr;
586}
587
588static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileLog *) {
589 return IrInstSrcIdCompileLog;
590}
591
592static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrName *) {
593 return IrInstSrcIdErrName;
594}
595
596static constexpr IrInstSrcId ir_inst_id(IrInstSrcEmbedFile *) {
597 return IrInstSrcIdEmbedFile;
598}
599
600static constexpr IrInstSrcId ir_inst_id(IrInstSrcCmpxchg *) {
601 return IrInstSrcIdCmpxchg;
602}
603
604static constexpr IrInstSrcId ir_inst_id(IrInstSrcFence *) {
605 return IrInstSrcIdFence;
606}
607
608static constexpr IrInstSrcId ir_inst_id(IrInstSrcReduce *) {
609 return IrInstSrcIdReduce;
610}
611
612static constexpr IrInstSrcId ir_inst_id(IrInstSrcTruncate *) {
613 return IrInstSrcIdTruncate;
614}
615
616static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntCast *) {
617 return IrInstSrcIdIntCast;
618}
619
620static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatCast *) {
621 return IrInstSrcIdFloatCast;
622}
623
624static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToFloat *) {
625 return IrInstSrcIdIntToFloat;
626}
627
628static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatToInt *) {
629 return IrInstSrcIdFloatToInt;
630}
631
632static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolToInt *) {
633 return IrInstSrcIdBoolToInt;
634}
635
636static constexpr IrInstSrcId ir_inst_id(IrInstSrcVectorType *) {
637 return IrInstSrcIdVectorType;
638}
639
640static constexpr IrInstSrcId ir_inst_id(IrInstSrcShuffleVector *) {
641 return IrInstSrcIdShuffleVector;
642}
643
644static constexpr IrInstSrcId ir_inst_id(IrInstSrcSplat *) {
645 return IrInstSrcIdSplat;
646}
647
648static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolNot *) {
649 return IrInstSrcIdBoolNot;
650}
651
652static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemset *) {
653 return IrInstSrcIdMemset;
654}
655
656static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemcpy *) {
657 return IrInstSrcIdMemcpy;
658}
659
660static constexpr IrInstSrcId ir_inst_id(IrInstSrcSlice *) {
661 return IrInstSrcIdSlice;
662}
663
664static constexpr IrInstSrcId ir_inst_id(IrInstSrcBreakpoint *) {
665 return IrInstSrcIdBreakpoint;
666}
667
668static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturnAddress *) {
669 return IrInstSrcIdReturnAddress;
670}
671
672static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameAddress *) {
673 return IrInstSrcIdFrameAddress;
674}
675
676static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameHandle *) {
677 return IrInstSrcIdFrameHandle;
678}
679
680static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameType *) {
681 return IrInstSrcIdFrameType;
682}
683
684static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameSize *) {
685 return IrInstSrcIdFrameSize;
686}
687
688static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignOf *) {
689 return IrInstSrcIdAlignOf;
690}
691
692static constexpr IrInstSrcId ir_inst_id(IrInstSrcOverflowOp *) {
693 return IrInstSrcIdOverflowOp;
694}
695
696static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestErr *) {
697 return IrInstSrcIdTestErr;
698}
699
700static constexpr IrInstSrcId ir_inst_id(IrInstSrcMulAdd *) {
701 return IrInstSrcIdMulAdd;
702}
703
704static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatOp *) {
705 return IrInstSrcIdFloatOp;
706}
707
708static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrCode *) {
709 return IrInstSrcIdUnwrapErrCode;
710}
711
712static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrPayload *) {
713 return IrInstSrcIdUnwrapErrPayload;
714}
715
716static constexpr IrInstSrcId ir_inst_id(IrInstSrcFnProto *) {
717 return IrInstSrcIdFnProto;
718}
719
720static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestComptime *) {
721 return IrInstSrcIdTestComptime;
722}
723
724static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrCast *) {
725 return IrInstSrcIdPtrCast;
726}
727
728static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitCast *) {
729 return IrInstSrcIdBitCast;
730}
731
732static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToPtr *) {
733 return IrInstSrcIdIntToPtr;
734}
735
736static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrToInt *) {
737 return IrInstSrcIdPtrToInt;
738}
739
740static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToEnum *) {
741 return IrInstSrcIdIntToEnum;
742}
743
744static constexpr IrInstSrcId ir_inst_id(IrInstSrcEnumToInt *) {
745 return IrInstSrcIdEnumToInt;
746}
747
748static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToErr *) {
749 return IrInstSrcIdIntToErr;
750}
751
752static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrToInt *) {
753 return IrInstSrcIdErrToInt;
754}
755
756static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckStatementIsVoid *) {
757 return IrInstSrcIdCheckStatementIsVoid;
758}
759
760static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeName *) {
761 return IrInstSrcIdTypeName;
762}
763
764static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclRef *) {
765 return IrInstSrcIdDeclRef;
766}
767
768static constexpr IrInstSrcId ir_inst_id(IrInstSrcPanic *) {
769 return IrInstSrcIdPanic;
770}
771
772static constexpr IrInstSrcId ir_inst_id(IrInstSrcTagName *) {
773 return IrInstSrcIdTagName;
774}
775
776static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldParentPtr *) {
777 return IrInstSrcIdFieldParentPtr;
778}
779
780static constexpr IrInstSrcId ir_inst_id(IrInstSrcByteOffsetOf *) {
781 return IrInstSrcIdByteOffsetOf;
782}
783
784static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitOffsetOf *) {
785 return IrInstSrcIdBitOffsetOf;
786}
787
788static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeInfo *) {
789 return IrInstSrcIdTypeInfo;
790}
791
792static constexpr IrInstSrcId ir_inst_id(IrInstSrcType *) {
793 return IrInstSrcIdType;
794}
795
796static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasField *) {
797 return IrInstSrcIdHasField;
798}
799
800static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetEvalBranchQuota *) {
801 return IrInstSrcIdSetEvalBranchQuota;
802}
803
804static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrType *) {
805 return IrInstSrcIdPtrType;
806}
807
808static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignCast *) {
809 return IrInstSrcIdAlignCast;
810}
811
812static constexpr IrInstSrcId ir_inst_id(IrInstSrcImplicitCast *) {
813 return IrInstSrcIdImplicitCast;
814}
815
816static constexpr IrInstSrcId ir_inst_id(IrInstSrcResolveResult *) {
817 return IrInstSrcIdResolveResult;
818}
819
820static constexpr IrInstSrcId ir_inst_id(IrInstSrcResetResult *) {
821 return IrInstSrcIdResetResult;
822}
823
824static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetAlignStack *) {
825 return IrInstSrcIdSetAlignStack;
826}
827
828static constexpr IrInstSrcId ir_inst_id(IrInstSrcExport *) {
829 return IrInstSrcIdExport;
830}
831
832static constexpr IrInstSrcId ir_inst_id(IrInstSrcExtern *) {
833 return IrInstSrcIdExtern;
834}
835
836static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorReturnTrace *) {
837 return IrInstSrcIdErrorReturnTrace;
838}
839
840static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorUnion *) {
841 return IrInstSrcIdErrorUnion;
842}
843
844static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicRmw *) {
845 return IrInstSrcIdAtomicRmw;
846}
847
848static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicLoad *) {
849 return IrInstSrcIdAtomicLoad;
850}
851
852static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicStore *) {
853 return IrInstSrcIdAtomicStore;
854}
855
856static constexpr IrInstSrcId ir_inst_id(IrInstSrcSaveErrRetAddr *) {
857 return IrInstSrcIdSaveErrRetAddr;
858}
859
860static constexpr IrInstSrcId ir_inst_id(IrInstSrcAddImplicitReturnType *) {
861 return IrInstSrcIdAddImplicitReturnType;
862}
863
864static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrSetCast *) {
865 return IrInstSrcIdErrSetCast;
866}
867
868static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckRuntimeScope *) {
869 return IrInstSrcIdCheckRuntimeScope;
870}
871
872static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasDecl *) {
873 return IrInstSrcIdHasDecl;
874}
875
876static constexpr IrInstSrcId ir_inst_id(IrInstSrcUndeclaredIdent *) {
877 return IrInstSrcIdUndeclaredIdent;
878}
879
880static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlloca *) {
881 return IrInstSrcIdAlloca;
882}
883
884static constexpr IrInstSrcId ir_inst_id(IrInstSrcEndExpr *) {
885 return IrInstSrcIdEndExpr;
886}
887
888static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnionInitNamedField *) {
889 return IrInstSrcIdUnionInitNamedField;
890}
891
892static constexpr IrInstSrcId ir_inst_id(IrInstSrcSuspendBegin *) {
893 return IrInstSrcIdSuspendBegin;
894}
895
896static constexpr IrInstSrcId ir_inst_id(IrInstSrcSuspendFinish *) {
897 return IrInstSrcIdSuspendFinish;
898}
899
900static constexpr IrInstSrcId ir_inst_id(IrInstSrcAwait *) {
901 return IrInstSrcIdAwait;
902}
903
904static constexpr IrInstSrcId ir_inst_id(IrInstSrcResume *) {
905 return IrInstSrcIdResume;
906}
907
908static constexpr IrInstSrcId ir_inst_id(IrInstSrcSpillBegin *) {
909 return IrInstSrcIdSpillBegin;
910}
911
912static constexpr IrInstSrcId ir_inst_id(IrInstSrcSpillEnd *) {
913 return IrInstSrcIdSpillEnd;
914}
915
916static constexpr IrInstSrcId ir_inst_id(IrInstSrcWasmMemorySize *) {
917 return IrInstSrcIdWasmMemorySize;
918}
919
920static constexpr IrInstSrcId ir_inst_id(IrInstSrcWasmMemoryGrow *) {
921 return IrInstSrcIdWasmMemoryGrow;
922}
923
924static constexpr IrInstSrcId ir_inst_id(IrInstSrcSrc *) {
925 return IrInstSrcIdSrc;
926}
927
928template<typename T>
929static T *ir_create_instruction(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
930 T *special_instruction = heap::c_allocator.create<T>();
931 special_instruction->base.id = ir_inst_id(special_instruction);
932 special_instruction->base.base.scope = scope;
933 special_instruction->base.base.source_node = source_node;
934 special_instruction->base.base.debug_id = irb_next_debug_id(ag);
935 special_instruction->base.owner_bb = ag->current_basic_block;
936 return special_instruction;
937}
938
939template<typename T>
940static T *ir_build_instruction(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
941 T *special_instruction = ir_create_instruction<T>(ag, scope, source_node);
942 ir_instruction_append(ag->current_basic_block, &special_instruction->base);
943 return special_instruction;
944}
945
946static IrInstSrc *ir_build_cond_br(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *condition,
947 Stage1ZirBasicBlock *then_block, Stage1ZirBasicBlock *else_block, IrInstSrc *is_comptime)
948{
949 IrInstSrcCondBr *inst = ir_build_instruction<IrInstSrcCondBr>(ag, scope, source_node);
950 inst->base.is_noreturn = true;
951 inst->condition = condition;
952 inst->then_block = then_block;
953 inst->else_block = else_block;
954 inst->is_comptime = is_comptime;
955
956 ir_ref_instruction(condition, ag->current_basic_block);
957 ir_ref_bb(then_block);
958 ir_ref_bb(else_block);
959 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, ag->current_basic_block);
960
961 return &inst->base;
962}
963
964static IrInstSrc *ir_build_return_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *operand) {
965 IrInstSrcReturn *inst = ir_build_instruction<IrInstSrcReturn>(ag, scope, source_node);
966 inst->base.is_noreturn = true;
967 inst->operand = operand;
968
969 if (operand != nullptr) ir_ref_instruction(operand, ag->current_basic_block);
970
971 return &inst->base;
972}
973
974static IrInstSrc *ir_build_const_void(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
975 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(ag, scope, source_node);
976 ir_instruction_append(ag->current_basic_block, &const_instruction->base);
977 const_instruction->value = ag->codegen->intern.for_void();
978 return &const_instruction->base;
979}
980
981static IrInstSrc *ir_build_const_undefined(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
982 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(ag, scope, source_node);
983 ir_instruction_append(ag->current_basic_block, &const_instruction->base);
984 const_instruction->value = ag->codegen->intern.for_undefined();
985 const_instruction->value->special = ConstValSpecialUndef;
986 return &const_instruction->base;
987}
988
989static IrInstSrc *ir_build_const_uint(Stage1AstGen *ag, Scope *scope, AstNode *source_node, uint64_t value) {
990 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(ag, scope, source_node);
991 const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
992 const_instruction->value->type = ag->codegen->builtin_types.entry_num_lit_int;
993 const_instruction->value->special = ConstValSpecialStatic;
994 bigint_init_unsigned(&const_instruction->value->data.x_bigint, value);
995 return &const_instruction->base;
996}
997
998static IrInstSrc *ir_build_const_bigint(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
999 BigInt bigint)
1000{
1001 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(ag, scope, source_node);
1002 const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1003 const_instruction->value->type = ag->codegen->builtin_types.entry_num_lit_int;
1004 const_instruction->value->special = ConstValSpecialStatic;
1005 const_instruction->value->data.x_bigint = bigint;
1006 return &const_instruction->base;
1007}
1008
1009static IrInstSrc *ir_build_const_bigfloat(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1010 BigFloat bigfloat)
1011{
1012 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(ag, scope, source_node);
1013 const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1014 const_instruction->value->type = ag->codegen->builtin_types.entry_num_lit_float;
1015 const_instruction->value->special = ConstValSpecialStatic;
1016 const_instruction->value->data.x_bigfloat = bigfloat;
1017 return &const_instruction->base;
1018}
1019
1020static IrInstSrc *ir_build_const_null(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
1021 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(ag, scope, source_node);
1022 ir_instruction_append(ag->current_basic_block, &const_instruction->base);
1023 const_instruction->value = ag->codegen->intern.for_null();
1024 return &const_instruction->base;
1025}
1026
1027static IrInstSrc *ir_build_const_usize(Stage1AstGen *ag, Scope *scope, AstNode *source_node, uint64_t value) {
1028 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(ag, scope, source_node);
1029 const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1030 const_instruction->value->type = ag->codegen->builtin_types.entry_usize;
1031 const_instruction->value->special = ConstValSpecialStatic;
1032 bigint_init_unsigned(&const_instruction->value->data.x_bigint, value);
1033 return &const_instruction->base;
1034}
1035
1036static IrInstSrc *ir_create_const_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1037 ZigType *type_entry)
1038{
1039 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(ag, scope, source_node);
1040 const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1041 const_instruction->value->type = ag->codegen->builtin_types.entry_type;
1042 const_instruction->value->special = ConstValSpecialStatic;
1043 const_instruction->value->data.x_type = type_entry;
1044 return &const_instruction->base;
1045}
1046
1047static IrInstSrc *ir_build_const_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1048 ZigType *type_entry)
1049{
1050 IrInstSrc *instruction = ir_create_const_type(ag, scope, source_node, type_entry);
1051 ir_instruction_append(ag->current_basic_block, instruction);
1052 return instruction;
1053}
1054
1055static IrInstSrc *ir_build_const_import(Stage1AstGen *ag, Scope *scope, AstNode *source_node, ZigType *import) {
1056 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(ag, scope, source_node);
1057 const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1058 const_instruction->value->type = ag->codegen->builtin_types.entry_type;
1059 const_instruction->value->special = ConstValSpecialStatic;
1060 const_instruction->value->data.x_type = import;
1061 return &const_instruction->base;
1062}
1063
1064static IrInstSrc *ir_build_const_bool(Stage1AstGen *ag, Scope *scope, AstNode *source_node, bool value) {
1065 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(ag, scope, source_node);
1066 const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1067 const_instruction->value->type = ag->codegen->builtin_types.entry_bool;
1068 const_instruction->value->special = ConstValSpecialStatic;
1069 const_instruction->value->data.x_bool = value;
1070 return &const_instruction->base;
1071}
1072
1073static IrInstSrc *ir_build_const_enum_literal(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Buf *name) {
1074 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(ag, scope, source_node);
1075 const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1076 const_instruction->value->type = ag->codegen->builtin_types.entry_enum_literal;
1077 const_instruction->value->special = ConstValSpecialStatic;
1078 const_instruction->value->data.x_enum_literal = name;
1079 return &const_instruction->base;
1080}
1081
1082// Consumes `str`.
1083static IrInstSrc *ir_create_const_str_lit(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Buf *str) {
1084 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(ag, scope, source_node);
1085 const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1086 init_const_str_lit(ag->codegen, const_instruction->value, str, true);
1087
1088 return &const_instruction->base;
1089}
1090
1091// Consumes `str`.
1092static IrInstSrc *ir_build_const_str_lit(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Buf *str) {
1093 IrInstSrc *instruction = ir_create_const_str_lit(ag, scope, source_node, str);
1094 ir_instruction_append(ag->current_basic_block, instruction);
1095 return instruction;
1096}
1097
1098static IrInstSrc *ir_build_bin_op(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrBinOp op_id,
1099 IrInstSrc *op1, IrInstSrc *op2, bool safety_check_on)
1100{
1101 IrInstSrcBinOp *inst = ir_build_instruction<IrInstSrcBinOp>(ag, scope, source_node);
1102 inst->op_id = op_id;
1103 inst->op1 = op1;
1104 inst->op2 = op2;
1105 inst->safety_check_on = safety_check_on;
1106
1107 ir_ref_instruction(op1, ag->current_basic_block);
1108 ir_ref_instruction(op2, ag->current_basic_block);
1109
1110 return &inst->base;
1111}
1112
1113static IrInstSrc *ir_build_merge_err_sets(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1114 IrInstSrc *op1, IrInstSrc *op2, Buf *type_name)
1115{
1116 IrInstSrcMergeErrSets *inst = ir_build_instruction<IrInstSrcMergeErrSets>(ag, scope, source_node);
1117 inst->op1 = op1;
1118 inst->op2 = op2;
1119 inst->type_name = type_name;
1120
1121 ir_ref_instruction(op1, ag->current_basic_block);
1122 ir_ref_instruction(op2, ag->current_basic_block);
1123
1124 return &inst->base;
1125}
1126
1127static IrInstSrc *ir_build_var_ptr_x(Stage1AstGen *ag, Scope *scope, AstNode *source_node, ZigVar *var,
1128 ScopeFnDef *crossed_fndef_scope)
1129{
1130 IrInstSrcVarPtr *instruction = ir_build_instruction<IrInstSrcVarPtr>(ag, scope, source_node);
1131 instruction->var = var;
1132 instruction->crossed_fndef_scope = crossed_fndef_scope;
1133
1134 var->ref_count += 1;
1135
1136 return &instruction->base;
1137}
1138
1139static IrInstSrc *ir_build_var_ptr(Stage1AstGen *ag, Scope *scope, AstNode *source_node, ZigVar *var) {
1140 return ir_build_var_ptr_x(ag, scope, source_node, var, nullptr);
1141}
1142
1143static IrInstSrc *ir_build_elem_ptr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1144 IrInstSrc *array_ptr, IrInstSrc *elem_index, bool safety_check_on, PtrLen ptr_len,
1145 AstNode *init_array_type_source_node)
1146{
1147 IrInstSrcElemPtr *instruction = ir_build_instruction<IrInstSrcElemPtr>(ag, scope, source_node);
1148 instruction->array_ptr = array_ptr;
1149 instruction->elem_index = elem_index;
1150 instruction->safety_check_on = safety_check_on;
1151 instruction->ptr_len = ptr_len;
1152 instruction->init_array_type_source_node = init_array_type_source_node;
1153
1154 ir_ref_instruction(array_ptr, ag->current_basic_block);
1155 ir_ref_instruction(elem_index, ag->current_basic_block);
1156
1157 return &instruction->base;
1158}
1159
1160static IrInstSrc *ir_build_field_ptr_instruction(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1161 IrInstSrc *container_ptr, IrInstSrc *field_name_expr, bool initializing)
1162{
1163 IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(ag, scope, source_node);
1164 instruction->container_ptr = container_ptr;
1165 instruction->field_name_buffer = nullptr;
1166 instruction->field_name_expr = field_name_expr;
1167 instruction->initializing = initializing;
1168
1169 ir_ref_instruction(container_ptr, ag->current_basic_block);
1170 ir_ref_instruction(field_name_expr, ag->current_basic_block);
1171
1172 return &instruction->base;
1173}
1174
1175static IrInstSrc *ir_build_field_ptr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1176 IrInstSrc *container_ptr, Buf *field_name, bool initializing)
1177{
1178 IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(ag, scope, source_node);
1179 instruction->container_ptr = container_ptr;
1180 instruction->field_name_buffer = field_name;
1181 instruction->field_name_expr = nullptr;
1182 instruction->initializing = initializing;
1183
1184 ir_ref_instruction(container_ptr, ag->current_basic_block);
1185
1186 return &instruction->base;
1187}
1188
1189static IrInstSrc *ir_build_has_field(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1190 IrInstSrc *container_type, IrInstSrc *field_name)
1191{
1192 IrInstSrcHasField *instruction = ir_build_instruction<IrInstSrcHasField>(ag, scope, source_node);
1193 instruction->container_type = container_type;
1194 instruction->field_name = field_name;
1195
1196 ir_ref_instruction(container_type, ag->current_basic_block);
1197 ir_ref_instruction(field_name, ag->current_basic_block);
1198
1199 return &instruction->base;
1200}
1201
1202static IrInstSrc *ir_build_call_extra(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1203 IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc *args, ResultLoc *result_loc)
1204{
1205 IrInstSrcCallExtra *call_instruction = ir_build_instruction<IrInstSrcCallExtra>(ag, scope, source_node);
1206 call_instruction->options = options;
1207 call_instruction->fn_ref = fn_ref;
1208 call_instruction->args = args;
1209 call_instruction->result_loc = result_loc;
1210
1211 ir_ref_instruction(options, ag->current_basic_block);
1212 ir_ref_instruction(fn_ref, ag->current_basic_block);
1213 ir_ref_instruction(args, ag->current_basic_block);
1214
1215 return &call_instruction->base;
1216}
1217
1218static IrInstSrc *ir_build_async_call_extra(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1219 CallModifier modifier, IrInstSrc *fn_ref, IrInstSrc *ret_ptr, IrInstSrc *new_stack, IrInstSrc *args, ResultLoc *result_loc)
1220{
1221 IrInstSrcAsyncCallExtra *call_instruction = ir_build_instruction<IrInstSrcAsyncCallExtra>(ag, scope, source_node);
1222 call_instruction->modifier = modifier;
1223 call_instruction->fn_ref = fn_ref;
1224 call_instruction->ret_ptr = ret_ptr;
1225 call_instruction->new_stack = new_stack;
1226 call_instruction->args = args;
1227 call_instruction->result_loc = result_loc;
1228
1229 ir_ref_instruction(fn_ref, ag->current_basic_block);
1230 if (ret_ptr != nullptr) ir_ref_instruction(ret_ptr, ag->current_basic_block);
1231 ir_ref_instruction(new_stack, ag->current_basic_block);
1232 ir_ref_instruction(args, ag->current_basic_block);
1233
1234 return &call_instruction->base;
1235}
1236
1237static IrInstSrc *ir_build_call_args(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1238 IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc **args_ptr, size_t args_len,
1239 ResultLoc *result_loc)
1240{
1241 IrInstSrcCallArgs *call_instruction = ir_build_instruction<IrInstSrcCallArgs>(ag, scope, source_node);
1242 call_instruction->options = options;
1243 call_instruction->fn_ref = fn_ref;
1244 call_instruction->args_ptr = args_ptr;
1245 call_instruction->args_len = args_len;
1246 call_instruction->result_loc = result_loc;
1247
1248 ir_ref_instruction(options, ag->current_basic_block);
1249 ir_ref_instruction(fn_ref, ag->current_basic_block);
1250 for (size_t i = 0; i < args_len; i += 1)
1251 ir_ref_instruction(args_ptr[i], ag->current_basic_block);
1252
1253 return &call_instruction->base;
1254}
1255
1256static IrInstSrc *ir_build_call_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1257 ZigFn *fn_entry, IrInstSrc *fn_ref, size_t arg_count, IrInstSrc **args,
1258 IrInstSrc *ret_ptr, CallModifier modifier, bool is_async_call_builtin,
1259 IrInstSrc *new_stack, ResultLoc *result_loc)
1260{
1261 IrInstSrcCall *call_instruction = ir_build_instruction<IrInstSrcCall>(ag, scope, source_node);
1262 call_instruction->fn_entry = fn_entry;
1263 call_instruction->fn_ref = fn_ref;
1264 call_instruction->args = args;
1265 call_instruction->arg_count = arg_count;
1266 call_instruction->modifier = modifier;
1267 call_instruction->is_async_call_builtin = is_async_call_builtin;
1268 call_instruction->new_stack = new_stack;
1269 call_instruction->result_loc = result_loc;
1270 call_instruction->ret_ptr = ret_ptr;
1271
1272 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ag->current_basic_block);
1273 for (size_t i = 0; i < arg_count; i += 1)
1274 ir_ref_instruction(args[i], ag->current_basic_block);
1275 if (ret_ptr != nullptr) ir_ref_instruction(ret_ptr, ag->current_basic_block);
1276 if (new_stack != nullptr) ir_ref_instruction(new_stack, ag->current_basic_block);
1277
1278 return &call_instruction->base;
1279}
1280
1281static IrInstSrc *ir_build_phi(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1282 size_t incoming_count, Stage1ZirBasicBlock **incoming_blocks, IrInstSrc **incoming_values,
1283 ResultLocPeerParent *peer_parent)
1284{
1285 assert(incoming_count != 0);
1286 assert(incoming_count != SIZE_MAX);
1287
1288 IrInstSrcPhi *phi_instruction = ir_build_instruction<IrInstSrcPhi>(ag, scope, source_node);
1289 phi_instruction->incoming_count = incoming_count;
1290 phi_instruction->incoming_blocks = incoming_blocks;
1291 phi_instruction->incoming_values = incoming_values;
1292 phi_instruction->peer_parent = peer_parent;
1293
1294 for (size_t i = 0; i < incoming_count; i += 1) {
1295 ir_ref_bb(incoming_blocks[i]);
1296 ir_ref_instruction(incoming_values[i], ag->current_basic_block);
1297 }
1298
1299 return &phi_instruction->base;
1300}
1301
1302static IrInstSrc *ir_build_br(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1303 Stage1ZirBasicBlock *dest_block, IrInstSrc *is_comptime)
1304{
1305 IrInstSrcBr *inst = ir_build_instruction<IrInstSrcBr>(ag, scope, source_node);
1306 inst->base.is_noreturn = true;
1307 inst->dest_block = dest_block;
1308 inst->is_comptime = is_comptime;
1309
1310 ir_ref_bb(dest_block);
1311 if (is_comptime) ir_ref_instruction(is_comptime, ag->current_basic_block);
1312
1313 return &inst->base;
1314}
1315
1316static IrInstSrc *ir_build_ptr_type_simple(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1317 IrInstSrc *child_type, bool is_const)
1318{
1319 IrInstSrcPtrTypeSimple *inst = heap::c_allocator.create<IrInstSrcPtrTypeSimple>();
1320 inst->base.id = is_const ? IrInstSrcIdPtrTypeSimpleConst : IrInstSrcIdPtrTypeSimple;
1321 inst->base.base.scope = scope;
1322 inst->base.base.source_node = source_node;
1323 inst->base.base.debug_id = irb_next_debug_id(ag);
1324 inst->base.owner_bb = ag->current_basic_block;
1325 ir_instruction_append(ag->current_basic_block, &inst->base);
1326
1327 inst->child_type = child_type;
1328
1329 ir_ref_instruction(child_type, ag->current_basic_block);
1330
1331 return &inst->base;
1332}
1333
1334static IrInstSrc *ir_build_ptr_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1335 IrInstSrc *child_type, bool is_const, bool is_volatile, PtrLen ptr_len,
1336 IrInstSrc *sentinel, IrInstSrc *align_value,
1337 uint32_t bit_offset_start, uint32_t host_int_bytes, bool is_allow_zero)
1338{
1339 if (!is_volatile && ptr_len == PtrLenSingle && sentinel == nullptr && align_value == nullptr &&
1340 bit_offset_start == 0 && host_int_bytes == 0 && is_allow_zero == 0)
1341 {
1342 return ir_build_ptr_type_simple(ag, scope, source_node, child_type, is_const);
1343 }
1344
1345 IrInstSrcPtrType *inst = ir_build_instruction<IrInstSrcPtrType>(ag, scope, source_node);
1346 inst->sentinel = sentinel;
1347 inst->align_value = align_value;
1348 inst->child_type = child_type;
1349 inst->is_const = is_const;
1350 inst->is_volatile = is_volatile;
1351 inst->ptr_len = ptr_len;
1352 inst->bit_offset_start = bit_offset_start;
1353 inst->host_int_bytes = host_int_bytes;
1354 inst->is_allow_zero = is_allow_zero;
1355
1356 if (sentinel) ir_ref_instruction(sentinel, ag->current_basic_block);
1357 if (align_value) ir_ref_instruction(align_value, ag->current_basic_block);
1358 ir_ref_instruction(child_type, ag->current_basic_block);
1359
1360 return &inst->base;
1361}
1362
1363static IrInstSrc *ir_build_un_op_lval(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrUnOp op_id,
1364 IrInstSrc *value, LVal lval, ResultLoc *result_loc)
1365{
1366 IrInstSrcUnOp *instruction = ir_build_instruction<IrInstSrcUnOp>(ag, scope, source_node);
1367 instruction->op_id = op_id;
1368 instruction->value = value;
1369 instruction->lval = lval;
1370 instruction->result_loc = result_loc;
1371
1372 ir_ref_instruction(value, ag->current_basic_block);
1373
1374 return &instruction->base;
1375}
1376
1377static IrInstSrc *ir_build_un_op(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrUnOp op_id,
1378 IrInstSrc *value)
1379{
1380 return ir_build_un_op_lval(ag, scope, source_node, op_id, value, LValNone, nullptr);
1381}
1382
1383static IrInstSrc *ir_build_container_init_list(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1384 size_t item_count, IrInstSrc **elem_result_loc_list, IrInstSrc *result_loc,
1385 AstNode *init_array_type_source_node)
1386{
1387 IrInstSrcContainerInitList *container_init_list_instruction =
1388 ir_build_instruction<IrInstSrcContainerInitList>(ag, scope, source_node);
1389 container_init_list_instruction->item_count = item_count;
1390 container_init_list_instruction->elem_result_loc_list = elem_result_loc_list;
1391 container_init_list_instruction->result_loc = result_loc;
1392 container_init_list_instruction->init_array_type_source_node = init_array_type_source_node;
1393
1394 for (size_t i = 0; i < item_count; i += 1) {
1395 ir_ref_instruction(elem_result_loc_list[i], ag->current_basic_block);
1396 }
1397 if (result_loc != nullptr) ir_ref_instruction(result_loc, ag->current_basic_block);
1398
1399 return &container_init_list_instruction->base;
1400}
1401
1402static IrInstSrc *ir_build_container_init_fields(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1403 size_t field_count, IrInstSrcContainerInitFieldsField *fields, IrInstSrc *result_loc)
1404{
1405 IrInstSrcContainerInitFields *container_init_fields_instruction =
1406 ir_build_instruction<IrInstSrcContainerInitFields>(ag, scope, source_node);
1407 container_init_fields_instruction->field_count = field_count;
1408 container_init_fields_instruction->fields = fields;
1409 container_init_fields_instruction->result_loc = result_loc;
1410
1411 for (size_t i = 0; i < field_count; i += 1) {
1412 ir_ref_instruction(fields[i].result_loc, ag->current_basic_block);
1413 }
1414 if (result_loc != nullptr) ir_ref_instruction(result_loc, ag->current_basic_block);
1415
1416 return &container_init_fields_instruction->base;
1417}
1418
1419static IrInstSrc *ir_build_unreachable(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
1420 IrInstSrcUnreachable *inst = ir_build_instruction<IrInstSrcUnreachable>(ag, scope, source_node);
1421 inst->base.is_noreturn = true;
1422 return &inst->base;
1423}
1424
1425static IrInstSrcStorePtr *ir_build_store_ptr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1426 IrInstSrc *ptr, IrInstSrc *value)
1427{
1428 IrInstSrcStorePtr *instruction = ir_build_instruction<IrInstSrcStorePtr>(ag, scope, source_node);
1429 instruction->ptr = ptr;
1430 instruction->value = value;
1431
1432 ir_ref_instruction(ptr, ag->current_basic_block);
1433 ir_ref_instruction(value, ag->current_basic_block);
1434
1435 return instruction;
1436}
1437
1438static IrInstSrc *ir_build_var_decl_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1439 ZigVar *var, IrInstSrc *align_value, IrInstSrc *ptr)
1440{
1441 IrInstSrcDeclVar *inst = ir_build_instruction<IrInstSrcDeclVar>(ag, scope, source_node);
1442 inst->var = var;
1443 inst->align_value = align_value;
1444 inst->ptr = ptr;
1445
1446 if (align_value != nullptr) ir_ref_instruction(align_value, ag->current_basic_block);
1447 ir_ref_instruction(ptr, ag->current_basic_block);
1448
1449 return &inst->base;
1450}
1451
1452static IrInstSrc *ir_build_export(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1453 IrInstSrc *target, IrInstSrc *options)
1454{
1455 IrInstSrcExport *export_instruction = ir_build_instruction<IrInstSrcExport>(
1456 ag, scope, source_node);
1457 export_instruction->target = target;
1458 export_instruction->options = options;
1459
1460 ir_ref_instruction(target, ag->current_basic_block);
1461 ir_ref_instruction(options, ag->current_basic_block);
1462
1463 return &export_instruction->base;
1464}
1465
1466static IrInstSrc *ir_build_extern(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1467 IrInstSrc *type, IrInstSrc *options)
1468{
1469 IrInstSrcExtern *extern_instruction = ir_build_instruction<IrInstSrcExtern>(
1470 ag, scope, source_node);
1471 extern_instruction->type = type;
1472 extern_instruction->options = options;
1473
1474 ir_ref_instruction(type, ag->current_basic_block);
1475 ir_ref_instruction(options, ag->current_basic_block);
1476
1477 return &extern_instruction->base;
1478}
1479
1480static IrInstSrc *ir_build_load_ptr(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *ptr) {
1481 IrInstSrcLoadPtr *instruction = ir_build_instruction<IrInstSrcLoadPtr>(ag, scope, source_node);
1482 instruction->ptr = ptr;
1483
1484 ir_ref_instruction(ptr, ag->current_basic_block);
1485
1486 return &instruction->base;
1487}
1488
1489static IrInstSrc *ir_build_typeof_n(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1490 IrInstSrc **values, size_t value_count)
1491{
1492 assert(value_count >= 2);
1493
1494 IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(ag, scope, source_node);
1495 instruction->value.list = values;
1496 instruction->value_count = value_count;
1497
1498 for (size_t i = 0; i < value_count; i++)
1499 ir_ref_instruction(values[i], ag->current_basic_block);
1500
1501 return &instruction->base;
1502}
1503
1504static IrInstSrc *ir_build_typeof_1(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *value) {
1505 IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(ag, scope, source_node);
1506 instruction->value.scalar = value;
1507
1508 ir_ref_instruction(value, ag->current_basic_block);
1509
1510 return &instruction->base;
1511}
1512
1513static IrInstSrc *ir_build_set_cold(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *is_cold) {
1514 IrInstSrcSetCold *instruction = ir_build_instruction<IrInstSrcSetCold>(ag, scope, source_node);
1515 instruction->is_cold = is_cold;
1516
1517 ir_ref_instruction(is_cold, ag->current_basic_block);
1518
1519 return &instruction->base;
1520}
1521
1522static IrInstSrc *ir_build_set_runtime_safety(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1523 IrInstSrc *safety_on)
1524{
1525 IrInstSrcSetRuntimeSafety *inst = ir_build_instruction<IrInstSrcSetRuntimeSafety>(ag, scope, source_node);
1526 inst->safety_on = safety_on;
1527
1528 ir_ref_instruction(safety_on, ag->current_basic_block);
1529
1530 return &inst->base;
1531}
1532
1533static IrInstSrc *ir_build_set_float_mode(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1534 IrInstSrc *mode_value)
1535{
1536 IrInstSrcSetFloatMode *instruction = ir_build_instruction<IrInstSrcSetFloatMode>(ag, scope, source_node);
1537 instruction->mode_value = mode_value;
1538
1539 ir_ref_instruction(mode_value, ag->current_basic_block);
1540
1541 return &instruction->base;
1542}
1543
1544static IrInstSrc *ir_build_array_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *size,
1545 IrInstSrc *sentinel, IrInstSrc *child_type)
1546{
1547 IrInstSrcArrayType *instruction = ir_build_instruction<IrInstSrcArrayType>(ag, scope, source_node);
1548 instruction->size = size;
1549 instruction->sentinel = sentinel;
1550 instruction->child_type = child_type;
1551
1552 ir_ref_instruction(size, ag->current_basic_block);
1553 if (sentinel != nullptr) ir_ref_instruction(sentinel, ag->current_basic_block);
1554 ir_ref_instruction(child_type, ag->current_basic_block);
1555
1556 return &instruction->base;
1557}
1558
1559static IrInstSrc *ir_build_anyframe_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1560 IrInstSrc *payload_type)
1561{
1562 IrInstSrcAnyFrameType *instruction = ir_build_instruction<IrInstSrcAnyFrameType>(ag, scope, source_node);
1563 instruction->payload_type = payload_type;
1564
1565 if (payload_type != nullptr) ir_ref_instruction(payload_type, ag->current_basic_block);
1566
1567 return &instruction->base;
1568}
1569
1570static IrInstSrc *ir_build_slice_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1571 IrInstSrc *child_type, bool is_const, bool is_volatile,
1572 IrInstSrc *sentinel, IrInstSrc *align_value, bool is_allow_zero)
1573{
1574 IrInstSrcSliceType *instruction = ir_build_instruction<IrInstSrcSliceType>(ag, scope, source_node);
1575 instruction->is_const = is_const;
1576 instruction->is_volatile = is_volatile;
1577 instruction->child_type = child_type;
1578 instruction->sentinel = sentinel;
1579 instruction->align_value = align_value;
1580 instruction->is_allow_zero = is_allow_zero;
1581
1582 if (sentinel != nullptr) ir_ref_instruction(sentinel, ag->current_basic_block);
1583 if (align_value != nullptr) ir_ref_instruction(align_value, ag->current_basic_block);
1584 ir_ref_instruction(child_type, ag->current_basic_block);
1585
1586 return &instruction->base;
1587}
1588
1589static IrInstSrc *ir_build_asm_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1590 IrInstSrc *asm_template, IrInstSrc **input_list, IrInstSrc **output_types,
1591 ZigVar **output_vars, size_t return_count, bool has_side_effects, bool is_global)
1592{
1593 IrInstSrcAsm *instruction = ir_build_instruction<IrInstSrcAsm>(ag, scope, source_node);
1594 instruction->asm_template = asm_template;
1595 instruction->input_list = input_list;
1596 instruction->output_types = output_types;
1597 instruction->output_vars = output_vars;
1598 instruction->return_count = return_count;
1599 instruction->has_side_effects = has_side_effects;
1600 instruction->is_global = is_global;
1601
1602 assert(source_node->type == NodeTypeAsmExpr);
1603 for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) {
1604 IrInstSrc *output_type = output_types[i];
1605 if (output_type) ir_ref_instruction(output_type, ag->current_basic_block);
1606 }
1607
1608 for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) {
1609 IrInstSrc *input_value = input_list[i];
1610 ir_ref_instruction(input_value, ag->current_basic_block);
1611 }
1612
1613 return &instruction->base;
1614}
1615
1616static IrInstSrc *ir_build_size_of(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *type_value,
1617 bool bit_size)
1618{
1619 IrInstSrcSizeOf *instruction = ir_build_instruction<IrInstSrcSizeOf>(ag, scope, source_node);
1620 instruction->type_value = type_value;
1621 instruction->bit_size = bit_size;
1622
1623 ir_ref_instruction(type_value, ag->current_basic_block);
1624
1625 return &instruction->base;
1626}
1627
1628static IrInstSrc *ir_build_test_non_null_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1629 IrInstSrc *value)
1630{
1631 IrInstSrcTestNonNull *instruction = ir_build_instruction<IrInstSrcTestNonNull>(ag, scope, source_node);
1632 instruction->value = value;
1633
1634 ir_ref_instruction(value, ag->current_basic_block);
1635
1636 return &instruction->base;
1637}
1638
1639static IrInstSrc *ir_build_optional_unwrap_ptr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1640 IrInstSrc *base_ptr, bool safety_check_on)
1641{
1642 IrInstSrcOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstSrcOptionalUnwrapPtr>(ag, scope, source_node);
1643 instruction->base_ptr = base_ptr;
1644 instruction->safety_check_on = safety_check_on;
1645
1646 ir_ref_instruction(base_ptr, ag->current_basic_block);
1647
1648 return &instruction->base;
1649}
1650
1651static IrInstSrc *ir_build_clz(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *type,
1652 IrInstSrc *op)
1653{
1654 IrInstSrcClz *instruction = ir_build_instruction<IrInstSrcClz>(ag, scope, source_node);
1655 instruction->type = type;
1656 instruction->op = op;
1657
1658 ir_ref_instruction(type, ag->current_basic_block);
1659 ir_ref_instruction(op, ag->current_basic_block);
1660
1661 return &instruction->base;
1662}
1663
1664static IrInstSrc *ir_build_ctz(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *type,
1665 IrInstSrc *op)
1666{
1667 IrInstSrcCtz *instruction = ir_build_instruction<IrInstSrcCtz>(ag, scope, source_node);
1668 instruction->type = type;
1669 instruction->op = op;
1670
1671 ir_ref_instruction(type, ag->current_basic_block);
1672 ir_ref_instruction(op, ag->current_basic_block);
1673
1674 return &instruction->base;
1675}
1676
1677static IrInstSrc *ir_build_pop_count(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *type,
1678 IrInstSrc *op)
1679{
1680 IrInstSrcPopCount *instruction = ir_build_instruction<IrInstSrcPopCount>(ag, scope, source_node);
1681 instruction->type = type;
1682 instruction->op = op;
1683
1684 ir_ref_instruction(type, ag->current_basic_block);
1685 ir_ref_instruction(op, ag->current_basic_block);
1686
1687 return &instruction->base;
1688}
1689
1690static IrInstSrc *ir_build_bswap(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *type,
1691 IrInstSrc *op)
1692{
1693 IrInstSrcBswap *instruction = ir_build_instruction<IrInstSrcBswap>(ag, scope, source_node);
1694 instruction->type = type;
1695 instruction->op = op;
1696
1697 ir_ref_instruction(type, ag->current_basic_block);
1698 ir_ref_instruction(op, ag->current_basic_block);
1699
1700 return &instruction->base;
1701}
1702
1703static IrInstSrc *ir_build_bit_reverse(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *type,
1704 IrInstSrc *op)
1705{
1706 IrInstSrcBitReverse *instruction = ir_build_instruction<IrInstSrcBitReverse>(ag, scope, source_node);
1707 instruction->type = type;
1708 instruction->op = op;
1709
1710 ir_ref_instruction(type, ag->current_basic_block);
1711 ir_ref_instruction(op, ag->current_basic_block);
1712
1713 return &instruction->base;
1714}
1715
1716static IrInstSrcSwitchBr *ir_build_switch_br_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1717 IrInstSrc *target_value, Stage1ZirBasicBlock *else_block, size_t case_count, IrInstSrcSwitchBrCase *cases,
1718 IrInstSrc *is_comptime, IrInstSrc *switch_prongs_void)
1719{
1720 IrInstSrcSwitchBr *instruction = ir_build_instruction<IrInstSrcSwitchBr>(ag, scope, source_node);
1721 instruction->base.is_noreturn = true;
1722 instruction->target_value = target_value;
1723 instruction->else_block = else_block;
1724 instruction->case_count = case_count;
1725 instruction->cases = cases;
1726 instruction->is_comptime = is_comptime;
1727 instruction->switch_prongs_void = switch_prongs_void;
1728
1729 ir_ref_instruction(target_value, ag->current_basic_block);
1730 ir_ref_instruction(is_comptime, ag->current_basic_block);
1731 ir_ref_bb(else_block);
1732 ir_ref_instruction(switch_prongs_void, ag->current_basic_block);
1733
1734 for (size_t i = 0; i < case_count; i += 1) {
1735 ir_ref_instruction(cases[i].value, ag->current_basic_block);
1736 ir_ref_bb(cases[i].block);
1737 }
1738
1739 return instruction;
1740}
1741
1742static IrInstSrc *ir_build_switch_target(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1743 IrInstSrc *target_value_ptr)
1744{
1745 IrInstSrcSwitchTarget *instruction = ir_build_instruction<IrInstSrcSwitchTarget>(ag, scope, source_node);
1746 instruction->target_value_ptr = target_value_ptr;
1747
1748 ir_ref_instruction(target_value_ptr, ag->current_basic_block);
1749
1750 return &instruction->base;
1751}
1752
1753static IrInstSrc *ir_build_switch_var(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1754 IrInstSrc *target_value_ptr, IrInstSrc **prongs_ptr, size_t prongs_len)
1755{
1756 IrInstSrcSwitchVar *instruction = ir_build_instruction<IrInstSrcSwitchVar>(ag, scope, source_node);
1757 instruction->target_value_ptr = target_value_ptr;
1758 instruction->prongs_ptr = prongs_ptr;
1759 instruction->prongs_len = prongs_len;
1760
1761 ir_ref_instruction(target_value_ptr, ag->current_basic_block);
1762 for (size_t i = 0; i < prongs_len; i += 1) {
1763 ir_ref_instruction(prongs_ptr[i], ag->current_basic_block);
1764 }
1765
1766 return &instruction->base;
1767}
1768
1769// For this instruction the switch_br must be set later.
1770static IrInstSrcSwitchElseVar *ir_build_switch_else_var(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1771 IrInstSrc *target_value_ptr)
1772{
1773 IrInstSrcSwitchElseVar *instruction = ir_build_instruction<IrInstSrcSwitchElseVar>(ag, scope, source_node);
1774 instruction->target_value_ptr = target_value_ptr;
1775
1776 ir_ref_instruction(target_value_ptr, ag->current_basic_block);
1777
1778 return instruction;
1779}
1780
1781static IrInstSrc *ir_build_import(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *name) {
1782 IrInstSrcImport *instruction = ir_build_instruction<IrInstSrcImport>(ag, scope, source_node);
1783 instruction->name = name;
1784
1785 ir_ref_instruction(name, ag->current_basic_block);
1786
1787 return &instruction->base;
1788}
1789
1790static IrInstSrc *ir_build_ref_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *value) {
1791 IrInstSrcRef *instruction = ir_build_instruction<IrInstSrcRef>(ag, scope, source_node);
1792 instruction->value = value;
1793
1794 ir_ref_instruction(value, ag->current_basic_block);
1795
1796 return &instruction->base;
1797}
1798
1799static IrInstSrc *ir_build_compile_err(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *msg) {
1800 IrInstSrcCompileErr *instruction = ir_build_instruction<IrInstSrcCompileErr>(ag, scope, source_node);
1801 instruction->msg = msg;
1802
1803 ir_ref_instruction(msg, ag->current_basic_block);
1804
1805 return &instruction->base;
1806}
1807
1808static IrInstSrc *ir_build_compile_log(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1809 size_t msg_count, IrInstSrc **msg_list)
1810{
1811 IrInstSrcCompileLog *instruction = ir_build_instruction<IrInstSrcCompileLog>(ag, scope, source_node);
1812 instruction->msg_count = msg_count;
1813 instruction->msg_list = msg_list;
1814
1815 for (size_t i = 0; i < msg_count; i += 1) {
1816 ir_ref_instruction(msg_list[i], ag->current_basic_block);
1817 }
1818
1819 return &instruction->base;
1820}
1821
1822static IrInstSrc *ir_build_err_name(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *value) {
1823 IrInstSrcErrName *instruction = ir_build_instruction<IrInstSrcErrName>(ag, scope, source_node);
1824 instruction->value = value;
1825
1826 ir_ref_instruction(value, ag->current_basic_block);
1827
1828 return &instruction->base;
1829}
1830
1831static IrInstSrc *ir_build_c_import(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
1832 IrInstSrcCImport *instruction = ir_build_instruction<IrInstSrcCImport>(ag, scope, source_node);
1833 return &instruction->base;
1834}
1835
1836static IrInstSrc *ir_build_c_include(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *name) {
1837 IrInstSrcCInclude *instruction = ir_build_instruction<IrInstSrcCInclude>(ag, scope, source_node);
1838 instruction->name = name;
1839
1840 ir_ref_instruction(name, ag->current_basic_block);
1841
1842 return &instruction->base;
1843}
1844
1845static IrInstSrc *ir_build_c_define(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *name, IrInstSrc *value) {
1846 IrInstSrcCDefine *instruction = ir_build_instruction<IrInstSrcCDefine>(ag, scope, source_node);
1847 instruction->name = name;
1848 instruction->value = value;
1849
1850 ir_ref_instruction(name, ag->current_basic_block);
1851 ir_ref_instruction(value, ag->current_basic_block);
1852
1853 return &instruction->base;
1854}
1855
1856static IrInstSrc *ir_build_c_undef(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *name) {
1857 IrInstSrcCUndef *instruction = ir_build_instruction<IrInstSrcCUndef>(ag, scope, source_node);
1858 instruction->name = name;
1859
1860 ir_ref_instruction(name, ag->current_basic_block);
1861
1862 return &instruction->base;
1863}
1864
1865static IrInstSrc *ir_build_embed_file(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *name) {
1866 IrInstSrcEmbedFile *instruction = ir_build_instruction<IrInstSrcEmbedFile>(ag, scope, source_node);
1867 instruction->name = name;
1868
1869 ir_ref_instruction(name, ag->current_basic_block);
1870
1871 return &instruction->base;
1872}
1873
1874static IrInstSrc *ir_build_cmpxchg_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1875 IrInstSrc *type_value, IrInstSrc *ptr, IrInstSrc *cmp_value, IrInstSrc *new_value,
1876 IrInstSrc *success_order_value, IrInstSrc *failure_order_value, bool is_weak, ResultLoc *result_loc)
1877{
1878 IrInstSrcCmpxchg *instruction = ir_build_instruction<IrInstSrcCmpxchg>(ag, scope, source_node);
1879 instruction->type_value = type_value;
1880 instruction->ptr = ptr;
1881 instruction->cmp_value = cmp_value;
1882 instruction->new_value = new_value;
1883 instruction->success_order_value = success_order_value;
1884 instruction->failure_order_value = failure_order_value;
1885 instruction->is_weak = is_weak;
1886 instruction->result_loc = result_loc;
1887
1888 ir_ref_instruction(type_value, ag->current_basic_block);
1889 ir_ref_instruction(ptr, ag->current_basic_block);
1890 ir_ref_instruction(cmp_value, ag->current_basic_block);
1891 ir_ref_instruction(new_value, ag->current_basic_block);
1892 ir_ref_instruction(success_order_value, ag->current_basic_block);
1893 ir_ref_instruction(failure_order_value, ag->current_basic_block);
1894
1895 return &instruction->base;
1896}
1897
1898static IrInstSrc *ir_build_fence(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *order) {
1899 IrInstSrcFence *instruction = ir_build_instruction<IrInstSrcFence>(ag, scope, source_node);
1900 instruction->order = order;
1901
1902 ir_ref_instruction(order, ag->current_basic_block);
1903
1904 return &instruction->base;
1905}
1906
1907static IrInstSrc *ir_build_reduce(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *op, IrInstSrc *value) {
1908 IrInstSrcReduce *instruction = ir_build_instruction<IrInstSrcReduce>(ag, scope, source_node);
1909 instruction->op = op;
1910 instruction->value = value;
1911
1912 ir_ref_instruction(op, ag->current_basic_block);
1913 ir_ref_instruction(value, ag->current_basic_block);
1914
1915 return &instruction->base;
1916}
1917
1918static IrInstSrc *ir_build_truncate(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1919 IrInstSrc *dest_type, IrInstSrc *target)
1920{
1921 IrInstSrcTruncate *instruction = ir_build_instruction<IrInstSrcTruncate>(ag, scope, source_node);
1922 instruction->dest_type = dest_type;
1923 instruction->target = target;
1924
1925 ir_ref_instruction(dest_type, ag->current_basic_block);
1926 ir_ref_instruction(target, ag->current_basic_block);
1927
1928 return &instruction->base;
1929}
1930
1931static IrInstSrc *ir_build_int_cast(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *dest_type,
1932 IrInstSrc *target)
1933{
1934 IrInstSrcIntCast *instruction = ir_build_instruction<IrInstSrcIntCast>(ag, scope, source_node);
1935 instruction->dest_type = dest_type;
1936 instruction->target = target;
1937
1938 ir_ref_instruction(dest_type, ag->current_basic_block);
1939 ir_ref_instruction(target, ag->current_basic_block);
1940
1941 return &instruction->base;
1942}
1943
1944static IrInstSrc *ir_build_float_cast(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *dest_type,
1945 IrInstSrc *target)
1946{
1947 IrInstSrcFloatCast *instruction = ir_build_instruction<IrInstSrcFloatCast>(ag, scope, source_node);
1948 instruction->dest_type = dest_type;
1949 instruction->target = target;
1950
1951 ir_ref_instruction(dest_type, ag->current_basic_block);
1952 ir_ref_instruction(target, ag->current_basic_block);
1953
1954 return &instruction->base;
1955}
1956
1957static IrInstSrc *ir_build_err_set_cast(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1958 IrInstSrc *dest_type, IrInstSrc *target)
1959{
1960 IrInstSrcErrSetCast *instruction = ir_build_instruction<IrInstSrcErrSetCast>(ag, scope, source_node);
1961 instruction->dest_type = dest_type;
1962 instruction->target = target;
1963
1964 ir_ref_instruction(dest_type, ag->current_basic_block);
1965 ir_ref_instruction(target, ag->current_basic_block);
1966
1967 return &instruction->base;
1968}
1969
1970static IrInstSrc *ir_build_int_to_float(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1971 IrInstSrc *dest_type, IrInstSrc *target)
1972{
1973 IrInstSrcIntToFloat *instruction = ir_build_instruction<IrInstSrcIntToFloat>(ag, scope, source_node);
1974 instruction->dest_type = dest_type;
1975 instruction->target = target;
1976
1977 ir_ref_instruction(dest_type, ag->current_basic_block);
1978 ir_ref_instruction(target, ag->current_basic_block);
1979
1980 return &instruction->base;
1981}
1982
1983static IrInstSrc *ir_build_float_to_int(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1984 IrInstSrc *dest_type, IrInstSrc *target)
1985{
1986 IrInstSrcFloatToInt *instruction = ir_build_instruction<IrInstSrcFloatToInt>(ag, scope, source_node);
1987 instruction->dest_type = dest_type;
1988 instruction->target = target;
1989
1990 ir_ref_instruction(dest_type, ag->current_basic_block);
1991 ir_ref_instruction(target, ag->current_basic_block);
1992
1993 return &instruction->base;
1994}
1995
1996static IrInstSrc *ir_build_bool_to_int(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *target) {
1997 IrInstSrcBoolToInt *instruction = ir_build_instruction<IrInstSrcBoolToInt>(ag, scope, source_node);
1998 instruction->target = target;
1999
2000 ir_ref_instruction(target, ag->current_basic_block);
2001
2002 return &instruction->base;
2003}
2004
2005static IrInstSrc *ir_build_vector_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *len,
2006 IrInstSrc *elem_type)
2007{
2008 IrInstSrcVectorType *instruction = ir_build_instruction<IrInstSrcVectorType>(ag, scope, source_node);
2009 instruction->len = len;
2010 instruction->elem_type = elem_type;
2011
2012 ir_ref_instruction(len, ag->current_basic_block);
2013 ir_ref_instruction(elem_type, ag->current_basic_block);
2014
2015 return &instruction->base;
2016}
2017
2018static IrInstSrc *ir_build_shuffle_vector(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2019 IrInstSrc *scalar_type, IrInstSrc *a, IrInstSrc *b, IrInstSrc *mask)
2020{
2021 IrInstSrcShuffleVector *instruction = ir_build_instruction<IrInstSrcShuffleVector>(ag, scope, source_node);
2022 instruction->scalar_type = scalar_type;
2023 instruction->a = a;
2024 instruction->b = b;
2025 instruction->mask = mask;
2026
2027 if (scalar_type != nullptr) ir_ref_instruction(scalar_type, ag->current_basic_block);
2028 ir_ref_instruction(a, ag->current_basic_block);
2029 ir_ref_instruction(b, ag->current_basic_block);
2030 ir_ref_instruction(mask, ag->current_basic_block);
2031
2032 return &instruction->base;
2033}
2034
2035static IrInstSrc *ir_build_splat_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2036 IrInstSrc *len, IrInstSrc *scalar)
2037{
2038 IrInstSrcSplat *instruction = ir_build_instruction<IrInstSrcSplat>(ag, scope, source_node);
2039 instruction->len = len;
2040 instruction->scalar = scalar;
2041
2042 ir_ref_instruction(len, ag->current_basic_block);
2043 ir_ref_instruction(scalar, ag->current_basic_block);
2044
2045 return &instruction->base;
2046}
2047
2048static IrInstSrc *ir_build_bool_not(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *value) {
2049 IrInstSrcBoolNot *instruction = ir_build_instruction<IrInstSrcBoolNot>(ag, scope, source_node);
2050 instruction->value = value;
2051
2052 ir_ref_instruction(value, ag->current_basic_block);
2053
2054 return &instruction->base;
2055}
2056
2057static IrInstSrc *ir_build_memset_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2058 IrInstSrc *dest_ptr, IrInstSrc *byte, IrInstSrc *count)
2059{
2060 IrInstSrcMemset *instruction = ir_build_instruction<IrInstSrcMemset>(ag, scope, source_node);
2061 instruction->dest_ptr = dest_ptr;
2062 instruction->byte = byte;
2063 instruction->count = count;
2064
2065 ir_ref_instruction(dest_ptr, ag->current_basic_block);
2066 ir_ref_instruction(byte, ag->current_basic_block);
2067 ir_ref_instruction(count, ag->current_basic_block);
2068
2069 return &instruction->base;
2070}
2071
2072static IrInstSrc *ir_build_memcpy_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2073 IrInstSrc *dest_ptr, IrInstSrc *src_ptr, IrInstSrc *count)
2074{
2075 IrInstSrcMemcpy *instruction = ir_build_instruction<IrInstSrcMemcpy>(ag, scope, source_node);
2076 instruction->dest_ptr = dest_ptr;
2077 instruction->src_ptr = src_ptr;
2078 instruction->count = count;
2079
2080 ir_ref_instruction(dest_ptr, ag->current_basic_block);
2081 ir_ref_instruction(src_ptr, ag->current_basic_block);
2082 ir_ref_instruction(count, ag->current_basic_block);
2083
2084 return &instruction->base;
2085}
2086
2087static IrInstSrc *ir_build_slice_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2088 IrInstSrc *ptr, IrInstSrc *start, IrInstSrc *end, IrInstSrc *sentinel,
2089 bool safety_check_on, ResultLoc *result_loc)
2090{
2091 IrInstSrcSlice *instruction = ir_build_instruction<IrInstSrcSlice>(ag, scope, source_node);
2092 instruction->ptr = ptr;
2093 instruction->start = start;
2094 instruction->end = end;
2095 instruction->sentinel = sentinel;
2096 instruction->safety_check_on = safety_check_on;
2097 instruction->result_loc = result_loc;
2098
2099 ir_ref_instruction(ptr, ag->current_basic_block);
2100 ir_ref_instruction(start, ag->current_basic_block);
2101 if (end) ir_ref_instruction(end, ag->current_basic_block);
2102 if (sentinel) ir_ref_instruction(sentinel, ag->current_basic_block);
2103
2104 return &instruction->base;
2105}
2106
2107static IrInstSrc *ir_build_breakpoint(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2108 IrInstSrcBreakpoint *instruction = ir_build_instruction<IrInstSrcBreakpoint>(ag, scope, source_node);
2109 return &instruction->base;
2110}
2111
2112static IrInstSrc *ir_build_return_address_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2113 IrInstSrcReturnAddress *instruction = ir_build_instruction<IrInstSrcReturnAddress>(ag, scope, source_node);
2114 return &instruction->base;
2115}
2116
2117static IrInstSrc *ir_build_frame_address_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2118 IrInstSrcFrameAddress *inst = ir_build_instruction<IrInstSrcFrameAddress>(ag, scope, source_node);
2119 return &inst->base;
2120}
2121
2122static IrInstSrc *ir_build_handle_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2123 IrInstSrcFrameHandle *inst = ir_build_instruction<IrInstSrcFrameHandle>(ag, scope, source_node);
2124 return &inst->base;
2125}
2126
2127static IrInstSrc *ir_build_frame_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *fn) {
2128 IrInstSrcFrameType *inst = ir_build_instruction<IrInstSrcFrameType>(ag, scope, source_node);
2129 inst->fn = fn;
2130
2131 ir_ref_instruction(fn, ag->current_basic_block);
2132
2133 return &inst->base;
2134}
2135
2136static IrInstSrc *ir_build_frame_size_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *fn) {
2137 IrInstSrcFrameSize *inst = ir_build_instruction<IrInstSrcFrameSize>(ag, scope, source_node);
2138 inst->fn = fn;
2139
2140 ir_ref_instruction(fn, ag->current_basic_block);
2141
2142 return &inst->base;
2143}
2144
2145static IrInstSrc *ir_build_overflow_op_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2146 IrOverflowOp op, IrInstSrc *type_value, IrInstSrc *op1, IrInstSrc *op2, IrInstSrc *result_ptr)
2147{
2148 IrInstSrcOverflowOp *instruction = ir_build_instruction<IrInstSrcOverflowOp>(ag, scope, source_node);
2149 instruction->op = op;
2150 instruction->type_value = type_value;
2151 instruction->op1 = op1;
2152 instruction->op2 = op2;
2153 instruction->result_ptr = result_ptr;
2154
2155 ir_ref_instruction(type_value, ag->current_basic_block);
2156 ir_ref_instruction(op1, ag->current_basic_block);
2157 ir_ref_instruction(op2, ag->current_basic_block);
2158 ir_ref_instruction(result_ptr, ag->current_basic_block);
2159
2160 return &instruction->base;
2161}
2162
2163static IrInstSrc *ir_build_float_op_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *operand,
2164 BuiltinFnId fn_id)
2165{
2166 IrInstSrcFloatOp *instruction = ir_build_instruction<IrInstSrcFloatOp>(ag, scope, source_node);
2167 instruction->operand = operand;
2168 instruction->fn_id = fn_id;
2169
2170 ir_ref_instruction(operand, ag->current_basic_block);
2171
2172 return &instruction->base;
2173}
2174
2175static IrInstSrc *ir_build_mul_add_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2176 IrInstSrc *type_value, IrInstSrc *op1, IrInstSrc *op2, IrInstSrc *op3)
2177{
2178 IrInstSrcMulAdd *instruction = ir_build_instruction<IrInstSrcMulAdd>(ag, scope, source_node);
2179 instruction->type_value = type_value;
2180 instruction->op1 = op1;
2181 instruction->op2 = op2;
2182 instruction->op3 = op3;
2183
2184 ir_ref_instruction(type_value, ag->current_basic_block);
2185 ir_ref_instruction(op1, ag->current_basic_block);
2186 ir_ref_instruction(op2, ag->current_basic_block);
2187 ir_ref_instruction(op3, ag->current_basic_block);
2188
2189 return &instruction->base;
2190}
2191
2192static IrInstSrc *ir_build_align_of(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *type_value) {
2193 IrInstSrcAlignOf *instruction = ir_build_instruction<IrInstSrcAlignOf>(ag, scope, source_node);
2194 instruction->type_value = type_value;
2195
2196 ir_ref_instruction(type_value, ag->current_basic_block);
2197
2198 return &instruction->base;
2199}
2200
2201static IrInstSrc *ir_build_test_err_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2202 IrInstSrc *base_ptr, bool resolve_err_set, bool base_ptr_is_payload)
2203{
2204 IrInstSrcTestErr *instruction = ir_build_instruction<IrInstSrcTestErr>(ag, scope, source_node);
2205 instruction->base_ptr = base_ptr;
2206 instruction->resolve_err_set = resolve_err_set;
2207 instruction->base_ptr_is_payload = base_ptr_is_payload;
2208
2209 ir_ref_instruction(base_ptr, ag->current_basic_block);
2210
2211 return &instruction->base;
2212}
2213
2214static IrInstSrc *ir_build_unwrap_err_code_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2215 IrInstSrc *err_union_ptr)
2216{
2217 IrInstSrcUnwrapErrCode *inst = ir_build_instruction<IrInstSrcUnwrapErrCode>(ag, scope, source_node);
2218 inst->err_union_ptr = err_union_ptr;
2219
2220 ir_ref_instruction(err_union_ptr, ag->current_basic_block);
2221
2222 return &inst->base;
2223}
2224
2225static IrInstSrc *ir_build_unwrap_err_payload_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2226 IrInstSrc *value, bool safety_check_on, bool initializing)
2227{
2228 IrInstSrcUnwrapErrPayload *inst = ir_build_instruction<IrInstSrcUnwrapErrPayload>(ag, scope, source_node);
2229 inst->value = value;
2230 inst->safety_check_on = safety_check_on;
2231 inst->initializing = initializing;
2232
2233 ir_ref_instruction(value, ag->current_basic_block);
2234
2235 return &inst->base;
2236}
2237
2238static IrInstSrc *ir_build_fn_proto(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2239 IrInstSrc **param_types, IrInstSrc *align_value, IrInstSrc *callconv_value,
2240 IrInstSrc *return_type, bool is_var_args)
2241{
2242 IrInstSrcFnProto *instruction = ir_build_instruction<IrInstSrcFnProto>(ag, scope, source_node);
2243 instruction->param_types = param_types;
2244 instruction->align_value = align_value;
2245 instruction->callconv_value = callconv_value;
2246 instruction->return_type = return_type;
2247 instruction->is_var_args = is_var_args;
2248
2249 assert(source_node->type == NodeTypeFnProto);
2250 size_t param_count = source_node->data.fn_proto.params.length;
2251 if (is_var_args) param_count -= 1;
2252 for (size_t i = 0; i < param_count; i += 1) {
2253 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], ag->current_basic_block);
2254 }
2255 if (align_value != nullptr) ir_ref_instruction(align_value, ag->current_basic_block);
2256 if (callconv_value != nullptr) ir_ref_instruction(callconv_value, ag->current_basic_block);
2257 ir_ref_instruction(return_type, ag->current_basic_block);
2258
2259 return &instruction->base;
2260}
2261
2262static IrInstSrc *ir_build_test_comptime(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *value) {
2263 IrInstSrcTestComptime *instruction = ir_build_instruction<IrInstSrcTestComptime>(ag, scope, source_node);
2264 instruction->value = value;
2265
2266 ir_ref_instruction(value, ag->current_basic_block);
2267
2268 return &instruction->base;
2269}
2270
2271static IrInstSrc *ir_build_ptr_cast_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2272 IrInstSrc *dest_type, IrInstSrc *ptr, bool safety_check_on)
2273{
2274 IrInstSrcPtrCast *instruction = ir_build_instruction<IrInstSrcPtrCast>(
2275 ag, scope, source_node);
2276 instruction->dest_type = dest_type;
2277 instruction->ptr = ptr;
2278 instruction->safety_check_on = safety_check_on;
2279
2280 ir_ref_instruction(dest_type, ag->current_basic_block);
2281 ir_ref_instruction(ptr, ag->current_basic_block);
2282
2283 return &instruction->base;
2284}
2285
2286static IrInstSrc *ir_build_implicit_cast(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2287 IrInstSrc *operand, ResultLocCast *result_loc_cast)
2288{
2289 IrInstSrcImplicitCast *instruction = ir_build_instruction<IrInstSrcImplicitCast>(ag, scope, source_node);
2290 instruction->operand = operand;
2291 instruction->result_loc_cast = result_loc_cast;
2292
2293 ir_ref_instruction(operand, ag->current_basic_block);
2294
2295 return &instruction->base;
2296}
2297
2298static IrInstSrc *ir_build_bit_cast_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2299 IrInstSrc *operand, ResultLocBitCast *result_loc_bit_cast)
2300{
2301 IrInstSrcBitCast *instruction = ir_build_instruction<IrInstSrcBitCast>(ag, scope, source_node);
2302 instruction->operand = operand;
2303 instruction->result_loc_bit_cast = result_loc_bit_cast;
2304
2305 ir_ref_instruction(operand, ag->current_basic_block);
2306
2307 return &instruction->base;
2308}
2309
2310static IrInstSrc *ir_build_int_to_ptr_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2311 IrInstSrc *dest_type, IrInstSrc *target)
2312{
2313 IrInstSrcIntToPtr *instruction = ir_build_instruction<IrInstSrcIntToPtr>(ag, scope, source_node);
2314 instruction->dest_type = dest_type;
2315 instruction->target = target;
2316
2317 ir_ref_instruction(dest_type, ag->current_basic_block);
2318 ir_ref_instruction(target, ag->current_basic_block);
2319
2320 return &instruction->base;
2321}
2322
2323static IrInstSrc *ir_build_ptr_to_int_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2324 IrInstSrc *target)
2325{
2326 IrInstSrcPtrToInt *inst = ir_build_instruction<IrInstSrcPtrToInt>(ag, scope, source_node);
2327 inst->target = target;
2328
2329 ir_ref_instruction(target, ag->current_basic_block);
2330
2331 return &inst->base;
2332}
2333
2334static IrInstSrc *ir_build_int_to_enum_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2335 IrInstSrc *dest_type, IrInstSrc *target)
2336{
2337 IrInstSrcIntToEnum *instruction = ir_build_instruction<IrInstSrcIntToEnum>(ag, scope, source_node);
2338 instruction->dest_type = dest_type;
2339 instruction->target = target;
2340
2341 if (dest_type) ir_ref_instruction(dest_type, ag->current_basic_block);
2342 ir_ref_instruction(target, ag->current_basic_block);
2343
2344 return &instruction->base;
2345}
2346
2347static IrInstSrc *ir_build_enum_to_int(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2348 IrInstSrc *target)
2349{
2350 IrInstSrcEnumToInt *instruction = ir_build_instruction<IrInstSrcEnumToInt>(
2351 ag, scope, source_node);
2352 instruction->target = target;
2353
2354 ir_ref_instruction(target, ag->current_basic_block);
2355
2356 return &instruction->base;
2357}
2358
2359static IrInstSrc *ir_build_int_to_err_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2360 IrInstSrc *target)
2361{
2362 IrInstSrcIntToErr *instruction = ir_build_instruction<IrInstSrcIntToErr>(ag, scope, source_node);
2363 instruction->target = target;
2364
2365 ir_ref_instruction(target, ag->current_basic_block);
2366
2367 return &instruction->base;
2368}
2369
2370static IrInstSrc *ir_build_err_to_int_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2371 IrInstSrc *target)
2372{
2373 IrInstSrcErrToInt *instruction = ir_build_instruction<IrInstSrcErrToInt>(
2374 ag, scope, source_node);
2375 instruction->target = target;
2376
2377 ir_ref_instruction(target, ag->current_basic_block);
2378
2379 return &instruction->base;
2380}
2381
2382static IrInstSrc *ir_build_check_switch_prongs(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2383 IrInstSrc *target_value, IrInstSrcCheckSwitchProngsRange *ranges, size_t range_count,
2384 AstNode* else_prong, bool have_underscore_prong)
2385{
2386 IrInstSrcCheckSwitchProngs *instruction = heap::c_allocator.create<IrInstSrcCheckSwitchProngs>();
2387 instruction->base.id = have_underscore_prong ?
2388 IrInstSrcIdCheckSwitchProngsUnderYes : IrInstSrcIdCheckSwitchProngsUnderNo;
2389 instruction->base.base.scope = scope;
2390 instruction->base.base.source_node = source_node;
2391 instruction->base.base.debug_id = irb_next_debug_id(ag);
2392 instruction->base.owner_bb = ag->current_basic_block;
2393 ir_instruction_append(ag->current_basic_block, &instruction->base);
2394
2395 instruction->target_value = target_value;
2396 instruction->ranges = ranges;
2397 instruction->range_count = range_count;
2398 instruction->else_prong = else_prong;
2399
2400 ir_ref_instruction(target_value, ag->current_basic_block);
2401 for (size_t i = 0; i < range_count; i += 1) {
2402 ir_ref_instruction(ranges[i].start, ag->current_basic_block);
2403 ir_ref_instruction(ranges[i].end, ag->current_basic_block);
2404 }
2405
2406 return &instruction->base;
2407}
2408
2409static IrInstSrc *ir_build_check_statement_is_void(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2410 IrInstSrc* statement_value)
2411{
2412 IrInstSrcCheckStatementIsVoid *instruction = ir_build_instruction<IrInstSrcCheckStatementIsVoid>(
2413 ag, scope, source_node);
2414 instruction->statement_value = statement_value;
2415
2416 ir_ref_instruction(statement_value, ag->current_basic_block);
2417
2418 return &instruction->base;
2419}
2420
2421static IrInstSrc *ir_build_type_name(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2422 IrInstSrc *type_value)
2423{
2424 IrInstSrcTypeName *instruction = ir_build_instruction<IrInstSrcTypeName>(ag, scope, source_node);
2425 instruction->type_value = type_value;
2426
2427 ir_ref_instruction(type_value, ag->current_basic_block);
2428
2429 return &instruction->base;
2430}
2431
2432static IrInstSrc *ir_build_decl_ref(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) {
2433 IrInstSrcDeclRef *instruction = ir_build_instruction<IrInstSrcDeclRef>(ag, scope, source_node);
2434 instruction->tld = tld;
2435 instruction->lval = lval;
2436
2437 return &instruction->base;
2438}
2439
2440static IrInstSrc *ir_build_panic_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *msg) {
2441 IrInstSrcPanic *instruction = ir_build_instruction<IrInstSrcPanic>(ag, scope, source_node);
2442 instruction->base.is_noreturn = true;
2443 instruction->msg = msg;
2444
2445 ir_ref_instruction(msg, ag->current_basic_block);
2446
2447 return &instruction->base;
2448}
2449
2450static IrInstSrc *ir_build_tag_name_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *target) {
2451 IrInstSrcTagName *instruction = ir_build_instruction<IrInstSrcTagName>(ag, scope, source_node);
2452 instruction->target = target;
2453
2454 ir_ref_instruction(target, ag->current_basic_block);
2455
2456 return &instruction->base;
2457}
2458
2459static IrInstSrc *ir_build_field_parent_ptr_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2460 IrInstSrc *type_value, IrInstSrc *field_name, IrInstSrc *field_ptr)
2461{
2462 IrInstSrcFieldParentPtr *inst = ir_build_instruction<IrInstSrcFieldParentPtr>(
2463 ag, scope, source_node);
2464 inst->type_value = type_value;
2465 inst->field_name = field_name;
2466 inst->field_ptr = field_ptr;
2467
2468 ir_ref_instruction(type_value, ag->current_basic_block);
2469 ir_ref_instruction(field_name, ag->current_basic_block);
2470 ir_ref_instruction(field_ptr, ag->current_basic_block);
2471
2472 return &inst->base;
2473}
2474
2475static IrInstSrc *ir_build_byte_offset_of(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2476 IrInstSrc *type_value, IrInstSrc *field_name)
2477{
2478 IrInstSrcByteOffsetOf *instruction = ir_build_instruction<IrInstSrcByteOffsetOf>(ag, scope, source_node);
2479 instruction->type_value = type_value;
2480 instruction->field_name = field_name;
2481
2482 ir_ref_instruction(type_value, ag->current_basic_block);
2483 ir_ref_instruction(field_name, ag->current_basic_block);
2484
2485 return &instruction->base;
2486}
2487
2488static IrInstSrc *ir_build_bit_offset_of(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2489 IrInstSrc *type_value, IrInstSrc *field_name)
2490{
2491 IrInstSrcBitOffsetOf *instruction = ir_build_instruction<IrInstSrcBitOffsetOf>(ag, scope, source_node);
2492 instruction->type_value = type_value;
2493 instruction->field_name = field_name;
2494
2495 ir_ref_instruction(type_value, ag->current_basic_block);
2496 ir_ref_instruction(field_name, ag->current_basic_block);
2497
2498 return &instruction->base;
2499}
2500
2501static IrInstSrc *ir_build_type_info(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *type_value) {
2502 IrInstSrcTypeInfo *instruction = ir_build_instruction<IrInstSrcTypeInfo>(ag, scope, source_node);
2503 instruction->type_value = type_value;
2504
2505 ir_ref_instruction(type_value, ag->current_basic_block);
2506
2507 return &instruction->base;
2508}
2509
2510static IrInstSrc *ir_build_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *type_info) {
2511 IrInstSrcType *instruction = ir_build_instruction<IrInstSrcType>(ag, scope, source_node);
2512 instruction->type_info = type_info;
2513
2514 ir_ref_instruction(type_info, ag->current_basic_block);
2515
2516 return &instruction->base;
2517}
2518
2519static IrInstSrc *ir_build_set_eval_branch_quota(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2520 IrInstSrc *new_quota)
2521{
2522 IrInstSrcSetEvalBranchQuota *instruction = ir_build_instruction<IrInstSrcSetEvalBranchQuota>(ag, scope, source_node);
2523 instruction->new_quota = new_quota;
2524
2525 ir_ref_instruction(new_quota, ag->current_basic_block);
2526
2527 return &instruction->base;
2528}
2529
2530static IrInstSrc *ir_build_align_cast_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2531 IrInstSrc *align_bytes, IrInstSrc *target)
2532{
2533 IrInstSrcAlignCast *instruction = ir_build_instruction<IrInstSrcAlignCast>(ag, scope, source_node);
2534 instruction->align_bytes = align_bytes;
2535 instruction->target = target;
2536
2537 ir_ref_instruction(align_bytes, ag->current_basic_block);
2538 ir_ref_instruction(target, ag->current_basic_block);
2539
2540 return &instruction->base;
2541}
2542
2543static IrInstSrc *ir_build_resolve_result(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2544 ResultLoc *result_loc, IrInstSrc *ty)
2545{
2546 IrInstSrcResolveResult *instruction = ir_build_instruction<IrInstSrcResolveResult>(ag, scope, source_node);
2547 instruction->result_loc = result_loc;
2548 instruction->ty = ty;
2549
2550 if (ty != nullptr) ir_ref_instruction(ty, ag->current_basic_block);
2551
2552 return &instruction->base;
2553}
2554
2555static IrInstSrc *ir_build_reset_result(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2556 ResultLoc *result_loc)
2557{
2558 IrInstSrcResetResult *instruction = ir_build_instruction<IrInstSrcResetResult>(ag, scope, source_node);
2559 instruction->result_loc = result_loc;
2560 instruction->base.is_gen = true;
2561
2562 return &instruction->base;
2563}
2564
2565static IrInstSrc *ir_build_set_align_stack(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2566 IrInstSrc *align_bytes)
2567{
2568 IrInstSrcSetAlignStack *instruction = ir_build_instruction<IrInstSrcSetAlignStack>(ag, scope, source_node);
2569 instruction->align_bytes = align_bytes;
2570
2571 ir_ref_instruction(align_bytes, ag->current_basic_block);
2572
2573 return &instruction->base;
2574}
2575
2576static IrInstSrc *ir_build_arg_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2577 IrInstSrc *fn_type, IrInstSrc *arg_index, bool allow_var)
2578{
2579 IrInstSrcArgType *instruction = heap::c_allocator.create<IrInstSrcArgType>();
2580 instruction->base.id = allow_var ?
2581 IrInstSrcIdArgTypeAllowVarTrue : IrInstSrcIdArgTypeAllowVarFalse;
2582 instruction->base.base.scope = scope;
2583 instruction->base.base.source_node = source_node;
2584 instruction->base.base.debug_id = irb_next_debug_id(ag);
2585 instruction->base.owner_bb = ag->current_basic_block;
2586 ir_instruction_append(ag->current_basic_block, &instruction->base);
2587
2588 instruction->fn_type = fn_type;
2589 instruction->arg_index = arg_index;
2590
2591 ir_ref_instruction(fn_type, ag->current_basic_block);
2592 ir_ref_instruction(arg_index, ag->current_basic_block);
2593
2594 return &instruction->base;
2595}
2596
2597static IrInstSrc *ir_build_error_return_trace_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2598 IrInstErrorReturnTraceOptional optional)
2599{
2600 IrInstSrcErrorReturnTrace *inst = ir_build_instruction<IrInstSrcErrorReturnTrace>(ag, scope, source_node);
2601 inst->optional = optional;
2602
2603 return &inst->base;
2604}
2605
2606static IrInstSrc *ir_build_error_union(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2607 IrInstSrc *err_set, IrInstSrc *payload)
2608{
2609 IrInstSrcErrorUnion *instruction = ir_build_instruction<IrInstSrcErrorUnion>(ag, scope, source_node);
2610 instruction->err_set = err_set;
2611 instruction->payload = payload;
2612
2613 ir_ref_instruction(err_set, ag->current_basic_block);
2614 ir_ref_instruction(payload, ag->current_basic_block);
2615
2616 return &instruction->base;
2617}
2618
2619static IrInstSrc *ir_build_atomic_rmw_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2620 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *op, IrInstSrc *operand,
2621 IrInstSrc *ordering)
2622{
2623 IrInstSrcAtomicRmw *instruction = ir_build_instruction<IrInstSrcAtomicRmw>(ag, scope, source_node);
2624 instruction->operand_type = operand_type;
2625 instruction->ptr = ptr;
2626 instruction->op = op;
2627 instruction->operand = operand;
2628 instruction->ordering = ordering;
2629
2630 ir_ref_instruction(operand_type, ag->current_basic_block);
2631 ir_ref_instruction(ptr, ag->current_basic_block);
2632 ir_ref_instruction(op, ag->current_basic_block);
2633 ir_ref_instruction(operand, ag->current_basic_block);
2634 ir_ref_instruction(ordering, ag->current_basic_block);
2635
2636 return &instruction->base;
2637}
2638
2639static IrInstSrc *ir_build_atomic_load_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2640 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *ordering)
2641{
2642 IrInstSrcAtomicLoad *instruction = ir_build_instruction<IrInstSrcAtomicLoad>(ag, scope, source_node);
2643 instruction->operand_type = operand_type;
2644 instruction->ptr = ptr;
2645 instruction->ordering = ordering;
2646
2647 ir_ref_instruction(operand_type, ag->current_basic_block);
2648 ir_ref_instruction(ptr, ag->current_basic_block);
2649 ir_ref_instruction(ordering, ag->current_basic_block);
2650
2651 return &instruction->base;
2652}
2653
2654static IrInstSrc *ir_build_atomic_store_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2655 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *value, IrInstSrc *ordering)
2656{
2657 IrInstSrcAtomicStore *instruction = ir_build_instruction<IrInstSrcAtomicStore>(ag, scope, source_node);
2658 instruction->operand_type = operand_type;
2659 instruction->ptr = ptr;
2660 instruction->value = value;
2661 instruction->ordering = ordering;
2662
2663 ir_ref_instruction(operand_type, ag->current_basic_block);
2664 ir_ref_instruction(ptr, ag->current_basic_block);
2665 ir_ref_instruction(value, ag->current_basic_block);
2666 ir_ref_instruction(ordering, ag->current_basic_block);
2667
2668 return &instruction->base;
2669}
2670
2671static IrInstSrc *ir_build_save_err_ret_addr_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2672 IrInstSrcSaveErrRetAddr *inst = ir_build_instruction<IrInstSrcSaveErrRetAddr>(ag, scope, source_node);
2673 return &inst->base;
2674}
2675
2676static IrInstSrc *ir_build_add_implicit_return_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2677 IrInstSrc *value, ResultLocReturn *result_loc_ret)
2678{
2679 IrInstSrcAddImplicitReturnType *inst = ir_build_instruction<IrInstSrcAddImplicitReturnType>(ag, scope, source_node);
2680 inst->value = value;
2681 inst->result_loc_ret = result_loc_ret;
2682
2683 ir_ref_instruction(value, ag->current_basic_block);
2684
2685 return &inst->base;
2686}
2687
2688static IrInstSrc *ir_build_has_decl(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2689 IrInstSrc *container, IrInstSrc *name)
2690{
2691 IrInstSrcHasDecl *instruction = ir_build_instruction<IrInstSrcHasDecl>(ag, scope, source_node);
2692 instruction->container = container;
2693 instruction->name = name;
2694
2695 ir_ref_instruction(container, ag->current_basic_block);
2696 ir_ref_instruction(name, ag->current_basic_block);
2697
2698 return &instruction->base;
2699}
2700
2701static IrInstSrc *ir_build_undeclared_identifier(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Buf *name) {
2702 IrInstSrcUndeclaredIdent *instruction = ir_build_instruction<IrInstSrcUndeclaredIdent>(ag, scope, source_node);
2703 instruction->name = name;
2704
2705 return &instruction->base;
2706}
2707
2708static IrInstSrc *ir_build_check_runtime_scope(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *scope_is_comptime, IrInstSrc *is_comptime) {
2709 IrInstSrcCheckRuntimeScope *instruction = ir_build_instruction<IrInstSrcCheckRuntimeScope>(ag, scope, source_node);
2710 instruction->scope_is_comptime = scope_is_comptime;
2711 instruction->is_comptime = is_comptime;
2712
2713 ir_ref_instruction(scope_is_comptime, ag->current_basic_block);
2714 ir_ref_instruction(is_comptime, ag->current_basic_block);
2715
2716 return &instruction->base;
2717}
2718
2719static IrInstSrc *ir_build_union_init_named_field(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2720 IrInstSrc *union_type, IrInstSrc *field_name, IrInstSrc *field_result_loc, IrInstSrc *result_loc)
2721{
2722 IrInstSrcUnionInitNamedField *instruction = ir_build_instruction<IrInstSrcUnionInitNamedField>(ag, scope, source_node);
2723 instruction->union_type = union_type;
2724 instruction->field_name = field_name;
2725 instruction->field_result_loc = field_result_loc;
2726 instruction->result_loc = result_loc;
2727
2728 ir_ref_instruction(union_type, ag->current_basic_block);
2729 ir_ref_instruction(field_name, ag->current_basic_block);
2730 ir_ref_instruction(field_result_loc, ag->current_basic_block);
2731 if (result_loc != nullptr) ir_ref_instruction(result_loc, ag->current_basic_block);
2732
2733 return &instruction->base;
2734}
2735
2736static IrInstSrc *ir_build_alloca_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2737 IrInstSrc *align, const char *name_hint, IrInstSrc *is_comptime)
2738{
2739 IrInstSrcAlloca *instruction = ir_build_instruction<IrInstSrcAlloca>(ag, scope, source_node);
2740 instruction->base.is_gen = true;
2741 instruction->align = align;
2742 instruction->name_hint = name_hint;
2743 instruction->is_comptime = is_comptime;
2744
2745 if (align != nullptr) ir_ref_instruction(align, ag->current_basic_block);
2746 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, ag->current_basic_block);
2747
2748 return &instruction->base;
2749}
2750
2751static IrInstSrc *ir_build_end_expr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2752 IrInstSrc *value, ResultLoc *result_loc)
2753{
2754 IrInstSrcEndExpr *instruction = ir_build_instruction<IrInstSrcEndExpr>(ag, scope, source_node);
2755 instruction->base.is_gen = true;
2756 instruction->value = value;
2757 instruction->result_loc = result_loc;
2758
2759 ir_ref_instruction(value, ag->current_basic_block);
2760
2761 return &instruction->base;
2762}
2763
2764static IrInstSrcSuspendBegin *ir_build_suspend_begin_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2765 return ir_build_instruction<IrInstSrcSuspendBegin>(ag, scope, source_node);
2766}
2767
2768static IrInstSrc *ir_build_suspend_finish_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2769 IrInstSrcSuspendBegin *begin)
2770{
2771 IrInstSrcSuspendFinish *inst = ir_build_instruction<IrInstSrcSuspendFinish>(ag, scope, source_node);
2772 inst->begin = begin;
2773
2774 ir_ref_instruction(&begin->base, ag->current_basic_block);
2775
2776 return &inst->base;
2777}
2778
2779static IrInstSrc *ir_build_await_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2780 IrInstSrc *frame, ResultLoc *result_loc, bool is_nosuspend)
2781{
2782 IrInstSrcAwait *instruction = ir_build_instruction<IrInstSrcAwait>(ag, scope, source_node);
2783 instruction->frame = frame;
2784 instruction->result_loc = result_loc;
2785 instruction->is_nosuspend = is_nosuspend;
2786
2787 ir_ref_instruction(frame, ag->current_basic_block);
2788
2789 return &instruction->base;
2790}
2791
2792static IrInstSrc *ir_build_resume_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *frame) {
2793 IrInstSrcResume *instruction = ir_build_instruction<IrInstSrcResume>(ag, scope, source_node);
2794 instruction->frame = frame;
2795
2796 ir_ref_instruction(frame, ag->current_basic_block);
2797
2798 return &instruction->base;
2799}
2800
2801static IrInstSrcSpillBegin *ir_build_spill_begin_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2802 IrInstSrc *operand, SpillId spill_id)
2803{
2804 IrInstSrcSpillBegin *instruction = ir_build_instruction<IrInstSrcSpillBegin>(ag, scope, source_node);
2805 instruction->operand = operand;
2806 instruction->spill_id = spill_id;
2807
2808 ir_ref_instruction(operand, ag->current_basic_block);
2809
2810 return instruction;
2811}
2812
2813static IrInstSrc *ir_build_spill_end_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2814 IrInstSrcSpillBegin *begin)
2815{
2816 IrInstSrcSpillEnd *instruction = ir_build_instruction<IrInstSrcSpillEnd>(ag, scope, source_node);
2817 instruction->begin = begin;
2818
2819 ir_ref_instruction(&begin->base, ag->current_basic_block);
2820
2821 return &instruction->base;
2822}
2823
2824static IrInstSrc *ir_build_wasm_memory_size_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *index) {
2825 IrInstSrcWasmMemorySize *instruction = ir_build_instruction<IrInstSrcWasmMemorySize>(ag, scope, source_node);
2826 instruction->index = index;
2827
2828 ir_ref_instruction(index, ag->current_basic_block);
2829
2830 return &instruction->base;
2831}
2832
2833static IrInstSrc *ir_build_wasm_memory_grow_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrInstSrc *index, IrInstSrc *delta) {
2834 IrInstSrcWasmMemoryGrow *instruction = ir_build_instruction<IrInstSrcWasmMemoryGrow>(ag, scope, source_node);
2835 instruction->index = index;
2836 instruction->delta = delta;
2837
2838 ir_ref_instruction(index, ag->current_basic_block);
2839 ir_ref_instruction(delta, ag->current_basic_block);
2840
2841 return &instruction->base;
2842}
2843
2844static IrInstSrc *ir_build_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2845 IrInstSrcSrc *instruction = ir_build_instruction<IrInstSrcSrc>(ag, scope, source_node);
2846
2847 return &instruction->base;
2848}
2849
2850static void ir_count_defers(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_scope, size_t *results) {
2851 results[ReturnKindUnconditional] = 0;
2852 results[ReturnKindError] = 0;
2853
2854 Scope *scope = inner_scope;
2855
2856 while (scope != outer_scope) {
2857 assert(scope);
2858 switch (scope->id) {
2859 case ScopeIdDefer: {
2860 AstNode *defer_node = scope->source_node;
2861 assert(defer_node->type == NodeTypeDefer);
2862 ReturnKind defer_kind = defer_node->data.defer.kind;
2863 results[defer_kind] += 1;
2864 scope = scope->parent;
2865 continue;
2866 }
2867 case ScopeIdDecls:
2868 case ScopeIdFnDef:
2869 return;
2870 case ScopeIdBlock:
2871 case ScopeIdVarDecl:
2872 case ScopeIdLoop:
2873 case ScopeIdSuspend:
2874 case ScopeIdCompTime:
2875 case ScopeIdNoSuspend:
2876 case ScopeIdRuntime:
2877 case ScopeIdTypeOf:
2878 case ScopeIdExpr:
2879 scope = scope->parent;
2880 continue;
2881 case ScopeIdDeferExpr:
2882 case ScopeIdCImport:
2883 zig_unreachable();
2884 }
2885 }
2886}
2887
2888static IrInstSrc *ir_mark_gen(IrInstSrc *instruction) {
2889 instruction->is_gen = true;
2890 return instruction;
2891}
2892
2893static bool astgen_defers_for_block(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_scope, bool *is_noreturn, IrInstSrc *err_value) {
2894 Scope *scope = inner_scope;
2895 if (is_noreturn != nullptr) *is_noreturn = false;
2896 while (scope != outer_scope) {
2897 if (!scope)
2898 return true;
2899
2900 switch (scope->id) {
2901 case ScopeIdDefer: {
2902 AstNode *defer_node = scope->source_node;
2903 assert(defer_node->type == NodeTypeDefer);
2904 ReturnKind defer_kind = defer_node->data.defer.kind;
2905 AstNode *defer_expr_node = defer_node->data.defer.expr;
2906 AstNode *defer_var_node = defer_node->data.defer.err_payload;
2907
2908 if (defer_kind == ReturnKindError && err_value == nullptr) {
2909 // This is an `errdefer` but we're generating code for a
2910 // `return` that doesn't return an error, skip it
2911 scope = scope->parent;
2912 continue;
2913 }
2914
2915 Scope *defer_expr_scope = defer_node->data.defer.expr_scope;
2916 if (defer_var_node != nullptr) {
2917 assert(defer_kind == ReturnKindError);
2918 assert(defer_var_node->type == NodeTypeIdentifier);
2919 Buf *var_name = node_identifier_buf(defer_var_node);
2920
2921 if (defer_expr_node->type == NodeTypeUnreachable) {
2922 add_node_error(ag->codegen, defer_var_node,
2923 buf_sprintf("unused variable: '%s'", buf_ptr(var_name)));
2924 return false;
2925 }
2926
2927 IrInstSrc *is_comptime;
2928 if (ir_should_inline(ag->exec, defer_expr_scope)) {
2929 is_comptime = ir_build_const_bool(ag, defer_expr_scope,
2930 defer_expr_node, true);
2931 } else {
2932 is_comptime = ir_build_test_comptime(ag, defer_expr_scope,
2933 defer_expr_node, err_value);
2934 }
2935
2936 ZigVar *err_var = ir_create_var(ag, defer_var_node, defer_expr_scope,
2937 var_name, true, true, false, is_comptime);
2938 build_decl_var_and_init(ag, defer_expr_scope, defer_var_node, err_var, err_value,
2939 buf_ptr(var_name), is_comptime);
2940
2941 defer_expr_scope = err_var->child_scope;
2942 }
2943
2944 IrInstSrc *defer_expr_value = astgen_node(ag, defer_expr_node, defer_expr_scope);
2945 if (defer_expr_value == ag->codegen->invalid_inst_src)
2946 return ag->codegen->invalid_inst_src;
2947
2948 if (defer_expr_value->is_noreturn) {
2949 if (is_noreturn != nullptr) *is_noreturn = true;
2950 } else {
2951 ir_mark_gen(ir_build_check_statement_is_void(ag, defer_expr_scope, defer_expr_node,
2952 defer_expr_value));
2953 }
2954 scope = scope->parent;
2955 continue;
2956 }
2957 case ScopeIdDecls:
2958 case ScopeIdFnDef:
2959 return true;
2960 case ScopeIdBlock:
2961 case ScopeIdVarDecl:
2962 case ScopeIdLoop:
2963 case ScopeIdSuspend:
2964 case ScopeIdCompTime:
2965 case ScopeIdNoSuspend:
2966 case ScopeIdRuntime:
2967 case ScopeIdTypeOf:
2968 case ScopeIdExpr:
2969 scope = scope->parent;
2970 continue;
2971 case ScopeIdDeferExpr:
2972 case ScopeIdCImport:
2973 zig_unreachable();
2974 }
2975 }
2976 return true;
2977}
2978
2979static void ir_set_cursor_at_end(Stage1AstGen *ag, Stage1ZirBasicBlock *basic_block) {
2980 assert(basic_block);
2981 ag->current_basic_block = basic_block;
2982}
2983
2984static void ir_set_cursor_at_end_and_append_block(Stage1AstGen *ag, Stage1ZirBasicBlock *basic_block) {
2985 basic_block->index = ag->exec->basic_block_list.length;
2986 ag->exec->basic_block_list.append(basic_block);
2987 ir_set_cursor_at_end(ag, basic_block);
2988}
2989
2990static ScopeSuspend *get_scope_suspend(Scope *scope) {
2991 while (scope) {
2992 if (scope->id == ScopeIdSuspend)
2993 return (ScopeSuspend *)scope;
2994 if (scope->id == ScopeIdFnDef)
2995 return nullptr;
2996
2997 scope = scope->parent;
2998 }
2999 return nullptr;
3000}
3001
3002static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) {
3003 while (scope) {
3004 if (scope->id == ScopeIdDeferExpr)
3005 return (ScopeDeferExpr *)scope;
3006 if (scope->id == ScopeIdFnDef)
3007 return nullptr;
3008
3009 scope = scope->parent;
3010 }
3011 return nullptr;
3012}
3013
3014static IrInstSrc *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
3015 assert(node->type == NodeTypeReturnExpr);
3016
3017 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope);
3018 if (scope_defer_expr) {
3019 if (!scope_defer_expr->reported_err) {
3020 add_node_error(ag->codegen, node, buf_sprintf("cannot return from defer expression"));
3021 scope_defer_expr->reported_err = true;
3022 }
3023 return ag->codegen->invalid_inst_src;
3024 }
3025
3026 Scope *outer_scope = ag->exec->begin_scope;
3027
3028 AstNode *expr_node = node->data.return_expr.expr;
3029 switch (node->data.return_expr.kind) {
3030 case ReturnKindUnconditional:
3031 {
3032 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
3033 result_loc_ret->base.id = ResultLocIdReturn;
3034 ir_build_reset_result(ag, scope, node, &result_loc_ret->base);
3035
3036 IrInstSrc *return_value;
3037 if (expr_node) {
3038 // Temporarily set this so that if we return a type it gets the name of the function
3039 ZigFn *prev_name_fn = ag->exec->name_fn;
3040 ag->exec->name_fn = ag->fn;
3041 return_value = astgen_node_extra(ag, expr_node, scope, LValNone, &result_loc_ret->base);
3042 ag->exec->name_fn = prev_name_fn;
3043 if (return_value == ag->codegen->invalid_inst_src)
3044 return ag->codegen->invalid_inst_src;
3045 } else {
3046 return_value = ir_build_const_void(ag, scope, node);
3047 ir_build_end_expr(ag, scope, node, return_value, &result_loc_ret->base);
3048 }
3049
3050 ir_mark_gen(ir_build_add_implicit_return_type(ag, scope, node, return_value, result_loc_ret));
3051
3052 size_t defer_counts[2];
3053 ir_count_defers(ag, scope, outer_scope, defer_counts);
3054 bool have_err_defers = defer_counts[ReturnKindError] > 0;
3055 if (!have_err_defers && !ag->codegen->have_err_ret_tracing) {
3056 // only generate unconditional defers
3057 if (!astgen_defers_for_block(ag, scope, outer_scope, nullptr, nullptr))
3058 return ag->codegen->invalid_inst_src;
3059 IrInstSrc *result = ir_build_return_src(ag, scope, node, nullptr);
3060 result_loc_ret->base.source_instruction = result;
3061 return result;
3062 }
3063 bool should_inline = ir_should_inline(ag->exec, scope);
3064
3065 Stage1ZirBasicBlock *err_block = ir_create_basic_block(ag, scope, "ErrRetErr");
3066 Stage1ZirBasicBlock *ok_block = ir_create_basic_block(ag, scope, "ErrRetOk");
3067
3068 IrInstSrc *is_err = ir_build_test_err_src(ag, scope, node, return_value, false, true);
3069
3070 IrInstSrc *is_comptime;
3071 if (should_inline) {
3072 is_comptime = ir_build_const_bool(ag, scope, node, should_inline);
3073 } else {
3074 is_comptime = ir_build_test_comptime(ag, scope, node, is_err);
3075 }
3076
3077 ir_mark_gen(ir_build_cond_br(ag, scope, node, is_err, err_block, ok_block, is_comptime));
3078 Stage1ZirBasicBlock *ret_stmt_block = ir_create_basic_block(ag, scope, "RetStmt");
3079
3080 ir_set_cursor_at_end_and_append_block(ag, err_block);
3081 if (!astgen_defers_for_block(ag, scope, outer_scope, nullptr, return_value))
3082 return ag->codegen->invalid_inst_src;
3083 if (ag->codegen->have_err_ret_tracing && !should_inline) {
3084 ir_build_save_err_ret_addr_src(ag, scope, node);
3085 }
3086 ir_build_br(ag, scope, node, ret_stmt_block, is_comptime);
3087
3088 ir_set_cursor_at_end_and_append_block(ag, ok_block);
3089 if (!astgen_defers_for_block(ag, scope, outer_scope, nullptr, nullptr))
3090 return ag->codegen->invalid_inst_src;
3091 ir_build_br(ag, scope, node, ret_stmt_block, is_comptime);
3092
3093 ir_set_cursor_at_end_and_append_block(ag, ret_stmt_block);
3094 IrInstSrc *result = ir_build_return_src(ag, scope, node, nullptr);
3095 result_loc_ret->base.source_instruction = result;
3096 return result;
3097 }
3098 case ReturnKindError:
3099 {
3100 assert(expr_node);
3101 IrInstSrc *err_union_ptr = astgen_node_extra(ag, expr_node, scope, LValPtr, nullptr);
3102 if (err_union_ptr == ag->codegen->invalid_inst_src)
3103 return ag->codegen->invalid_inst_src;
3104 IrInstSrc *is_err_val = ir_build_test_err_src(ag, scope, node, err_union_ptr, true, false);
3105
3106 Stage1ZirBasicBlock *return_block = ir_create_basic_block(ag, scope, "ErrRetReturn");
3107 Stage1ZirBasicBlock *continue_block = ir_create_basic_block(ag, scope, "ErrRetContinue");
3108 IrInstSrc *is_comptime;
3109 bool should_inline = ir_should_inline(ag->exec, scope);
3110 if (should_inline) {
3111 is_comptime = ir_build_const_bool(ag, scope, node, true);
3112 } else {
3113 is_comptime = ir_build_test_comptime(ag, scope, node, is_err_val);
3114 }
3115 ir_mark_gen(ir_build_cond_br(ag, scope, node, is_err_val, return_block, continue_block, is_comptime));
3116
3117 ir_set_cursor_at_end_and_append_block(ag, return_block);
3118 IrInstSrc *err_val_ptr = ir_build_unwrap_err_code_src(ag, scope, node, err_union_ptr);
3119 IrInstSrc *err_val = ir_build_load_ptr(ag, scope, node, err_val_ptr);
3120 ir_mark_gen(ir_build_add_implicit_return_type(ag, scope, node, err_val, nullptr));
3121 IrInstSrcSpillBegin *spill_begin = ir_build_spill_begin_src(ag, scope, node, err_val,
3122 SpillIdRetErrCode);
3123 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
3124 result_loc_ret->base.id = ResultLocIdReturn;
3125 ir_build_reset_result(ag, scope, node, &result_loc_ret->base);
3126 ir_build_end_expr(ag, scope, node, err_val, &result_loc_ret->base);
3127
3128 bool is_noreturn = false;
3129 if (!astgen_defers_for_block(ag, scope, outer_scope, &is_noreturn, err_val)) {
3130 return ag->codegen->invalid_inst_src;
3131 }
3132 if (!is_noreturn) {
3133 if (ag->codegen->have_err_ret_tracing && !should_inline) {
3134 ir_build_save_err_ret_addr_src(ag, scope, node);
3135 }
3136 err_val = ir_build_spill_end_src(ag, scope, node, spill_begin);
3137 IrInstSrc *ret_inst = ir_build_return_src(ag, scope, node, err_val);
3138 result_loc_ret->base.source_instruction = ret_inst;
3139 }
3140
3141 ir_set_cursor_at_end_and_append_block(ag, continue_block);
3142 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(ag, scope, node, err_union_ptr, false, false);
3143 if (lval == LValPtr)
3144 return unwrapped_ptr;
3145 else
3146 return ir_expr_wrap(ag, scope, ir_build_load_ptr(ag, scope, node, unwrapped_ptr), result_loc);
3147 }
3148 }
3149 zig_unreachable();
3150}
3151
3152ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
3153 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime,
3154 bool skip_name_check)
3155{
3156 ZigVar *variable_entry = heap::c_allocator.create<ZigVar>();
3157 variable_entry->parent_scope = parent_scope;
3158 variable_entry->shadowable = is_shadowable;
3159 variable_entry->is_comptime = is_comptime;
3160 variable_entry->src_arg_index = SIZE_MAX;
3161 variable_entry->const_value = codegen->pass1_arena->create<ZigValue>();
3162
3163 if (is_comptime != nullptr) {
3164 is_comptime->base.ref_count += 1;
3165 }
3166
3167 if (name) {
3168 variable_entry->name = strdup(buf_ptr(name));
3169
3170 if (!skip_name_check) {
3171 ZigVar *existing_var = find_variable(codegen, parent_scope, name, nullptr);
3172 if (existing_var && !existing_var->shadowable) {
3173 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) {
3174 ErrorMsg *msg = add_node_error(codegen, node,
3175 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
3176 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
3177 }
3178 variable_entry->var_type = codegen->builtin_types.entry_invalid;
3179 } else {
3180 ZigType *type;
3181 if (get_primitive_type(codegen, name, &type) != ErrorPrimitiveTypeNotFound) {
3182 add_node_error(codegen, node,
3183 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name)));
3184 variable_entry->var_type = codegen->builtin_types.entry_invalid;
3185 } else {
3186 Tld *tld = find_decl(codegen, parent_scope, name);
3187 if (tld != nullptr) {
3188 bool want_err_msg = true;
3189 if (tld->id == TldIdVar) {
3190 ZigVar *var = reinterpret_cast<TldVar *>(tld)->var;
3191 if (var != nullptr && var->var_type != nullptr && type_is_invalid(var->var_type)) {
3192 want_err_msg = false;
3193 }
3194 }
3195 if (want_err_msg) {
3196 ErrorMsg *msg = add_node_error(codegen, node,
3197 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
3198 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here"));
3199 }
3200 variable_entry->var_type = codegen->builtin_types.entry_invalid;
3201 }
3202 }
3203 }
3204 }
3205 } else {
3206 assert(is_shadowable);
3207 // TODO make this name not actually be in scope. user should be able to make a variable called "_anon"
3208 // might already be solved, let's just make sure it has test coverage
3209 // maybe we put a prefix on this so the debug info doesn't clobber user debug info for same named variables
3210 variable_entry->name = "_anon";
3211 }
3212
3213 variable_entry->src_is_const = src_is_const;
3214 variable_entry->gen_is_const = gen_is_const;
3215 variable_entry->decl_node = node;
3216 variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry);
3217
3218 return variable_entry;
3219}
3220
3221
3222// Set name to nullptr to make the variable anonymous (not visible to programmer).
3223// After you call this function var->child_scope has the variable in scope
3224static ZigVar *ir_create_var(Stage1AstGen *ag, AstNode *node, Scope *scope, Buf *name,
3225 bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime)
3226{
3227 bool is_underscored = name ? buf_eql_str(name, "_") : false;
3228 ZigVar *var = create_local_var(ag->codegen, node, scope,
3229 (is_underscored ? nullptr : name), src_is_const, gen_is_const,
3230 (is_underscored ? true : is_shadowable), is_comptime, false);
3231 assert(var->child_scope);
3232 return var;
3233}
3234
3235static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) {
3236 ResultLocPeer *result = heap::c_allocator.create<ResultLocPeer>();
3237 result->base.id = ResultLocIdPeer;
3238 result->base.source_instruction = peer_parent->base.source_instruction;
3239 result->parent = peer_parent;
3240 result->base.allow_write_through_const = peer_parent->parent->allow_write_through_const;
3241 return result;
3242}
3243
3244static bool is_duplicate_label(CodeGen *g, Scope *scope, AstNode *node, Buf *name) {
3245 if (name == nullptr) return false;
3246
3247 for (;;) {
3248 if (scope == nullptr || scope->id == ScopeIdFnDef) {
3249 break;
3250 } else if (scope->id == ScopeIdBlock || scope->id == ScopeIdLoop) {
3251 Buf *this_block_name = scope->id == ScopeIdBlock ? ((ScopeBlock *)scope)->name : ((ScopeLoop *)scope)->name;
3252 if (this_block_name != nullptr && buf_eql_buf(name, this_block_name)) {
3253 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("redeclaration of label '%s'", buf_ptr(name)));
3254 add_error_note(g, msg, scope->source_node, buf_sprintf("previous declaration is here"));
3255 return true;
3256 }
3257 }
3258 scope = scope->parent;
3259 }
3260 return false;
3261}
3262
3263static IrInstSrc *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *block_node, LVal lval,
3264 ResultLoc *result_loc)
3265{
3266 assert(block_node->type == NodeTypeBlock);
3267
3268 ZigList<IrInstSrc *> incoming_values = {0};
3269 ZigList<Stage1ZirBasicBlock *> incoming_blocks = {0};
3270
3271 if (is_duplicate_label(ag->codegen, parent_scope, block_node, block_node->data.block.name))
3272 return ag->codegen->invalid_inst_src;
3273
3274 ScopeBlock *scope_block = create_block_scope(ag->codegen, block_node, parent_scope);
3275
3276 Scope *outer_block_scope = &scope_block->base;
3277 Scope *child_scope = outer_block_scope;
3278
3279 ZigFn *fn_entry = scope_fn_entry(parent_scope);
3280 if (fn_entry && fn_entry->child_scope == parent_scope) {
3281 fn_entry->def_scope = scope_block;
3282 }
3283
3284 if (block_node->data.block.statements.length == 0) {
3285 if (scope_block->name != nullptr) {
3286 add_node_error(ag->codegen, block_node, buf_sprintf("unused block label"));
3287 }
3288 // {}
3289 return ir_lval_wrap(ag, parent_scope, ir_build_const_void(ag, child_scope, block_node), lval, result_loc);
3290 }
3291
3292 if (block_node->data.block.name != nullptr) {
3293 scope_block->lval = lval;
3294 scope_block->incoming_blocks = &incoming_blocks;
3295 scope_block->incoming_values = &incoming_values;
3296 scope_block->end_block = ir_create_basic_block(ag, parent_scope, "BlockEnd");
3297 scope_block->is_comptime = ir_build_const_bool(ag, parent_scope, block_node,
3298 ir_should_inline(ag->exec, parent_scope));
3299
3300 scope_block->peer_parent = heap::c_allocator.create<ResultLocPeerParent>();
3301 scope_block->peer_parent->base.id = ResultLocIdPeerParent;
3302 scope_block->peer_parent->base.source_instruction = scope_block->is_comptime;
3303 scope_block->peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const;
3304 scope_block->peer_parent->end_bb = scope_block->end_block;
3305 scope_block->peer_parent->is_comptime = scope_block->is_comptime;
3306 scope_block->peer_parent->parent = result_loc;
3307 ir_build_reset_result(ag, parent_scope, block_node, &scope_block->peer_parent->base);
3308 }
3309
3310 bool is_continuation_unreachable = false;
3311 bool found_invalid_inst = false;
3312 IrInstSrc *noreturn_return_value = nullptr;
3313 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) {
3314 AstNode *statement_node = block_node->data.block.statements.at(i);
3315
3316 IrInstSrc *statement_value = astgen_node(ag, statement_node, child_scope);
3317 if (statement_value == ag->codegen->invalid_inst_src) {
3318 // keep generating all the elements of the block in case of error,
3319 // we want to collect other compile errors
3320 found_invalid_inst = true;
3321 continue;
3322 }
3323
3324 is_continuation_unreachable = instr_is_unreachable(statement_value);
3325 if (is_continuation_unreachable) {
3326 // keep the last noreturn statement value around in case we need to return it
3327 noreturn_return_value = statement_value;
3328 }
3329 // This logic must be kept in sync with
3330 // [STMT_EXPR_TEST_THING] <--- (search this token)
3331 if (statement_node->type == NodeTypeDefer) {
3332 // defer starts a new scope
3333 child_scope = statement_node->data.defer.child_scope;
3334 assert(child_scope);
3335 } else if (statement_value->id == IrInstSrcIdDeclVar) {
3336 // variable declarations start a new scope
3337 IrInstSrcDeclVar *decl_var_instruction = (IrInstSrcDeclVar *)statement_value;
3338 child_scope = decl_var_instruction->var->child_scope;
3339 } else if (!is_continuation_unreachable) {
3340 // this statement's value must be void
3341 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, statement_node, statement_value));
3342 }
3343 }
3344
3345 if (scope_block->name != nullptr && scope_block->name_used == false) {
3346 add_node_error(ag->codegen, block_node, buf_sprintf("unused block label"));
3347 }
3348
3349 if (found_invalid_inst)
3350 return ag->codegen->invalid_inst_src;
3351
3352 if (is_continuation_unreachable) {
3353 assert(noreturn_return_value != nullptr);
3354 if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) {
3355 return noreturn_return_value;
3356 }
3357
3358 if (scope_block->peer_parent != nullptr && scope_block->peer_parent->peers.length != 0) {
3359 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block;
3360 }
3361 ir_set_cursor_at_end_and_append_block(ag, scope_block->end_block);
3362 IrInstSrc *phi = ir_build_phi(ag, parent_scope, block_node, incoming_blocks.length,
3363 incoming_blocks.items, incoming_values.items, scope_block->peer_parent);
3364 return ir_expr_wrap(ag, parent_scope, phi, result_loc);
3365 } else {
3366 incoming_blocks.append(ag->current_basic_block);
3367 IrInstSrc *else_expr_result = ir_mark_gen(ir_build_const_void(ag, parent_scope, block_node));
3368
3369 if (scope_block->peer_parent != nullptr) {
3370 ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent);
3371 scope_block->peer_parent->peers.append(peer_result);
3372 ir_build_end_expr(ag, parent_scope, block_node, else_expr_result, &peer_result->base);
3373
3374 if (scope_block->peer_parent->peers.length != 0) {
3375 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block;
3376 }
3377 }
3378
3379 incoming_values.append(else_expr_result);
3380 }
3381
3382 bool is_return_from_fn = block_node == ag->main_block_node;
3383 if (!is_return_from_fn) {
3384 if (!astgen_defers_for_block(ag, child_scope, outer_block_scope, nullptr, nullptr))
3385 return ag->codegen->invalid_inst_src;
3386 }
3387
3388 IrInstSrc *result;
3389 if (block_node->data.block.name != nullptr) {
3390 ir_mark_gen(ir_build_br(ag, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime));
3391 ir_set_cursor_at_end_and_append_block(ag, scope_block->end_block);
3392 IrInstSrc *phi = ir_build_phi(ag, parent_scope, block_node, incoming_blocks.length,
3393 incoming_blocks.items, incoming_values.items, scope_block->peer_parent);
3394 result = ir_expr_wrap(ag, parent_scope, phi, result_loc);
3395 } else {
3396 IrInstSrc *void_inst = ir_mark_gen(ir_build_const_void(ag, child_scope, block_node));
3397 result = ir_lval_wrap(ag, parent_scope, void_inst, lval, result_loc);
3398 }
3399 if (!is_return_from_fn)
3400 return result;
3401
3402 // no need for save_err_ret_addr because this cannot return error
3403 // only generate unconditional defers
3404
3405 ir_mark_gen(ir_build_add_implicit_return_type(ag, child_scope, block_node, result, nullptr));
3406 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
3407 result_loc_ret->base.id = ResultLocIdReturn;
3408 ir_build_reset_result(ag, parent_scope, block_node, &result_loc_ret->base);
3409 ir_mark_gen(ir_build_end_expr(ag, parent_scope, block_node, result, &result_loc_ret->base));
3410 if (!astgen_defers_for_block(ag, child_scope, outer_block_scope, nullptr, nullptr))
3411 return ag->codegen->invalid_inst_src;
3412 return ir_mark_gen(ir_build_return_src(ag, child_scope, result->base.source_node, result));
3413}
3414
3415static IrInstSrc *astgen_bin_op_id(Stage1AstGen *ag, Scope *scope, AstNode *node, IrBinOp op_id) {
3416 Scope *inner_scope = scope;
3417 if (op_id == IrBinOpArrayCat || op_id == IrBinOpArrayMult) {
3418 inner_scope = create_comptime_scope(ag->codegen, node, scope);
3419 }
3420
3421 IrInstSrc *op1 = astgen_node(ag, node->data.bin_op_expr.op1, inner_scope);
3422 IrInstSrc *op2 = astgen_node(ag, node->data.bin_op_expr.op2, inner_scope);
3423
3424 if (op1 == ag->codegen->invalid_inst_src || op2 == ag->codegen->invalid_inst_src)
3425 return ag->codegen->invalid_inst_src;
3426
3427 return ir_build_bin_op(ag, scope, node, op_id, op1, op2, true);
3428}
3429
3430static IrInstSrc *astgen_merge_err_sets(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3431 IrInstSrc *op1 = astgen_node(ag, node->data.bin_op_expr.op1, scope);
3432 IrInstSrc *op2 = astgen_node(ag, node->data.bin_op_expr.op2, scope);
3433
3434 if (op1 == ag->codegen->invalid_inst_src || op2 == ag->codegen->invalid_inst_src)
3435 return ag->codegen->invalid_inst_src;
3436
3437 // TODO only pass type_name when the || operator is the top level AST node in the var decl expr
3438 Buf bare_name = BUF_INIT;
3439 Buf *type_name = get_anon_type_name(ag->codegen, ag->exec, "error", scope, node, &bare_name);
3440
3441 return ir_build_merge_err_sets(ag, scope, node, op1, op2, type_name);
3442}
3443
3444static IrInstSrc *astgen_assign(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3445 IrInstSrc *lvalue = astgen_node_extra(ag, node->data.bin_op_expr.op1, scope, LValAssign, nullptr);
3446 if (lvalue == ag->codegen->invalid_inst_src)
3447 return ag->codegen->invalid_inst_src;
3448
3449 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
3450 result_loc_inst->base.id = ResultLocIdInstruction;
3451 result_loc_inst->base.source_instruction = lvalue;
3452 ir_ref_instruction(lvalue, ag->current_basic_block);
3453 ir_build_reset_result(ag, scope, node, &result_loc_inst->base);
3454
3455 IrInstSrc *rvalue = astgen_node_extra(ag, node->data.bin_op_expr.op2, scope, LValNone,
3456 &result_loc_inst->base);
3457 if (rvalue == ag->codegen->invalid_inst_src)
3458 return ag->codegen->invalid_inst_src;
3459
3460 return ir_build_const_void(ag, scope, node);
3461}
3462
3463static IrInstSrc *astgen_assign_op(Stage1AstGen *ag, Scope *scope, AstNode *node, IrBinOp op_id) {
3464 IrInstSrc *lvalue = astgen_node_extra(ag, node->data.bin_op_expr.op1, scope, LValAssign, nullptr);
3465 if (lvalue == ag->codegen->invalid_inst_src)
3466 return lvalue;
3467 IrInstSrc *op1 = ir_build_load_ptr(ag, scope, node->data.bin_op_expr.op1, lvalue);
3468 IrInstSrc *op2 = astgen_node(ag, node->data.bin_op_expr.op2, scope);
3469 if (op2 == ag->codegen->invalid_inst_src)
3470 return op2;
3471 IrInstSrc *result = ir_build_bin_op(ag, scope, node, op_id, op1, op2, true);
3472 ir_build_store_ptr(ag, scope, node, lvalue, result);
3473 return ir_build_const_void(ag, scope, node);
3474}
3475
3476static IrInstSrc *astgen_bool_or(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3477 assert(node->type == NodeTypeBinOpExpr);
3478
3479 IrInstSrc *val1 = astgen_node(ag, node->data.bin_op_expr.op1, scope);
3480 if (val1 == ag->codegen->invalid_inst_src)
3481 return ag->codegen->invalid_inst_src;
3482 Stage1ZirBasicBlock *post_val1_block = ag->current_basic_block;
3483
3484 IrInstSrc *is_comptime;
3485 if (ir_should_inline(ag->exec, scope)) {
3486 is_comptime = ir_build_const_bool(ag, scope, node, true);
3487 } else {
3488 is_comptime = ir_build_test_comptime(ag, scope, node, val1);
3489 }
3490
3491 // block for when val1 == false
3492 Stage1ZirBasicBlock *false_block = ir_create_basic_block(ag, scope, "BoolOrFalse");
3493 // block for when val1 == true (don't even evaluate the second part)
3494 Stage1ZirBasicBlock *true_block = ir_create_basic_block(ag, scope, "BoolOrTrue");
3495
3496 ir_build_cond_br(ag, scope, node, val1, true_block, false_block, is_comptime);
3497
3498 ir_set_cursor_at_end_and_append_block(ag, false_block);
3499 IrInstSrc *val2 = astgen_node(ag, node->data.bin_op_expr.op2, scope);
3500 if (val2 == ag->codegen->invalid_inst_src)
3501 return ag->codegen->invalid_inst_src;
3502 Stage1ZirBasicBlock *post_val2_block = ag->current_basic_block;
3503
3504 ir_build_br(ag, scope, node, true_block, is_comptime);
3505
3506 ir_set_cursor_at_end_and_append_block(ag, true_block);
3507
3508 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
3509 incoming_values[0] = val1;
3510 incoming_values[1] = val2;
3511 Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
3512 incoming_blocks[0] = post_val1_block;
3513 incoming_blocks[1] = post_val2_block;
3514
3515 return ir_build_phi(ag, scope, node, 2, incoming_blocks, incoming_values, nullptr);
3516}
3517
3518static IrInstSrc *astgen_bool_and(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3519 assert(node->type == NodeTypeBinOpExpr);
3520
3521 IrInstSrc *val1 = astgen_node(ag, node->data.bin_op_expr.op1, scope);
3522 if (val1 == ag->codegen->invalid_inst_src)
3523 return ag->codegen->invalid_inst_src;
3524 Stage1ZirBasicBlock *post_val1_block = ag->current_basic_block;
3525
3526 IrInstSrc *is_comptime;
3527 if (ir_should_inline(ag->exec, scope)) {
3528 is_comptime = ir_build_const_bool(ag, scope, node, true);
3529 } else {
3530 is_comptime = ir_build_test_comptime(ag, scope, node, val1);
3531 }
3532
3533 // block for when val1 == true
3534 Stage1ZirBasicBlock *true_block = ir_create_basic_block(ag, scope, "BoolAndTrue");
3535 // block for when val1 == false (don't even evaluate the second part)
3536 Stage1ZirBasicBlock *false_block = ir_create_basic_block(ag, scope, "BoolAndFalse");
3537
3538 ir_build_cond_br(ag, scope, node, val1, true_block, false_block, is_comptime);
3539
3540 ir_set_cursor_at_end_and_append_block(ag, true_block);
3541 IrInstSrc *val2 = astgen_node(ag, node->data.bin_op_expr.op2, scope);
3542 if (val2 == ag->codegen->invalid_inst_src)
3543 return ag->codegen->invalid_inst_src;
3544 Stage1ZirBasicBlock *post_val2_block = ag->current_basic_block;
3545
3546 ir_build_br(ag, scope, node, false_block, is_comptime);
3547
3548 ir_set_cursor_at_end_and_append_block(ag, false_block);
3549
3550 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
3551 incoming_values[0] = val1;
3552 incoming_values[1] = val2;
3553 Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
3554 incoming_blocks[0] = post_val1_block;
3555 incoming_blocks[1] = post_val2_block;
3556
3557 return ir_build_phi(ag, scope, node, 2, incoming_blocks, incoming_values, nullptr);
3558}
3559
3560static ResultLocPeerParent *ir_build_result_peers(Stage1AstGen *ag, IrInstSrc *cond_br_inst,
3561 Stage1ZirBasicBlock *end_block, ResultLoc *parent, IrInstSrc *is_comptime)
3562{
3563 ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>();
3564 peer_parent->base.id = ResultLocIdPeerParent;
3565 peer_parent->base.source_instruction = cond_br_inst;
3566 peer_parent->base.allow_write_through_const = parent->allow_write_through_const;
3567 peer_parent->end_bb = end_block;
3568 peer_parent->is_comptime = is_comptime;
3569 peer_parent->parent = parent;
3570
3571 IrInstSrc *popped_inst = ag->current_basic_block->instruction_list.pop();
3572 ir_assert(popped_inst == cond_br_inst, &cond_br_inst->base);
3573
3574 ir_build_reset_result(ag, cond_br_inst->base.scope, cond_br_inst->base.source_node, &peer_parent->base);
3575 ag->current_basic_block->instruction_list.append(popped_inst);
3576
3577 return peer_parent;
3578}
3579
3580static ResultLocPeerParent *ir_build_binary_result_peers(Stage1AstGen *ag, IrInstSrc *cond_br_inst,
3581 Stage1ZirBasicBlock *else_block, Stage1ZirBasicBlock *end_block, ResultLoc *parent, IrInstSrc *is_comptime)
3582{
3583 ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, parent, is_comptime);
3584
3585 peer_parent->peers.append(create_peer_result(peer_parent));
3586 peer_parent->peers.last()->next_bb = else_block;
3587
3588 peer_parent->peers.append(create_peer_result(peer_parent));
3589 peer_parent->peers.last()->next_bb = end_block;
3590
3591 return peer_parent;
3592}
3593
3594static IrInstSrc *astgen_orelse(Stage1AstGen *ag, Scope *parent_scope, AstNode *node, LVal lval,
3595 ResultLoc *result_loc)
3596{
3597 assert(node->type == NodeTypeBinOpExpr);
3598
3599 AstNode *op1_node = node->data.bin_op_expr.op1;
3600 AstNode *op2_node = node->data.bin_op_expr.op2;
3601
3602 IrInstSrc *maybe_ptr = astgen_node_extra(ag, op1_node, parent_scope, LValPtr, nullptr);
3603 if (maybe_ptr == ag->codegen->invalid_inst_src)
3604 return ag->codegen->invalid_inst_src;
3605
3606 IrInstSrc *maybe_val = ir_build_load_ptr(ag, parent_scope, node, maybe_ptr);
3607 IrInstSrc *is_non_null = ir_build_test_non_null_src(ag, parent_scope, node, maybe_val);
3608
3609 IrInstSrc *is_comptime;
3610 if (ir_should_inline(ag->exec, parent_scope)) {
3611 is_comptime = ir_build_const_bool(ag, parent_scope, node, true);
3612 } else {
3613 is_comptime = ir_build_test_comptime(ag, parent_scope, node, is_non_null);
3614 }
3615
3616 Stage1ZirBasicBlock *ok_block = ir_create_basic_block(ag, parent_scope, "OptionalNonNull");
3617 Stage1ZirBasicBlock *null_block = ir_create_basic_block(ag, parent_scope, "OptionalNull");
3618 Stage1ZirBasicBlock *end_block = ir_create_basic_block(ag, parent_scope, "OptionalEnd");
3619 IrInstSrc *cond_br_inst = ir_build_cond_br(ag, parent_scope, node, is_non_null, ok_block, null_block, is_comptime);
3620
3621 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(ag, cond_br_inst, ok_block, end_block,
3622 result_loc, is_comptime);
3623
3624 ir_set_cursor_at_end_and_append_block(ag, null_block);
3625 IrInstSrc *null_result = astgen_node_extra(ag, op2_node, parent_scope, LValNone,
3626 &peer_parent->peers.at(0)->base);
3627 if (null_result == ag->codegen->invalid_inst_src)
3628 return ag->codegen->invalid_inst_src;
3629 Stage1ZirBasicBlock *after_null_block = ag->current_basic_block;
3630 if (!instr_is_unreachable(null_result))
3631 ir_mark_gen(ir_build_br(ag, parent_scope, node, end_block, is_comptime));
3632
3633 ir_set_cursor_at_end_and_append_block(ag, ok_block);
3634 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(ag, parent_scope, node, maybe_ptr, false);
3635 IrInstSrc *unwrapped_payload = ir_build_load_ptr(ag, parent_scope, node, unwrapped_ptr);
3636 ir_build_end_expr(ag, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base);
3637 Stage1ZirBasicBlock *after_ok_block = ag->current_basic_block;
3638 ir_build_br(ag, parent_scope, node, end_block, is_comptime);
3639
3640 ir_set_cursor_at_end_and_append_block(ag, end_block);
3641 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
3642 incoming_values[0] = null_result;
3643 incoming_values[1] = unwrapped_payload;
3644 Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
3645 incoming_blocks[0] = after_null_block;
3646 incoming_blocks[1] = after_ok_block;
3647 IrInstSrc *phi = ir_build_phi(ag, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent);
3648 return ir_lval_wrap(ag, parent_scope, phi, lval, result_loc);
3649}
3650
3651static IrInstSrc *astgen_error_union(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) {
3652 assert(node->type == NodeTypeBinOpExpr);
3653
3654 AstNode *op1_node = node->data.bin_op_expr.op1;
3655 AstNode *op2_node = node->data.bin_op_expr.op2;
3656
3657 IrInstSrc *err_set = astgen_node(ag, op1_node, parent_scope);
3658 if (err_set == ag->codegen->invalid_inst_src)
3659 return ag->codegen->invalid_inst_src;
3660
3661 IrInstSrc *payload = astgen_node(ag, op2_node, parent_scope);
3662 if (payload == ag->codegen->invalid_inst_src)
3663 return ag->codegen->invalid_inst_src;
3664
3665 return ir_build_error_union(ag, parent_scope, node, err_set, payload);
3666}
3667
3668static IrInstSrc *astgen_bin_op(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
3669 assert(node->type == NodeTypeBinOpExpr);
3670
3671 BinOpType bin_op_type = node->data.bin_op_expr.bin_op;
3672 switch (bin_op_type) {
3673 case BinOpTypeInvalid:
3674 zig_unreachable();
3675 case BinOpTypeAssign:
3676 return ir_lval_wrap(ag, scope, astgen_assign(ag, scope, node), lval, result_loc);
3677 case BinOpTypeAssignTimes:
3678 return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpMult), lval, result_loc);
3679 case BinOpTypeAssignTimesWrap:
3680 return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpMultWrap), lval, result_loc);
3681 case BinOpTypeAssignDiv:
3682 return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpDivUnspecified), lval, result_loc);
3683 case BinOpTypeAssignMod:
3684 return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpRemUnspecified), lval, result_loc);
3685 case BinOpTypeAssignPlus:
3686 return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpAdd), lval, result_loc);
3687 case BinOpTypeAssignPlusWrap:
3688 return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpAddWrap), lval, result_loc);
3689 case BinOpTypeAssignMinus:
3690 return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpSub), lval, result_loc);
3691 case BinOpTypeAssignMinusWrap:
3692 return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpSubWrap), lval, result_loc);
3693 case BinOpTypeAssignBitShiftLeft:
3694 return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc);
3695 case BinOpTypeAssignBitShiftRight:
3696 return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc);
3697 case BinOpTypeAssignBitAnd:
3698 return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpBinAnd), lval, result_loc);
3699 case BinOpTypeAssignBitXor:
3700 return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpBinXor), lval, result_loc);
3701 case BinOpTypeAssignBitOr:
3702 return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpBinOr), lval, result_loc);
3703 case BinOpTypeBoolOr:
3704 return ir_lval_wrap(ag, scope, astgen_bool_or(ag, scope, node), lval, result_loc);
3705 case BinOpTypeBoolAnd:
3706 return ir_lval_wrap(ag, scope, astgen_bool_and(ag, scope, node), lval, result_loc);
3707 case BinOpTypeCmpEq:
3708 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpCmpEq), lval, result_loc);
3709 case BinOpTypeCmpNotEq:
3710 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpCmpNotEq), lval, result_loc);
3711 case BinOpTypeCmpLessThan:
3712 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpCmpLessThan), lval, result_loc);
3713 case BinOpTypeCmpGreaterThan:
3714 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpCmpGreaterThan), lval, result_loc);
3715 case BinOpTypeCmpLessOrEq:
3716 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpCmpLessOrEq), lval, result_loc);
3717 case BinOpTypeCmpGreaterOrEq:
3718 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc);
3719 case BinOpTypeBinOr:
3720 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpBinOr), lval, result_loc);
3721 case BinOpTypeBinXor:
3722 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpBinXor), lval, result_loc);
3723 case BinOpTypeBinAnd:
3724 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpBinAnd), lval, result_loc);
3725 case BinOpTypeBitShiftLeft:
3726 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc);
3727 case BinOpTypeBitShiftRight:
3728 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc);
3729 case BinOpTypeAdd:
3730 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpAdd), lval, result_loc);
3731 case BinOpTypeAddWrap:
3732 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpAddWrap), lval, result_loc);
3733 case BinOpTypeSub:
3734 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpSub), lval, result_loc);
3735 case BinOpTypeSubWrap:
3736 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpSubWrap), lval, result_loc);
3737 case BinOpTypeMult:
3738 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpMult), lval, result_loc);
3739 case BinOpTypeMultWrap:
3740 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpMultWrap), lval, result_loc);
3741 case BinOpTypeDiv:
3742 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpDivUnspecified), lval, result_loc);
3743 case BinOpTypeMod:
3744 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpRemUnspecified), lval, result_loc);
3745 case BinOpTypeArrayCat:
3746 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpArrayCat), lval, result_loc);
3747 case BinOpTypeArrayMult:
3748 return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpArrayMult), lval, result_loc);
3749 case BinOpTypeMergeErrorSets:
3750 return ir_lval_wrap(ag, scope, astgen_merge_err_sets(ag, scope, node), lval, result_loc);
3751 case BinOpTypeUnwrapOptional:
3752 return astgen_orelse(ag, scope, node, lval, result_loc);
3753 case BinOpTypeErrorUnion:
3754 return ir_lval_wrap(ag, scope, astgen_error_union(ag, scope, node), lval, result_loc);
3755 }
3756 zig_unreachable();
3757}
3758
3759static IrInstSrc *astgen_int_lit(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3760 assert(node->type == NodeTypeIntLiteral);
3761
3762 RootStruct *root_struct = node->owner->data.structure.root_struct;
3763 BigInt bigint;
3764 token_number_literal_bigint(root_struct, &bigint, node->main_token);
3765 return ir_build_const_bigint(ag, scope, node, bigint);
3766}
3767
3768static IrInstSrc *astgen_float_lit(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3769 Error err;
3770 assert(node->type == NodeTypeFloatLiteral);
3771
3772 RootStruct *root_struct = node->owner->data.structure.root_struct;
3773 const char *source = buf_ptr(root_struct->source_code);
3774 uint32_t byte_offset = root_struct->token_locs[node->main_token].offset;
3775
3776 BigFloat bigfloat;
3777 if ((err = bigfloat_init_buf(&bigfloat, (const uint8_t *)source + byte_offset))) {
3778 add_node_error(ag->codegen, node, buf_sprintf("float literal out of range of any type"));
3779 return ag->codegen->invalid_inst_src;
3780 }
3781
3782 return ir_build_const_bigfloat(ag, scope, node, bigfloat);
3783}
3784
3785static IrInstSrc *astgen_char_lit(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3786 Error err;
3787 assert(node->type == NodeTypeCharLiteral);
3788
3789 RootStruct *root_struct = node->owner->data.structure.root_struct;
3790 const char *source = buf_ptr(root_struct->source_code);
3791 uint32_t byte_offset = root_struct->token_locs[node->main_token].offset;
3792
3793 src_assert(source[byte_offset] == '\'', node);
3794 byte_offset += 1;
3795
3796 uint32_t codepoint;
3797 size_t bad_index;
3798 if ((err = source_char_literal(source + byte_offset, &codepoint, &bad_index))) {
3799 add_node_error(ag->codegen, node, buf_sprintf("invalid character"));
3800 return ag->codegen->invalid_inst_src;
3801 }
3802 return ir_build_const_uint(ag, scope, node, codepoint);
3803}
3804
3805static IrInstSrc *astgen_null_literal(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3806 assert(node->type == NodeTypeNullLiteral);
3807
3808 return ir_build_const_null(ag, scope, node);
3809}
3810
3811static IrInstSrc *astgen_identifier(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
3812 ResultLoc *result_loc)
3813{
3814 Error err;
3815 assert(node->type == NodeTypeIdentifier);
3816
3817 Buf *variable_name = node_identifier_buf(node);
3818
3819 if (buf_eql_str(variable_name, "_")) {
3820 if (lval == LValAssign) {
3821 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(ag, scope, node);
3822 const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
3823 const_instruction->value->type = get_pointer_to_type(ag->codegen,
3824 ag->codegen->builtin_types.entry_void, false);
3825 const_instruction->value->special = ConstValSpecialStatic;
3826 const_instruction->value->data.x_ptr.special = ConstPtrSpecialDiscard;
3827 return &const_instruction->base;
3828 } else {
3829 add_node_error(ag->codegen, node, buf_sprintf("`_` may only be used to assign things to"));
3830 return ag->codegen->invalid_inst_src;
3831 }
3832 }
3833
3834 ZigType *primitive_type;
3835 if ((err = get_primitive_type(ag->codegen, variable_name, &primitive_type))) {
3836 if (err == ErrorOverflow) {
3837 add_node_error(ag->codegen, node,
3838 buf_sprintf("primitive integer type '%s' exceeds maximum bit width of 65535",
3839 buf_ptr(variable_name)));
3840 return ag->codegen->invalid_inst_src;
3841 }
3842 assert(err == ErrorPrimitiveTypeNotFound);
3843 } else {
3844 IrInstSrc *value = ir_build_const_type(ag, scope, node, primitive_type);
3845 if (lval == LValPtr || lval == LValAssign) {
3846 return ir_build_ref_src(ag, scope, node, value);
3847 } else {
3848 return ir_expr_wrap(ag, scope, value, result_loc);
3849 }
3850 }
3851
3852 ScopeFnDef *crossed_fndef_scope;
3853 ZigVar *var = find_variable(ag->codegen, scope, variable_name, &crossed_fndef_scope);
3854 if (var) {
3855 IrInstSrc *var_ptr = ir_build_var_ptr_x(ag, scope, node, var, crossed_fndef_scope);
3856 if (lval == LValPtr || lval == LValAssign) {
3857 return var_ptr;
3858 } else {
3859 return ir_expr_wrap(ag, scope, ir_build_load_ptr(ag, scope, node, var_ptr), result_loc);
3860 }
3861 }
3862
3863 Tld *tld = find_decl(ag->codegen, scope, variable_name);
3864 if (tld) {
3865 IrInstSrc *decl_ref = ir_build_decl_ref(ag, scope, node, tld, lval);
3866 if (lval == LValPtr || lval == LValAssign) {
3867 return decl_ref;
3868 } else {
3869 return ir_expr_wrap(ag, scope, decl_ref, result_loc);
3870 }
3871 }
3872
3873 if (get_container_scope(node->owner)->any_imports_failed) {
3874 // skip the error message since we had a failing import in this file
3875 // if an import breaks we don't need redundant undeclared identifier errors
3876 return ag->codegen->invalid_inst_src;
3877 }
3878
3879 return ir_build_undeclared_identifier(ag, scope, node, variable_name);
3880}
3881
3882static IrInstSrc *astgen_array_access(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
3883 ResultLoc *result_loc)
3884{
3885 assert(node->type == NodeTypeArrayAccessExpr);
3886
3887 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;
3888 IrInstSrc *array_ref_instruction = astgen_node_extra(ag, array_ref_node, scope, LValPtr, nullptr);
3889 if (array_ref_instruction == ag->codegen->invalid_inst_src)
3890 return array_ref_instruction;
3891
3892 // Create an usize-typed result location to hold the subscript value, this
3893 // makes it possible for the compiler to infer the subscript expression type
3894 // if needed
3895 IrInstSrc *usize_type_inst = ir_build_const_type(ag, scope, node, ag->codegen->builtin_types.entry_usize);
3896 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(ag, usize_type_inst, no_result_loc());
3897
3898 AstNode *subscript_node = node->data.array_access_expr.subscript;
3899 IrInstSrc *subscript_value = astgen_node_extra(ag, subscript_node, scope, LValNone, &result_loc_cast->base);
3900 if (subscript_value == ag->codegen->invalid_inst_src)
3901 return ag->codegen->invalid_inst_src;
3902
3903 IrInstSrc *subscript_instruction = ir_build_implicit_cast(ag, scope, subscript_node, subscript_value, result_loc_cast);
3904
3905 IrInstSrc *ptr_instruction = ir_build_elem_ptr(ag, scope, node, array_ref_instruction,
3906 subscript_instruction, true, PtrLenSingle, nullptr);
3907 if (lval == LValPtr || lval == LValAssign)
3908 return ptr_instruction;
3909
3910 IrInstSrc *load_ptr = ir_build_load_ptr(ag, scope, node, ptr_instruction);
3911 return ir_expr_wrap(ag, scope, load_ptr, result_loc);
3912}
3913
3914static IrInstSrc *astgen_field_access(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3915 assert(node->type == NodeTypeFieldAccessExpr);
3916
3917 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
3918 Buf *field_name = node->data.field_access_expr.field_name;
3919
3920 IrInstSrc *container_ref_instruction = astgen_node_extra(ag, container_ref_node, scope, LValPtr, nullptr);
3921 if (container_ref_instruction == ag->codegen->invalid_inst_src)
3922 return container_ref_instruction;
3923
3924 return ir_build_field_ptr(ag, scope, node, container_ref_instruction, field_name, false);
3925}
3926
3927static IrInstSrc *astgen_overflow_op(Stage1AstGen *ag, Scope *scope, AstNode *node, IrOverflowOp op) {
3928 assert(node->type == NodeTypeFnCallExpr);
3929
3930 AstNode *type_node = node->data.fn_call_expr.params.at(0);
3931 AstNode *op1_node = node->data.fn_call_expr.params.at(1);
3932 AstNode *op2_node = node->data.fn_call_expr.params.at(2);
3933 AstNode *result_ptr_node = node->data.fn_call_expr.params.at(3);
3934
3935
3936 IrInstSrc *type_value = astgen_node(ag, type_node, scope);
3937 if (type_value == ag->codegen->invalid_inst_src)
3938 return ag->codegen->invalid_inst_src;
3939
3940 IrInstSrc *op1 = astgen_node(ag, op1_node, scope);
3941 if (op1 == ag->codegen->invalid_inst_src)
3942 return ag->codegen->invalid_inst_src;
3943
3944 IrInstSrc *op2 = astgen_node(ag, op2_node, scope);
3945 if (op2 == ag->codegen->invalid_inst_src)
3946 return ag->codegen->invalid_inst_src;
3947
3948 IrInstSrc *result_ptr = astgen_node(ag, result_ptr_node, scope);
3949 if (result_ptr == ag->codegen->invalid_inst_src)
3950 return ag->codegen->invalid_inst_src;
3951
3952 return ir_build_overflow_op_src(ag, scope, node, op, type_value, op1, op2, result_ptr);
3953}
3954
3955static IrInstSrc *astgen_mul_add(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3956 assert(node->type == NodeTypeFnCallExpr);
3957
3958 AstNode *type_node = node->data.fn_call_expr.params.at(0);
3959 AstNode *op1_node = node->data.fn_call_expr.params.at(1);
3960 AstNode *op2_node = node->data.fn_call_expr.params.at(2);
3961 AstNode *op3_node = node->data.fn_call_expr.params.at(3);
3962
3963 IrInstSrc *type_value = astgen_node(ag, type_node, scope);
3964 if (type_value == ag->codegen->invalid_inst_src)
3965 return ag->codegen->invalid_inst_src;
3966
3967 IrInstSrc *op1 = astgen_node(ag, op1_node, scope);
3968 if (op1 == ag->codegen->invalid_inst_src)
3969 return ag->codegen->invalid_inst_src;
3970
3971 IrInstSrc *op2 = astgen_node(ag, op2_node, scope);
3972 if (op2 == ag->codegen->invalid_inst_src)
3973 return ag->codegen->invalid_inst_src;
3974
3975 IrInstSrc *op3 = astgen_node(ag, op3_node, scope);
3976 if (op3 == ag->codegen->invalid_inst_src)
3977 return ag->codegen->invalid_inst_src;
3978
3979 return ir_build_mul_add_src(ag, scope, node, type_value, op1, op2, op3);
3980}
3981
3982static IrInstSrc *astgen_this(Stage1AstGen *ag, Scope *orig_scope, AstNode *node) {
3983 for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) {
3984 if (it_scope->id == ScopeIdDecls) {
3985 ScopeDecls *decls_scope = (ScopeDecls *)it_scope;
3986 ZigType *container_type = decls_scope->container_type;
3987 if (container_type != nullptr) {
3988 return ir_build_const_type(ag, orig_scope, node, container_type);
3989 } else {
3990 return ir_build_const_import(ag, orig_scope, node, decls_scope->import);
3991 }
3992 }
3993 }
3994 zig_unreachable();
3995}
3996
3997static IrInstSrc *astgen_async_call(Stage1AstGen *ag, Scope *scope, AstNode *await_node, AstNode *call_node,
3998 LVal lval, ResultLoc *result_loc)
3999{
4000 if (call_node->data.fn_call_expr.params.length != 4) {
4001 add_node_error(ag->codegen, call_node,
4002 buf_sprintf("expected 4 arguments, found %" ZIG_PRI_usize,
4003 call_node->data.fn_call_expr.params.length));
4004 return ag->codegen->invalid_inst_src;
4005 }
4006
4007 AstNode *bytes_node = call_node->data.fn_call_expr.params.at(0);
4008 IrInstSrc *bytes = astgen_node(ag, bytes_node, scope);
4009 if (bytes == ag->codegen->invalid_inst_src)
4010 return bytes;
4011
4012 AstNode *ret_ptr_node = call_node->data.fn_call_expr.params.at(1);
4013 IrInstSrc *ret_ptr = astgen_node(ag, ret_ptr_node, scope);
4014 if (ret_ptr == ag->codegen->invalid_inst_src)
4015 return ret_ptr;
4016
4017 AstNode *fn_ref_node = call_node->data.fn_call_expr.params.at(2);
4018 IrInstSrc *fn_ref = astgen_node(ag, fn_ref_node, scope);
4019 if (fn_ref == ag->codegen->invalid_inst_src)
4020 return fn_ref;
4021
4022 CallModifier modifier = (await_node == nullptr) ? CallModifierAsync : CallModifierNone;
4023 bool is_async_call_builtin = true;
4024 AstNode *args_node = call_node->data.fn_call_expr.params.at(3);
4025 if (args_node->type == NodeTypeContainerInitExpr) {
4026 if (args_node->data.container_init_expr.kind == ContainerInitKindArray ||
4027 args_node->data.container_init_expr.entries.length == 0)
4028 {
4029 size_t arg_count = args_node->data.container_init_expr.entries.length;
4030 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count);
4031 for (size_t i = 0; i < arg_count; i += 1) {
4032 AstNode *arg_node = args_node->data.container_init_expr.entries.at(i);
4033 IrInstSrc *arg = astgen_node(ag, arg_node, scope);
4034 if (arg == ag->codegen->invalid_inst_src)
4035 return arg;
4036 args[i] = arg;
4037 }
4038
4039 IrInstSrc *call = ir_build_call_src(ag, scope, call_node, nullptr, fn_ref, arg_count, args,
4040 ret_ptr, modifier, is_async_call_builtin, bytes, result_loc);
4041 return ir_lval_wrap(ag, scope, call, lval, result_loc);
4042 } else {
4043 exec_add_error_node(ag->codegen, ag->exec, args_node,
4044 buf_sprintf("TODO: @asyncCall with anon struct literal"));
4045 return ag->codegen->invalid_inst_src;
4046 }
4047 }
4048 IrInstSrc *args = astgen_node(ag, args_node, scope);
4049 if (args == ag->codegen->invalid_inst_src)
4050 return args;
4051
4052 IrInstSrc *call = ir_build_async_call_extra(ag, scope, call_node, modifier, fn_ref, ret_ptr, bytes, args, result_loc);
4053 return ir_lval_wrap(ag, scope, call, lval, result_loc);
4054}
4055
4056static IrInstSrc *astgen_fn_call_with_args(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
4057 AstNode *fn_ref_node, CallModifier modifier, IrInstSrc *options,
4058 AstNode **args_ptr, size_t args_len, LVal lval, ResultLoc *result_loc)
4059{
4060 IrInstSrc *fn_ref = astgen_node(ag, fn_ref_node, scope);
4061 if (fn_ref == ag->codegen->invalid_inst_src)
4062 return fn_ref;
4063
4064 IrInstSrc *fn_type = ir_build_typeof_1(ag, scope, source_node, fn_ref);
4065
4066 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len);
4067 for (size_t i = 0; i < args_len; i += 1) {
4068 AstNode *arg_node = args_ptr[i];
4069
4070 IrInstSrc *arg_index = ir_build_const_usize(ag, scope, arg_node, i);
4071 IrInstSrc *arg_type = ir_build_arg_type(ag, scope, source_node, fn_type, arg_index, true);
4072 ResultLoc *no_result = no_result_loc();
4073 ir_build_reset_result(ag, scope, source_node, no_result);
4074 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(ag, arg_type, no_result);
4075
4076 IrInstSrc *arg = astgen_node_extra(ag, arg_node, scope, LValNone, &result_loc_cast->base);
4077 if (arg == ag->codegen->invalid_inst_src)
4078 return arg;
4079
4080 args[i] = ir_build_implicit_cast(ag, scope, arg_node, arg, result_loc_cast);
4081 }
4082
4083 IrInstSrc *fn_call;
4084 if (options != nullptr) {
4085 fn_call = ir_build_call_args(ag, scope, source_node, options, fn_ref, args, args_len, result_loc);
4086 } else {
4087 fn_call = ir_build_call_src(ag, scope, source_node, nullptr, fn_ref, args_len, args, nullptr,
4088 modifier, false, nullptr, result_loc);
4089 }
4090 return ir_lval_wrap(ag, scope, fn_call, lval, result_loc);
4091}
4092
4093static IrInstSrc *astgen_builtin_fn_call(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
4094 ResultLoc *result_loc)
4095{
4096 assert(node->type == NodeTypeFnCallExpr);
4097
4098 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
4099 Buf *name = node_identifier_buf(fn_ref_expr);
4100 auto entry = ag->codegen->builtin_fn_table.maybe_get(name);
4101
4102 if (!entry) {
4103 add_node_error(ag->codegen, node,
4104 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name)));
4105 return ag->codegen->invalid_inst_src;
4106 }
4107
4108 BuiltinFnEntry *builtin_fn = entry->value;
4109 size_t actual_param_count = node->data.fn_call_expr.params.length;
4110
4111 if (builtin_fn->param_count != SIZE_MAX && builtin_fn->param_count != actual_param_count) {
4112 add_node_error(ag->codegen, node,
4113 buf_sprintf("expected %" ZIG_PRI_usize " argument(s), found %" ZIG_PRI_usize,
4114 builtin_fn->param_count, actual_param_count));
4115 return ag->codegen->invalid_inst_src;
4116 }
4117
4118 switch (builtin_fn->id) {
4119 case BuiltinFnIdInvalid:
4120 zig_unreachable();
4121 case BuiltinFnIdTypeof:
4122 {
4123 Scope *sub_scope = create_typeof_scope(ag->codegen, node, scope);
4124
4125 size_t arg_count = node->data.fn_call_expr.params.length;
4126
4127 IrInstSrc *type_of;
4128
4129 if (arg_count == 0) {
4130 add_node_error(ag->codegen, node,
4131 buf_sprintf("expected at least 1 argument, found 0"));
4132 return ag->codegen->invalid_inst_src;
4133 } else if (arg_count == 1) {
4134 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4135 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, sub_scope);
4136 if (arg0_value == ag->codegen->invalid_inst_src)
4137 return arg0_value;
4138
4139 type_of = ir_build_typeof_1(ag, scope, node, arg0_value);
4140 } else {
4141 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count);
4142 for (size_t i = 0; i < arg_count; i += 1) {
4143 AstNode *arg_node = node->data.fn_call_expr.params.at(i);
4144 IrInstSrc *arg = astgen_node(ag, arg_node, sub_scope);
4145 if (arg == ag->codegen->invalid_inst_src)
4146 return ag->codegen->invalid_inst_src;
4147 args[i] = arg;
4148 }
4149
4150 type_of = ir_build_typeof_n(ag, scope, node, args, arg_count);
4151 }
4152 return ir_lval_wrap(ag, scope, type_of, lval, result_loc);
4153 }
4154 case BuiltinFnIdSetCold:
4155 {
4156 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4157 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4158 if (arg0_value == ag->codegen->invalid_inst_src)
4159 return arg0_value;
4160
4161 IrInstSrc *set_cold = ir_build_set_cold(ag, scope, node, arg0_value);
4162 return ir_lval_wrap(ag, scope, set_cold, lval, result_loc);
4163 }
4164 case BuiltinFnIdSetRuntimeSafety:
4165 {
4166 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4167 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4168 if (arg0_value == ag->codegen->invalid_inst_src)
4169 return arg0_value;
4170
4171 IrInstSrc *set_safety = ir_build_set_runtime_safety(ag, scope, node, arg0_value);
4172 return ir_lval_wrap(ag, scope, set_safety, lval, result_loc);
4173 }
4174 case BuiltinFnIdSetFloatMode:
4175 {
4176 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4177 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4178 if (arg0_value == ag->codegen->invalid_inst_src)
4179 return arg0_value;
4180
4181 IrInstSrc *set_float_mode = ir_build_set_float_mode(ag, scope, node, arg0_value);
4182 return ir_lval_wrap(ag, scope, set_float_mode, lval, result_loc);
4183 }
4184 case BuiltinFnIdSizeof:
4185 case BuiltinFnIdBitSizeof:
4186 {
4187 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4188 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4189 if (arg0_value == ag->codegen->invalid_inst_src)
4190 return arg0_value;
4191
4192 IrInstSrc *size_of = ir_build_size_of(ag, scope, node, arg0_value, builtin_fn->id == BuiltinFnIdBitSizeof);
4193 return ir_lval_wrap(ag, scope, size_of, lval, result_loc);
4194 }
4195 case BuiltinFnIdImport:
4196 {
4197 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4198 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4199 if (arg0_value == ag->codegen->invalid_inst_src)
4200 return arg0_value;
4201
4202 IrInstSrc *import = ir_build_import(ag, scope, node, arg0_value);
4203 return ir_lval_wrap(ag, scope, import, lval, result_loc);
4204 }
4205 case BuiltinFnIdCImport:
4206 {
4207 IrInstSrc *c_import = ir_build_c_import(ag, scope, node);
4208 return ir_lval_wrap(ag, scope, c_import, lval, result_loc);
4209 }
4210 case BuiltinFnIdCInclude:
4211 {
4212 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4213 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4214 if (arg0_value == ag->codegen->invalid_inst_src)
4215 return arg0_value;
4216
4217 if (!ag->in_c_import_scope) {
4218 add_node_error(ag->codegen, node, buf_sprintf("C include valid only inside C import block"));
4219 return ag->codegen->invalid_inst_src;
4220 }
4221
4222 IrInstSrc *c_include = ir_build_c_include(ag, scope, node, arg0_value);
4223 return ir_lval_wrap(ag, scope, c_include, lval, result_loc);
4224 }
4225 case BuiltinFnIdCDefine:
4226 {
4227 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4228 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4229 if (arg0_value == ag->codegen->invalid_inst_src)
4230 return arg0_value;
4231
4232 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4233 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4234 if (arg1_value == ag->codegen->invalid_inst_src)
4235 return arg1_value;
4236
4237 if (!ag->in_c_import_scope) {
4238 add_node_error(ag->codegen, node, buf_sprintf("C define valid only inside C import block"));
4239 return ag->codegen->invalid_inst_src;
4240 }
4241
4242 IrInstSrc *c_define = ir_build_c_define(ag, scope, node, arg0_value, arg1_value);
4243 return ir_lval_wrap(ag, scope, c_define, lval, result_loc);
4244 }
4245 case BuiltinFnIdCUndef:
4246 {
4247 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4248 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4249 if (arg0_value == ag->codegen->invalid_inst_src)
4250 return arg0_value;
4251
4252 if (!ag->in_c_import_scope) {
4253 add_node_error(ag->codegen, node, buf_sprintf("C undef valid only inside C import block"));
4254 return ag->codegen->invalid_inst_src;
4255 }
4256
4257 IrInstSrc *c_undef = ir_build_c_undef(ag, scope, node, arg0_value);
4258 return ir_lval_wrap(ag, scope, c_undef, lval, result_loc);
4259 }
4260 case BuiltinFnIdCompileErr:
4261 {
4262 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4263 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4264 if (arg0_value == ag->codegen->invalid_inst_src)
4265 return arg0_value;
4266
4267 IrInstSrc *compile_err = ir_build_compile_err(ag, scope, node, arg0_value);
4268 return ir_lval_wrap(ag, scope, compile_err, lval, result_loc);
4269 }
4270 case BuiltinFnIdCompileLog:
4271 {
4272 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(actual_param_count);
4273
4274 for (size_t i = 0; i < actual_param_count; i += 1) {
4275 AstNode *arg_node = node->data.fn_call_expr.params.at(i);
4276 args[i] = astgen_node(ag, arg_node, scope);
4277 if (args[i] == ag->codegen->invalid_inst_src)
4278 return ag->codegen->invalid_inst_src;
4279 }
4280
4281 IrInstSrc *compile_log = ir_build_compile_log(ag, scope, node, actual_param_count, args);
4282 return ir_lval_wrap(ag, scope, compile_log, lval, result_loc);
4283 }
4284 case BuiltinFnIdErrName:
4285 {
4286 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4287 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4288 if (arg0_value == ag->codegen->invalid_inst_src)
4289 return arg0_value;
4290
4291 IrInstSrc *err_name = ir_build_err_name(ag, scope, node, arg0_value);
4292 return ir_lval_wrap(ag, scope, err_name, lval, result_loc);
4293 }
4294 case BuiltinFnIdEmbedFile:
4295 {
4296 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4297 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4298 if (arg0_value == ag->codegen->invalid_inst_src)
4299 return arg0_value;
4300
4301 IrInstSrc *embed_file = ir_build_embed_file(ag, scope, node, arg0_value);
4302 return ir_lval_wrap(ag, scope, embed_file, lval, result_loc);
4303 }
4304 case BuiltinFnIdCmpxchgWeak:
4305 case BuiltinFnIdCmpxchgStrong:
4306 {
4307 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4308 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4309 if (arg0_value == ag->codegen->invalid_inst_src)
4310 return arg0_value;
4311
4312 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4313 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4314 if (arg1_value == ag->codegen->invalid_inst_src)
4315 return arg1_value;
4316
4317 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
4318 IrInstSrc *arg2_value = astgen_node(ag, arg2_node, scope);
4319 if (arg2_value == ag->codegen->invalid_inst_src)
4320 return arg2_value;
4321
4322 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
4323 IrInstSrc *arg3_value = astgen_node(ag, arg3_node, scope);
4324 if (arg3_value == ag->codegen->invalid_inst_src)
4325 return arg3_value;
4326
4327 AstNode *arg4_node = node->data.fn_call_expr.params.at(4);
4328 IrInstSrc *arg4_value = astgen_node(ag, arg4_node, scope);
4329 if (arg4_value == ag->codegen->invalid_inst_src)
4330 return arg4_value;
4331
4332 AstNode *arg5_node = node->data.fn_call_expr.params.at(5);
4333 IrInstSrc *arg5_value = astgen_node(ag, arg5_node, scope);
4334 if (arg5_value == ag->codegen->invalid_inst_src)
4335 return arg5_value;
4336
4337 IrInstSrc *cmpxchg = ir_build_cmpxchg_src(ag, scope, node, arg0_value, arg1_value,
4338 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak),
4339 result_loc);
4340 return ir_lval_wrap(ag, scope, cmpxchg, lval, result_loc);
4341 }
4342 case BuiltinFnIdFence:
4343 {
4344 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4345 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4346 if (arg0_value == ag->codegen->invalid_inst_src)
4347 return arg0_value;
4348
4349 IrInstSrc *fence = ir_build_fence(ag, scope, node, arg0_value);
4350 return ir_lval_wrap(ag, scope, fence, lval, result_loc);
4351 }
4352 case BuiltinFnIdReduce:
4353 {
4354 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4355 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4356 if (arg0_value == ag->codegen->invalid_inst_src)
4357 return arg0_value;
4358
4359 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4360 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4361 if (arg1_value == ag->codegen->invalid_inst_src)
4362 return arg1_value;
4363
4364 IrInstSrc *reduce = ir_build_reduce(ag, scope, node, arg0_value, arg1_value);
4365 return ir_lval_wrap(ag, scope, reduce, lval, result_loc);
4366 }
4367 case BuiltinFnIdDivExact:
4368 {
4369 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4370 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4371 if (arg0_value == ag->codegen->invalid_inst_src)
4372 return arg0_value;
4373
4374 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4375 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4376 if (arg1_value == ag->codegen->invalid_inst_src)
4377 return arg1_value;
4378
4379 IrInstSrc *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true);
4380 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4381 }
4382 case BuiltinFnIdDivTrunc:
4383 {
4384 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4385 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4386 if (arg0_value == ag->codegen->invalid_inst_src)
4387 return arg0_value;
4388
4389 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4390 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4391 if (arg1_value == ag->codegen->invalid_inst_src)
4392 return arg1_value;
4393
4394 IrInstSrc *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true);
4395 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4396 }
4397 case BuiltinFnIdDivFloor:
4398 {
4399 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4400 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4401 if (arg0_value == ag->codegen->invalid_inst_src)
4402 return arg0_value;
4403
4404 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4405 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4406 if (arg1_value == ag->codegen->invalid_inst_src)
4407 return arg1_value;
4408
4409 IrInstSrc *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true);
4410 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4411 }
4412 case BuiltinFnIdRem:
4413 {
4414 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4415 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4416 if (arg0_value == ag->codegen->invalid_inst_src)
4417 return arg0_value;
4418
4419 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4420 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4421 if (arg1_value == ag->codegen->invalid_inst_src)
4422 return arg1_value;
4423
4424 IrInstSrc *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true);
4425 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4426 }
4427 case BuiltinFnIdMod:
4428 {
4429 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4430 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4431 if (arg0_value == ag->codegen->invalid_inst_src)
4432 return arg0_value;
4433
4434 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4435 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4436 if (arg1_value == ag->codegen->invalid_inst_src)
4437 return arg1_value;
4438
4439 IrInstSrc *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true);
4440 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4441 }
4442 case BuiltinFnIdSqrt:
4443 case BuiltinFnIdSin:
4444 case BuiltinFnIdCos:
4445 case BuiltinFnIdExp:
4446 case BuiltinFnIdExp2:
4447 case BuiltinFnIdLog:
4448 case BuiltinFnIdLog2:
4449 case BuiltinFnIdLog10:
4450 case BuiltinFnIdFabs:
4451 case BuiltinFnIdFloor:
4452 case BuiltinFnIdCeil:
4453 case BuiltinFnIdTrunc:
4454 case BuiltinFnIdNearbyInt:
4455 case BuiltinFnIdRound:
4456 {
4457 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4458 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4459 if (arg0_value == ag->codegen->invalid_inst_src)
4460 return arg0_value;
4461
4462 IrInstSrc *inst = ir_build_float_op_src(ag, scope, node, arg0_value, builtin_fn->id);
4463 return ir_lval_wrap(ag, scope, inst, lval, result_loc);
4464 }
4465 case BuiltinFnIdTruncate:
4466 {
4467 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4468 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4469 if (arg0_value == ag->codegen->invalid_inst_src)
4470 return arg0_value;
4471
4472 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4473 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4474 if (arg1_value == ag->codegen->invalid_inst_src)
4475 return arg1_value;
4476
4477 IrInstSrc *truncate = ir_build_truncate(ag, scope, node, arg0_value, arg1_value);
4478 return ir_lval_wrap(ag, scope, truncate, lval, result_loc);
4479 }
4480 case BuiltinFnIdIntCast:
4481 {
4482 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4483 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4484 if (arg0_value == ag->codegen->invalid_inst_src)
4485 return arg0_value;
4486
4487 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4488 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4489 if (arg1_value == ag->codegen->invalid_inst_src)
4490 return arg1_value;
4491
4492 IrInstSrc *result = ir_build_int_cast(ag, scope, node, arg0_value, arg1_value);
4493 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4494 }
4495 case BuiltinFnIdFloatCast:
4496 {
4497 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4498 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4499 if (arg0_value == ag->codegen->invalid_inst_src)
4500 return arg0_value;
4501
4502 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4503 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4504 if (arg1_value == ag->codegen->invalid_inst_src)
4505 return arg1_value;
4506
4507 IrInstSrc *result = ir_build_float_cast(ag, scope, node, arg0_value, arg1_value);
4508 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4509 }
4510 case BuiltinFnIdErrSetCast:
4511 {
4512 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4513 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4514 if (arg0_value == ag->codegen->invalid_inst_src)
4515 return arg0_value;
4516
4517 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4518 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4519 if (arg1_value == ag->codegen->invalid_inst_src)
4520 return arg1_value;
4521
4522 IrInstSrc *result = ir_build_err_set_cast(ag, scope, node, arg0_value, arg1_value);
4523 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4524 }
4525 case BuiltinFnIdIntToFloat:
4526 {
4527 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4528 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4529 if (arg0_value == ag->codegen->invalid_inst_src)
4530 return arg0_value;
4531
4532 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4533 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4534 if (arg1_value == ag->codegen->invalid_inst_src)
4535 return arg1_value;
4536
4537 IrInstSrc *result = ir_build_int_to_float(ag, scope, node, arg0_value, arg1_value);
4538 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4539 }
4540 case BuiltinFnIdFloatToInt:
4541 {
4542 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4543 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4544 if (arg0_value == ag->codegen->invalid_inst_src)
4545 return arg0_value;
4546
4547 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4548 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4549 if (arg1_value == ag->codegen->invalid_inst_src)
4550 return arg1_value;
4551
4552 IrInstSrc *result = ir_build_float_to_int(ag, scope, node, arg0_value, arg1_value);
4553 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4554 }
4555 case BuiltinFnIdErrToInt:
4556 {
4557 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4558 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4559 if (arg0_value == ag->codegen->invalid_inst_src)
4560 return arg0_value;
4561
4562 IrInstSrc *result = ir_build_err_to_int_src(ag, scope, node, arg0_value);
4563 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4564 }
4565 case BuiltinFnIdIntToErr:
4566 {
4567 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4568 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4569 if (arg0_value == ag->codegen->invalid_inst_src)
4570 return arg0_value;
4571
4572 IrInstSrc *result = ir_build_int_to_err_src(ag, scope, node, arg0_value);
4573 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4574 }
4575 case BuiltinFnIdBoolToInt:
4576 {
4577 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4578 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4579 if (arg0_value == ag->codegen->invalid_inst_src)
4580 return arg0_value;
4581
4582 IrInstSrc *result = ir_build_bool_to_int(ag, scope, node, arg0_value);
4583 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4584 }
4585 case BuiltinFnIdVectorType:
4586 {
4587 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4588 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4589 if (arg0_value == ag->codegen->invalid_inst_src)
4590 return arg0_value;
4591
4592 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4593 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4594 if (arg1_value == ag->codegen->invalid_inst_src)
4595 return arg1_value;
4596
4597 IrInstSrc *vector_type = ir_build_vector_type(ag, scope, node, arg0_value, arg1_value);
4598 return ir_lval_wrap(ag, scope, vector_type, lval, result_loc);
4599 }
4600 case BuiltinFnIdShuffle:
4601 {
4602 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4603 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4604 if (arg0_value == ag->codegen->invalid_inst_src)
4605 return arg0_value;
4606
4607 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4608 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4609 if (arg1_value == ag->codegen->invalid_inst_src)
4610 return arg1_value;
4611
4612 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
4613 IrInstSrc *arg2_value = astgen_node(ag, arg2_node, scope);
4614 if (arg2_value == ag->codegen->invalid_inst_src)
4615 return arg2_value;
4616
4617 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
4618 IrInstSrc *arg3_value = astgen_node(ag, arg3_node, scope);
4619 if (arg3_value == ag->codegen->invalid_inst_src)
4620 return arg3_value;
4621
4622 IrInstSrc *shuffle_vector = ir_build_shuffle_vector(ag, scope, node,
4623 arg0_value, arg1_value, arg2_value, arg3_value);
4624 return ir_lval_wrap(ag, scope, shuffle_vector, lval, result_loc);
4625 }
4626 case BuiltinFnIdSplat:
4627 {
4628 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4629 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4630 if (arg0_value == ag->codegen->invalid_inst_src)
4631 return arg0_value;
4632
4633 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4634 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4635 if (arg1_value == ag->codegen->invalid_inst_src)
4636 return arg1_value;
4637
4638 IrInstSrc *splat = ir_build_splat_src(ag, scope, node,
4639 arg0_value, arg1_value);
4640 return ir_lval_wrap(ag, scope, splat, lval, result_loc);
4641 }
4642 case BuiltinFnIdMemcpy:
4643 {
4644 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4645 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4646 if (arg0_value == ag->codegen->invalid_inst_src)
4647 return arg0_value;
4648
4649 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4650 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4651 if (arg1_value == ag->codegen->invalid_inst_src)
4652 return arg1_value;
4653
4654 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
4655 IrInstSrc *arg2_value = astgen_node(ag, arg2_node, scope);
4656 if (arg2_value == ag->codegen->invalid_inst_src)
4657 return arg2_value;
4658
4659 IrInstSrc *ir_memcpy = ir_build_memcpy_src(ag, scope, node, arg0_value, arg1_value, arg2_value);
4660 return ir_lval_wrap(ag, scope, ir_memcpy, lval, result_loc);
4661 }
4662 case BuiltinFnIdMemset:
4663 {
4664 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4665 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4666 if (arg0_value == ag->codegen->invalid_inst_src)
4667 return arg0_value;
4668
4669 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4670 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4671 if (arg1_value == ag->codegen->invalid_inst_src)
4672 return arg1_value;
4673
4674 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
4675 IrInstSrc *arg2_value = astgen_node(ag, arg2_node, scope);
4676 if (arg2_value == ag->codegen->invalid_inst_src)
4677 return arg2_value;
4678
4679 IrInstSrc *ir_memset = ir_build_memset_src(ag, scope, node, arg0_value, arg1_value, arg2_value);
4680 return ir_lval_wrap(ag, scope, ir_memset, lval, result_loc);
4681 }
4682 case BuiltinFnIdWasmMemorySize:
4683 {
4684 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4685 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4686 if (arg0_value == ag->codegen->invalid_inst_src)
4687 return arg0_value;
4688
4689 IrInstSrc *ir_wasm_memory_size = ir_build_wasm_memory_size_src(ag, scope, node, arg0_value);
4690 return ir_lval_wrap(ag, scope, ir_wasm_memory_size, lval, result_loc);
4691 }
4692 case BuiltinFnIdWasmMemoryGrow:
4693 {
4694 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4695 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4696 if (arg0_value == ag->codegen->invalid_inst_src)
4697 return arg0_value;
4698
4699 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4700 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4701 if (arg1_value == ag->codegen->invalid_inst_src)
4702 return arg1_value;
4703
4704 IrInstSrc *ir_wasm_memory_grow = ir_build_wasm_memory_grow_src(ag, scope, node, arg0_value, arg1_value);
4705 return ir_lval_wrap(ag, scope, ir_wasm_memory_grow, lval, result_loc);
4706 }
4707 case BuiltinFnIdField:
4708 {
4709 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4710 IrInstSrc *arg0_value = astgen_node_extra(ag, arg0_node, scope, LValPtr, nullptr);
4711 if (arg0_value == ag->codegen->invalid_inst_src)
4712 return arg0_value;
4713
4714 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4715 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4716 if (arg1_value == ag->codegen->invalid_inst_src)
4717 return arg1_value;
4718
4719 IrInstSrc *ptr_instruction = ir_build_field_ptr_instruction(ag, scope, node,
4720 arg0_value, arg1_value, false);
4721
4722 if (lval == LValPtr || lval == LValAssign)
4723 return ptr_instruction;
4724
4725 IrInstSrc *load_ptr = ir_build_load_ptr(ag, scope, node, ptr_instruction);
4726 return ir_expr_wrap(ag, scope, load_ptr, result_loc);
4727 }
4728 case BuiltinFnIdHasField:
4729 {
4730 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4731 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4732 if (arg0_value == ag->codegen->invalid_inst_src)
4733 return arg0_value;
4734
4735 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4736 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4737 if (arg1_value == ag->codegen->invalid_inst_src)
4738 return arg1_value;
4739
4740 IrInstSrc *type_info = ir_build_has_field(ag, scope, node, arg0_value, arg1_value);
4741 return ir_lval_wrap(ag, scope, type_info, lval, result_loc);
4742 }
4743 case BuiltinFnIdTypeInfo:
4744 {
4745 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4746 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4747 if (arg0_value == ag->codegen->invalid_inst_src)
4748 return arg0_value;
4749
4750 IrInstSrc *type_info = ir_build_type_info(ag, scope, node, arg0_value);
4751 return ir_lval_wrap(ag, scope, type_info, lval, result_loc);
4752 }
4753 case BuiltinFnIdType:
4754 {
4755 AstNode *arg_node = node->data.fn_call_expr.params.at(0);
4756 IrInstSrc *arg = astgen_node(ag, arg_node, scope);
4757 if (arg == ag->codegen->invalid_inst_src)
4758 return arg;
4759
4760 IrInstSrc *type = ir_build_type(ag, scope, node, arg);
4761 return ir_lval_wrap(ag, scope, type, lval, result_loc);
4762 }
4763 case BuiltinFnIdBreakpoint:
4764 return ir_lval_wrap(ag, scope, ir_build_breakpoint(ag, scope, node), lval, result_loc);
4765 case BuiltinFnIdReturnAddress:
4766 return ir_lval_wrap(ag, scope, ir_build_return_address_src(ag, scope, node), lval, result_loc);
4767 case BuiltinFnIdFrameAddress:
4768 return ir_lval_wrap(ag, scope, ir_build_frame_address_src(ag, scope, node), lval, result_loc);
4769 case BuiltinFnIdFrameHandle:
4770 if (ag->fn == nullptr) {
4771 add_node_error(ag->codegen, node,
4772 buf_sprintf("@frame() called outside of function definition"));
4773 return ag->codegen->invalid_inst_src;
4774 }
4775 return ir_lval_wrap(ag, scope, ir_build_handle_src(ag, scope, node), lval, result_loc);
4776 case BuiltinFnIdFrameType: {
4777 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4778 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4779 if (arg0_value == ag->codegen->invalid_inst_src)
4780 return arg0_value;
4781
4782 IrInstSrc *frame_type = ir_build_frame_type(ag, scope, node, arg0_value);
4783 return ir_lval_wrap(ag, scope, frame_type, lval, result_loc);
4784 }
4785 case BuiltinFnIdFrameSize: {
4786 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4787 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4788 if (arg0_value == ag->codegen->invalid_inst_src)
4789 return arg0_value;
4790
4791 IrInstSrc *frame_size = ir_build_frame_size_src(ag, scope, node, arg0_value);
4792 return ir_lval_wrap(ag, scope, frame_size, lval, result_loc);
4793 }
4794 case BuiltinFnIdAlignOf:
4795 {
4796 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4797 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4798 if (arg0_value == ag->codegen->invalid_inst_src)
4799 return arg0_value;
4800
4801 IrInstSrc *align_of = ir_build_align_of(ag, scope, node, arg0_value);
4802 return ir_lval_wrap(ag, scope, align_of, lval, result_loc);
4803 }
4804 case BuiltinFnIdAddWithOverflow:
4805 return ir_lval_wrap(ag, scope, astgen_overflow_op(ag, scope, node, IrOverflowOpAdd), lval, result_loc);
4806 case BuiltinFnIdSubWithOverflow:
4807 return ir_lval_wrap(ag, scope, astgen_overflow_op(ag, scope, node, IrOverflowOpSub), lval, result_loc);
4808 case BuiltinFnIdMulWithOverflow:
4809 return ir_lval_wrap(ag, scope, astgen_overflow_op(ag, scope, node, IrOverflowOpMul), lval, result_loc);
4810 case BuiltinFnIdShlWithOverflow:
4811 return ir_lval_wrap(ag, scope, astgen_overflow_op(ag, scope, node, IrOverflowOpShl), lval, result_loc);
4812 case BuiltinFnIdMulAdd:
4813 return ir_lval_wrap(ag, scope, astgen_mul_add(ag, scope, node), lval, result_loc);
4814 case BuiltinFnIdTypeName:
4815 {
4816 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4817 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4818 if (arg0_value == ag->codegen->invalid_inst_src)
4819 return arg0_value;
4820
4821 IrInstSrc *type_name = ir_build_type_name(ag, scope, node, arg0_value);
4822 return ir_lval_wrap(ag, scope, type_name, lval, result_loc);
4823 }
4824 case BuiltinFnIdPanic:
4825 {
4826 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4827 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4828 if (arg0_value == ag->codegen->invalid_inst_src)
4829 return arg0_value;
4830
4831 IrInstSrc *panic = ir_build_panic_src(ag, scope, node, arg0_value);
4832 return ir_lval_wrap(ag, scope, panic, lval, result_loc);
4833 }
4834 case BuiltinFnIdPtrCast:
4835 {
4836 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4837 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4838 if (arg0_value == ag->codegen->invalid_inst_src)
4839 return arg0_value;
4840
4841 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4842 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4843 if (arg1_value == ag->codegen->invalid_inst_src)
4844 return arg1_value;
4845
4846 IrInstSrc *ptr_cast = ir_build_ptr_cast_src(ag, scope, node, arg0_value, arg1_value, true);
4847 return ir_lval_wrap(ag, scope, ptr_cast, lval, result_loc);
4848 }
4849 case BuiltinFnIdBitCast:
4850 {
4851 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0);
4852 IrInstSrc *dest_type = astgen_node(ag, dest_type_node, scope);
4853 if (dest_type == ag->codegen->invalid_inst_src)
4854 return dest_type;
4855
4856 ResultLocBitCast *result_loc_bit_cast = heap::c_allocator.create<ResultLocBitCast>();
4857 result_loc_bit_cast->base.id = ResultLocIdBitCast;
4858 result_loc_bit_cast->base.source_instruction = dest_type;
4859 result_loc_bit_cast->base.allow_write_through_const = result_loc->allow_write_through_const;
4860 ir_ref_instruction(dest_type, ag->current_basic_block);
4861 result_loc_bit_cast->parent = result_loc;
4862
4863 ir_build_reset_result(ag, scope, node, &result_loc_bit_cast->base);
4864
4865 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4866 IrInstSrc *arg1_value = astgen_node_extra(ag, arg1_node, scope, LValNone,
4867 &result_loc_bit_cast->base);
4868 if (arg1_value == ag->codegen->invalid_inst_src)
4869 return arg1_value;
4870
4871 IrInstSrc *bitcast = ir_build_bit_cast_src(ag, scope, arg1_node, arg1_value, result_loc_bit_cast);
4872 return ir_lval_wrap(ag, scope, bitcast, lval, result_loc);
4873 }
4874 case BuiltinFnIdAs:
4875 {
4876 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0);
4877 IrInstSrc *dest_type = astgen_node(ag, dest_type_node, scope);
4878 if (dest_type == ag->codegen->invalid_inst_src)
4879 return dest_type;
4880
4881 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(ag, dest_type, result_loc);
4882
4883 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4884 IrInstSrc *arg1_value = astgen_node_extra(ag, arg1_node, scope, LValNone,
4885 &result_loc_cast->base);
4886 if (arg1_value == ag->codegen->invalid_inst_src)
4887 return arg1_value;
4888
4889 IrInstSrc *result = ir_build_implicit_cast(ag, scope, node, arg1_value, result_loc_cast);
4890 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4891 }
4892 case BuiltinFnIdIntToPtr:
4893 {
4894 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4895 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4896 if (arg0_value == ag->codegen->invalid_inst_src)
4897 return arg0_value;
4898
4899 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4900 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4901 if (arg1_value == ag->codegen->invalid_inst_src)
4902 return arg1_value;
4903
4904 IrInstSrc *int_to_ptr = ir_build_int_to_ptr_src(ag, scope, node, arg0_value, arg1_value);
4905 return ir_lval_wrap(ag, scope, int_to_ptr, lval, result_loc);
4906 }
4907 case BuiltinFnIdPtrToInt:
4908 {
4909 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4910 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4911 if (arg0_value == ag->codegen->invalid_inst_src)
4912 return arg0_value;
4913
4914 IrInstSrc *ptr_to_int = ir_build_ptr_to_int_src(ag, scope, node, arg0_value);
4915 return ir_lval_wrap(ag, scope, ptr_to_int, lval, result_loc);
4916 }
4917 case BuiltinFnIdTagName:
4918 {
4919 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4920 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4921 if (arg0_value == ag->codegen->invalid_inst_src)
4922 return arg0_value;
4923
4924 IrInstSrc *tag_name = ir_build_tag_name_src(ag, scope, node, arg0_value);
4925 return ir_lval_wrap(ag, scope, tag_name, lval, result_loc);
4926 }
4927 case BuiltinFnIdFieldParentPtr:
4928 {
4929 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4930 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4931 if (arg0_value == ag->codegen->invalid_inst_src)
4932 return arg0_value;
4933
4934 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4935 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4936 if (arg1_value == ag->codegen->invalid_inst_src)
4937 return arg1_value;
4938
4939 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
4940 IrInstSrc *arg2_value = astgen_node(ag, arg2_node, scope);
4941 if (arg2_value == ag->codegen->invalid_inst_src)
4942 return arg2_value;
4943
4944 IrInstSrc *field_parent_ptr = ir_build_field_parent_ptr_src(ag, scope, node,
4945 arg0_value, arg1_value, arg2_value);
4946 return ir_lval_wrap(ag, scope, field_parent_ptr, lval, result_loc);
4947 }
4948 case BuiltinFnIdByteOffsetOf:
4949 {
4950 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4951 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4952 if (arg0_value == ag->codegen->invalid_inst_src)
4953 return arg0_value;
4954
4955 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4956 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4957 if (arg1_value == ag->codegen->invalid_inst_src)
4958 return arg1_value;
4959
4960 IrInstSrc *offset_of = ir_build_byte_offset_of(ag, scope, node, arg0_value, arg1_value);
4961 return ir_lval_wrap(ag, scope, offset_of, lval, result_loc);
4962 }
4963 case BuiltinFnIdBitOffsetOf:
4964 {
4965 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4966 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
4967 if (arg0_value == ag->codegen->invalid_inst_src)
4968 return arg0_value;
4969
4970 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4971 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
4972 if (arg1_value == ag->codegen->invalid_inst_src)
4973 return arg1_value;
4974
4975 IrInstSrc *offset_of = ir_build_bit_offset_of(ag, scope, node, arg0_value, arg1_value);
4976 return ir_lval_wrap(ag, scope, offset_of, lval, result_loc);
4977 }
4978 case BuiltinFnIdCall: {
4979 // Cast the options parameter to the options type
4980 ZigType *options_type = get_builtin_type(ag->codegen, "CallOptions");
4981 IrInstSrc *options_type_inst = ir_build_const_type(ag, scope, node, options_type);
4982 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(ag, options_type_inst, no_result_loc());
4983
4984 AstNode *options_node = node->data.fn_call_expr.params.at(0);
4985 IrInstSrc *options_inner = astgen_node_extra(ag, options_node, scope,
4986 LValNone, &result_loc_cast->base);
4987 if (options_inner == ag->codegen->invalid_inst_src)
4988 return options_inner;
4989 IrInstSrc *options = ir_build_implicit_cast(ag, scope, options_node, options_inner, result_loc_cast);
4990
4991 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1);
4992 AstNode *args_node = node->data.fn_call_expr.params.at(2);
4993 if (args_node->type == NodeTypeContainerInitExpr) {
4994 if (args_node->data.container_init_expr.kind == ContainerInitKindArray ||
4995 args_node->data.container_init_expr.entries.length == 0)
4996 {
4997 return astgen_fn_call_with_args(ag, scope, node,
4998 fn_ref_node, CallModifierNone, options,
4999 args_node->data.container_init_expr.entries.items,
5000 args_node->data.container_init_expr.entries.length,
5001 lval, result_loc);
5002 } else {
5003 exec_add_error_node(ag->codegen, ag->exec, args_node,
5004 buf_sprintf("TODO: @call with anon struct literal"));
5005 return ag->codegen->invalid_inst_src;
5006 }
5007 } else {
5008 IrInstSrc *fn_ref = astgen_node(ag, fn_ref_node, scope);
5009 if (fn_ref == ag->codegen->invalid_inst_src)
5010 return fn_ref;
5011
5012 IrInstSrc *args = astgen_node(ag, args_node, scope);
5013 if (args == ag->codegen->invalid_inst_src)
5014 return args;
5015
5016 IrInstSrc *call = ir_build_call_extra(ag, scope, node, options, fn_ref, args, result_loc);
5017 return ir_lval_wrap(ag, scope, call, lval, result_loc);
5018 }
5019 }
5020 case BuiltinFnIdAsyncCall:
5021 return astgen_async_call(ag, scope, nullptr, node, lval, result_loc);
5022 case BuiltinFnIdShlExact:
5023 {
5024 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5025 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
5026 if (arg0_value == ag->codegen->invalid_inst_src)
5027 return arg0_value;
5028
5029 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5030 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
5031 if (arg1_value == ag->codegen->invalid_inst_src)
5032 return arg1_value;
5033
5034 IrInstSrc *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true);
5035 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
5036 }
5037 case BuiltinFnIdShrExact:
5038 {
5039 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5040 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
5041 if (arg0_value == ag->codegen->invalid_inst_src)
5042 return arg0_value;
5043
5044 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5045 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
5046 if (arg1_value == ag->codegen->invalid_inst_src)
5047 return arg1_value;
5048
5049 IrInstSrc *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true);
5050 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
5051 }
5052 case BuiltinFnIdSetEvalBranchQuota:
5053 {
5054 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5055 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
5056 if (arg0_value == ag->codegen->invalid_inst_src)
5057 return arg0_value;
5058
5059 IrInstSrc *set_eval_branch_quota = ir_build_set_eval_branch_quota(ag, scope, node, arg0_value);
5060 return ir_lval_wrap(ag, scope, set_eval_branch_quota, lval, result_loc);
5061 }
5062 case BuiltinFnIdAlignCast:
5063 {
5064 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5065 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
5066 if (arg0_value == ag->codegen->invalid_inst_src)
5067 return arg0_value;
5068
5069 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5070 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
5071 if (arg1_value == ag->codegen->invalid_inst_src)
5072 return arg1_value;
5073
5074 IrInstSrc *align_cast = ir_build_align_cast_src(ag, scope, node, arg0_value, arg1_value);
5075 return ir_lval_wrap(ag, scope, align_cast, lval, result_loc);
5076 }
5077 case BuiltinFnIdThis:
5078 {
5079 IrInstSrc *this_inst = astgen_this(ag, scope, node);
5080 return ir_lval_wrap(ag, scope, this_inst, lval, result_loc);
5081 }
5082 case BuiltinFnIdSetAlignStack:
5083 {
5084 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5085 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
5086 if (arg0_value == ag->codegen->invalid_inst_src)
5087 return arg0_value;
5088
5089 IrInstSrc *set_align_stack = ir_build_set_align_stack(ag, scope, node, arg0_value);
5090 return ir_lval_wrap(ag, scope, set_align_stack, lval, result_loc);
5091 }
5092 case BuiltinFnIdExport:
5093 {
5094 // Cast the options parameter to the options type
5095 ZigType *options_type = get_builtin_type(ag->codegen, "ExportOptions");
5096 IrInstSrc *options_type_inst = ir_build_const_type(ag, scope, node, options_type);
5097 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(ag, options_type_inst, no_result_loc());
5098
5099 AstNode *target_node = node->data.fn_call_expr.params.at(0);
5100 IrInstSrc *target_value = astgen_node(ag, target_node, scope);
5101 if (target_value == ag->codegen->invalid_inst_src)
5102 return target_value;
5103
5104 AstNode *options_node = node->data.fn_call_expr.params.at(1);
5105 IrInstSrc *options_value = astgen_node_extra(ag, options_node,
5106 scope, LValNone, &result_loc_cast->base);
5107 if (options_value == ag->codegen->invalid_inst_src)
5108 return options_value;
5109
5110 IrInstSrc *casted_options_value = ir_build_implicit_cast(
5111 ag, scope, options_node, options_value, result_loc_cast);
5112
5113 IrInstSrc *ir_export = ir_build_export(ag, scope, node, target_value, casted_options_value);
5114 return ir_lval_wrap(ag, scope, ir_export, lval, result_loc);
5115 }
5116 case BuiltinFnIdExtern:
5117 {
5118 // Cast the options parameter to the options type
5119 ZigType *options_type = get_builtin_type(ag->codegen, "ExternOptions");
5120 IrInstSrc *options_type_inst = ir_build_const_type(ag, scope, node, options_type);
5121 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(ag, options_type_inst, no_result_loc());
5122
5123 AstNode *type_node = node->data.fn_call_expr.params.at(0);
5124 IrInstSrc *type_value = astgen_node(ag, type_node, scope);
5125 if (type_value == ag->codegen->invalid_inst_src)
5126 return type_value;
5127
5128 AstNode *options_node = node->data.fn_call_expr.params.at(1);
5129 IrInstSrc *options_value = astgen_node_extra(ag, options_node,
5130 scope, LValNone, &result_loc_cast->base);
5131 if (options_value == ag->codegen->invalid_inst_src)
5132 return options_value;
5133
5134 IrInstSrc *casted_options_value = ir_build_implicit_cast(
5135 ag, scope, options_node, options_value, result_loc_cast);
5136
5137 IrInstSrc *ir_extern = ir_build_extern(ag, scope, node, type_value, casted_options_value);
5138 return ir_lval_wrap(ag, scope, ir_extern, lval, result_loc);
5139 }
5140 case BuiltinFnIdErrorReturnTrace:
5141 {
5142 IrInstSrc *error_return_trace = ir_build_error_return_trace_src(ag, scope, node,
5143 IrInstErrorReturnTraceNull);
5144 return ir_lval_wrap(ag, scope, error_return_trace, lval, result_loc);
5145 }
5146 case BuiltinFnIdAtomicRmw:
5147 {
5148 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5149 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
5150 if (arg0_value == ag->codegen->invalid_inst_src)
5151 return arg0_value;
5152
5153 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5154 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
5155 if (arg1_value == ag->codegen->invalid_inst_src)
5156 return arg1_value;
5157
5158 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
5159 IrInstSrc *arg2_value = astgen_node(ag, arg2_node, scope);
5160 if (arg2_value == ag->codegen->invalid_inst_src)
5161 return arg2_value;
5162
5163 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
5164 IrInstSrc *arg3_value = astgen_node(ag, arg3_node, scope);
5165 if (arg3_value == ag->codegen->invalid_inst_src)
5166 return arg3_value;
5167
5168 AstNode *arg4_node = node->data.fn_call_expr.params.at(4);
5169 IrInstSrc *arg4_value = astgen_node(ag, arg4_node, scope);
5170 if (arg4_value == ag->codegen->invalid_inst_src)
5171 return arg4_value;
5172
5173 IrInstSrc *inst = ir_build_atomic_rmw_src(ag, scope, node,
5174 arg0_value, arg1_value, arg2_value, arg3_value, arg4_value);
5175 return ir_lval_wrap(ag, scope, inst, lval, result_loc);
5176 }
5177 case BuiltinFnIdAtomicLoad:
5178 {
5179 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5180 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
5181 if (arg0_value == ag->codegen->invalid_inst_src)
5182 return arg0_value;
5183
5184 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5185 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
5186 if (arg1_value == ag->codegen->invalid_inst_src)
5187 return arg1_value;
5188
5189 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
5190 IrInstSrc *arg2_value = astgen_node(ag, arg2_node, scope);
5191 if (arg2_value == ag->codegen->invalid_inst_src)
5192 return arg2_value;
5193
5194 IrInstSrc *inst = ir_build_atomic_load_src(ag, scope, node, arg0_value, arg1_value, arg2_value);
5195 return ir_lval_wrap(ag, scope, inst, lval, result_loc);
5196 }
5197 case BuiltinFnIdAtomicStore:
5198 {
5199 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5200 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
5201 if (arg0_value == ag->codegen->invalid_inst_src)
5202 return arg0_value;
5203
5204 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5205 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
5206 if (arg1_value == ag->codegen->invalid_inst_src)
5207 return arg1_value;
5208
5209 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
5210 IrInstSrc *arg2_value = astgen_node(ag, arg2_node, scope);
5211 if (arg2_value == ag->codegen->invalid_inst_src)
5212 return arg2_value;
5213
5214 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
5215 IrInstSrc *arg3_value = astgen_node(ag, arg3_node, scope);
5216 if (arg3_value == ag->codegen->invalid_inst_src)
5217 return arg3_value;
5218
5219 IrInstSrc *inst = ir_build_atomic_store_src(ag, scope, node, arg0_value, arg1_value,
5220 arg2_value, arg3_value);
5221 return ir_lval_wrap(ag, scope, inst, lval, result_loc);
5222 }
5223 case BuiltinFnIdIntToEnum:
5224 {
5225 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5226 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
5227 if (arg0_value == ag->codegen->invalid_inst_src)
5228 return arg0_value;
5229
5230 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5231 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
5232 if (arg1_value == ag->codegen->invalid_inst_src)
5233 return arg1_value;
5234
5235 IrInstSrc *result = ir_build_int_to_enum_src(ag, scope, node, arg0_value, arg1_value);
5236 return ir_lval_wrap(ag, scope, result, lval, result_loc);
5237 }
5238 case BuiltinFnIdEnumToInt:
5239 {
5240 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5241 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
5242 if (arg0_value == ag->codegen->invalid_inst_src)
5243 return arg0_value;
5244
5245 IrInstSrc *result = ir_build_enum_to_int(ag, scope, node, arg0_value);
5246 return ir_lval_wrap(ag, scope, result, lval, result_loc);
5247 }
5248 case BuiltinFnIdCtz:
5249 case BuiltinFnIdPopCount:
5250 case BuiltinFnIdClz:
5251 case BuiltinFnIdBswap:
5252 case BuiltinFnIdBitReverse:
5253 {
5254 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5255 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
5256 if (arg0_value == ag->codegen->invalid_inst_src)
5257 return arg0_value;
5258
5259 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5260 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
5261 if (arg1_value == ag->codegen->invalid_inst_src)
5262 return arg1_value;
5263
5264 IrInstSrc *result;
5265 switch (builtin_fn->id) {
5266 case BuiltinFnIdCtz:
5267 result = ir_build_ctz(ag, scope, node, arg0_value, arg1_value);
5268 break;
5269 case BuiltinFnIdPopCount:
5270 result = ir_build_pop_count(ag, scope, node, arg0_value, arg1_value);
5271 break;
5272 case BuiltinFnIdClz:
5273 result = ir_build_clz(ag, scope, node, arg0_value, arg1_value);
5274 break;
5275 case BuiltinFnIdBswap:
5276 result = ir_build_bswap(ag, scope, node, arg0_value, arg1_value);
5277 break;
5278 case BuiltinFnIdBitReverse:
5279 result = ir_build_bit_reverse(ag, scope, node, arg0_value, arg1_value);
5280 break;
5281 default:
5282 zig_unreachable();
5283 }
5284 return ir_lval_wrap(ag, scope, result, lval, result_loc);
5285 }
5286 case BuiltinFnIdHasDecl:
5287 {
5288 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5289 IrInstSrc *arg0_value = astgen_node(ag, arg0_node, scope);
5290 if (arg0_value == ag->codegen->invalid_inst_src)
5291 return arg0_value;
5292
5293 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5294 IrInstSrc *arg1_value = astgen_node(ag, arg1_node, scope);
5295 if (arg1_value == ag->codegen->invalid_inst_src)
5296 return arg1_value;
5297
5298 IrInstSrc *has_decl = ir_build_has_decl(ag, scope, node, arg0_value, arg1_value);
5299 return ir_lval_wrap(ag, scope, has_decl, lval, result_loc);
5300 }
5301 case BuiltinFnIdUnionInit:
5302 {
5303 AstNode *union_type_node = node->data.fn_call_expr.params.at(0);
5304 IrInstSrc *union_type_inst = astgen_node(ag, union_type_node, scope);
5305 if (union_type_inst == ag->codegen->invalid_inst_src)
5306 return union_type_inst;
5307
5308 AstNode *name_node = node->data.fn_call_expr.params.at(1);
5309 IrInstSrc *name_inst = astgen_node(ag, name_node, scope);
5310 if (name_inst == ag->codegen->invalid_inst_src)
5311 return name_inst;
5312
5313 AstNode *init_node = node->data.fn_call_expr.params.at(2);
5314
5315 return astgen_union_init_expr(ag, scope, node, union_type_inst, name_inst, init_node,
5316 lval, result_loc);
5317 }
5318 case BuiltinFnIdSrc:
5319 {
5320 IrInstSrc *src_inst = ir_build_src(ag, scope, node);
5321 return ir_lval_wrap(ag, scope, src_inst, lval, result_loc);
5322 }
5323 }
5324 zig_unreachable();
5325}
5326
5327static ScopeNoSuspend *get_scope_nosuspend(Scope *scope) {
5328 while (scope) {
5329 if (scope->id == ScopeIdNoSuspend)
5330 return (ScopeNoSuspend *)scope;
5331 if (scope->id == ScopeIdFnDef)
5332 return nullptr;
5333
5334 scope = scope->parent;
5335 }
5336 return nullptr;
5337}
5338
5339static IrInstSrc *astgen_fn_call(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
5340 ResultLoc *result_loc)
5341{
5342 assert(node->type == NodeTypeFnCallExpr);
5343
5344 if (node->data.fn_call_expr.modifier == CallModifierBuiltin)
5345 return astgen_builtin_fn_call(ag, scope, node, lval, result_loc);
5346
5347 bool is_nosuspend = get_scope_nosuspend(scope) != nullptr;
5348 CallModifier modifier = node->data.fn_call_expr.modifier;
5349 if (is_nosuspend && modifier != CallModifierAsync) {
5350 modifier = CallModifierNoSuspend;
5351 }
5352
5353 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
5354 return astgen_fn_call_with_args(ag, scope, node, fn_ref_node, modifier,
5355 nullptr, node->data.fn_call_expr.params.items, node->data.fn_call_expr.params.length, lval, result_loc);
5356}
5357
5358static IrInstSrc *astgen_if_bool_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
5359 ResultLoc *result_loc)
5360{
5361 assert(node->type == NodeTypeIfBoolExpr);
5362
5363 IrInstSrc *condition = astgen_node(ag, node->data.if_bool_expr.condition, scope);
5364 if (condition == ag->codegen->invalid_inst_src)
5365 return ag->codegen->invalid_inst_src;
5366
5367 IrInstSrc *is_comptime;
5368 if (ir_should_inline(ag->exec, scope)) {
5369 is_comptime = ir_build_const_bool(ag, scope, node, true);
5370 } else {
5371 is_comptime = ir_build_test_comptime(ag, scope, node, condition);
5372 }
5373
5374 AstNode *then_node = node->data.if_bool_expr.then_block;
5375 AstNode *else_node = node->data.if_bool_expr.else_node;
5376
5377 Stage1ZirBasicBlock *then_block = ir_create_basic_block(ag, scope, "Then");
5378 Stage1ZirBasicBlock *else_block = ir_create_basic_block(ag, scope, "Else");
5379 Stage1ZirBasicBlock *endif_block = ir_create_basic_block(ag, scope, "EndIf");
5380
5381 IrInstSrc *cond_br_inst = ir_build_cond_br(ag, scope, node, condition,
5382 then_block, else_block, is_comptime);
5383 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(ag, cond_br_inst, else_block, endif_block,
5384 result_loc, is_comptime);
5385
5386 ir_set_cursor_at_end_and_append_block(ag, then_block);
5387
5388 Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, scope, is_comptime);
5389 IrInstSrc *then_expr_result = astgen_node_extra(ag, then_node, subexpr_scope, lval,
5390 &peer_parent->peers.at(0)->base);
5391 if (then_expr_result == ag->codegen->invalid_inst_src)
5392 return ag->codegen->invalid_inst_src;
5393 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
5394 if (!instr_is_unreachable(then_expr_result))
5395 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));
5396
5397 ir_set_cursor_at_end_and_append_block(ag, else_block);
5398 IrInstSrc *else_expr_result;
5399 if (else_node) {
5400 else_expr_result = astgen_node_extra(ag, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base);
5401 if (else_expr_result == ag->codegen->invalid_inst_src)
5402 return ag->codegen->invalid_inst_src;
5403 } else {
5404 else_expr_result = ir_build_const_void(ag, scope, node);
5405 ir_build_end_expr(ag, scope, node, else_expr_result, &peer_parent->peers.at(1)->base);
5406 }
5407 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
5408 if (!instr_is_unreachable(else_expr_result))
5409 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));
5410
5411 ir_set_cursor_at_end_and_append_block(ag, endif_block);
5412 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
5413 incoming_values[0] = then_expr_result;
5414 incoming_values[1] = else_expr_result;
5415 Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
5416 incoming_blocks[0] = after_then_block;
5417 incoming_blocks[1] = after_else_block;
5418
5419 IrInstSrc *phi = ir_build_phi(ag, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
5420 return ir_expr_wrap(ag, scope, phi, result_loc);
5421}
5422
5423static IrInstSrc *astgen_prefix_op_id_lval(Stage1AstGen *ag, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) {
5424 assert(node->type == NodeTypePrefixOpExpr);
5425 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
5426
5427 IrInstSrc *value = astgen_node_extra(ag, expr_node, scope, lval, nullptr);
5428 if (value == ag->codegen->invalid_inst_src)
5429 return value;
5430
5431 return ir_build_un_op(ag, scope, node, op_id, value);
5432}
5433
5434static IrInstSrc *astgen_prefix_op_id(Stage1AstGen *ag, Scope *scope, AstNode *node, IrUnOp op_id) {
5435 return astgen_prefix_op_id_lval(ag, scope, node, op_id, LValNone);
5436}
5437
5438static IrInstSrc *ir_expr_wrap(Stage1AstGen *ag, Scope *scope, IrInstSrc *inst, ResultLoc *result_loc) {
5439 if (inst == ag->codegen->invalid_inst_src) return inst;
5440 ir_build_end_expr(ag, scope, inst->base.source_node, inst, result_loc);
5441 return inst;
5442}
5443
5444static IrInstSrc *ir_lval_wrap(Stage1AstGen *ag, Scope *scope, IrInstSrc *value, LVal lval,
5445 ResultLoc *result_loc)
5446{
5447 // This logic must be kept in sync with
5448 // [STMT_EXPR_TEST_THING] <--- (search this token)
5449 if (value == ag->codegen->invalid_inst_src ||
5450 instr_is_unreachable(value) ||
5451 value->base.source_node->type == NodeTypeDefer ||
5452 value->id == IrInstSrcIdDeclVar)
5453 {
5454 return value;
5455 }
5456
5457 assert(lval != LValAssign);
5458 if (lval == LValPtr) {
5459 // We needed a pointer to a value, but we got a value. So we create
5460 // an instruction which just makes a pointer of it.
5461 return ir_build_ref_src(ag, scope, value->base.source_node, value);
5462 } else if (result_loc != nullptr) {
5463 return ir_expr_wrap(ag, scope, value, result_loc);
5464 } else {
5465 return value;
5466 }
5467
5468}
5469
5470static PtrLen star_token_to_ptr_len(TokenId token_id) {
5471 switch (token_id) {
5472 case TokenIdStar:
5473 case TokenIdStarStar:
5474 return PtrLenSingle;
5475 case TokenIdLBracket:
5476 return PtrLenUnknown;
5477 case TokenIdIdentifier:
5478 return PtrLenC;
5479 default:
5480 zig_unreachable();
5481 }
5482}
5483
5484static Error token_number_literal_u32(Stage1AstGen *ag, AstNode *source_node,
5485 RootStruct *root_struct, uint32_t *result, TokenIndex token)
5486{
5487 BigInt bigint;
5488 token_number_literal_bigint(root_struct, &bigint, token);
5489
5490 if (!bigint_fits_in_bits(&bigint, 32, false)) {
5491 Buf *val_buf = buf_alloc();
5492 bigint_append_buf(val_buf, &bigint, 10);
5493 exec_add_error_node(ag->codegen, ag->exec, source_node,
5494 buf_sprintf("value %s too large for u32", buf_ptr(val_buf)));
5495 bigint_deinit(&bigint);
5496 return ErrorSemanticAnalyzeFail;
5497 }
5498 *result = bigint_as_u32(&bigint);
5499 bigint_deinit(&bigint);
5500 return ErrorNone;
5501
5502}
5503
5504static IrInstSrc *astgen_pointer_type(Stage1AstGen *ag, Scope *scope, AstNode *node) {
5505 Error err;
5506 assert(node->type == NodeTypePointerType);
5507
5508 RootStruct *root_struct = node->owner->data.structure.root_struct;
5509 TokenId star_tok_id = root_struct->token_ids[node->data.pointer_type.star_token];
5510 PtrLen ptr_len = star_token_to_ptr_len(star_tok_id);
5511
5512 bool is_const = node->data.pointer_type.is_const;
5513 bool is_volatile = node->data.pointer_type.is_volatile;
5514 bool is_allow_zero = node->data.pointer_type.allow_zero_token != 0;
5515 AstNode *sentinel_expr = node->data.pointer_type.sentinel;
5516 AstNode *expr_node = node->data.pointer_type.op_expr;
5517 AstNode *align_expr = node->data.pointer_type.align_expr;
5518
5519 IrInstSrc *sentinel;
5520 if (sentinel_expr != nullptr) {
5521 sentinel = astgen_node(ag, sentinel_expr, scope);
5522 if (sentinel == ag->codegen->invalid_inst_src)
5523 return sentinel;
5524 } else {
5525 sentinel = nullptr;
5526 }
5527
5528 IrInstSrc *align_value;
5529 if (align_expr != nullptr) {
5530 align_value = astgen_node(ag, align_expr, scope);
5531 if (align_value == ag->codegen->invalid_inst_src)
5532 return align_value;
5533 } else {
5534 align_value = nullptr;
5535 }
5536
5537 IrInstSrc *child_type = astgen_node(ag, expr_node, scope);
5538 if (child_type == ag->codegen->invalid_inst_src)
5539 return child_type;
5540
5541 uint32_t bit_offset_start = 0;
5542 if (node->data.pointer_type.bit_offset_start != 0) {
5543 if ((err = token_number_literal_u32(ag, node, root_struct, &bit_offset_start,
5544 node->data.pointer_type.bit_offset_start)))
5545 {
5546 return ag->codegen->invalid_inst_src;
5547 }
5548 }
5549
5550 uint32_t host_int_bytes = 0;
5551 if (node->data.pointer_type.host_int_bytes != 0) {
5552 if ((err = token_number_literal_u32(ag, node, root_struct, &host_int_bytes,
5553 node->data.pointer_type.host_int_bytes)))
5554 {
5555 return ag->codegen->invalid_inst_src;
5556 }
5557 }
5558
5559 if (host_int_bytes != 0 && bit_offset_start >= host_int_bytes * 8) {
5560 exec_add_error_node(ag->codegen, ag->exec, node,
5561 buf_sprintf("bit offset starts after end of host integer"));
5562 return ag->codegen->invalid_inst_src;
5563 }
5564
5565 return ir_build_ptr_type(ag, scope, node, child_type, is_const, is_volatile,
5566 ptr_len, sentinel, align_value, bit_offset_start, host_int_bytes, is_allow_zero);
5567}
5568
5569static IrInstSrc *astgen_catch_unreachable(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
5570 AstNode *expr_node, LVal lval, ResultLoc *result_loc)
5571{
5572 IrInstSrc *err_union_ptr = astgen_node_extra(ag, expr_node, scope, LValPtr, nullptr);
5573 if (err_union_ptr == ag->codegen->invalid_inst_src)
5574 return ag->codegen->invalid_inst_src;
5575
5576 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(ag, scope, source_node, err_union_ptr, true, false);
5577 if (payload_ptr == ag->codegen->invalid_inst_src)
5578 return ag->codegen->invalid_inst_src;
5579
5580 if (lval == LValPtr)
5581 return payload_ptr;
5582
5583 IrInstSrc *load_ptr = ir_build_load_ptr(ag, scope, source_node, payload_ptr);
5584 return ir_expr_wrap(ag, scope, load_ptr, result_loc);
5585}
5586
5587static IrInstSrc *astgen_bool_not(Stage1AstGen *ag, Scope *scope, AstNode *node) {
5588 assert(node->type == NodeTypePrefixOpExpr);
5589 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
5590
5591 IrInstSrc *value = astgen_node(ag, expr_node, scope);
5592 if (value == ag->codegen->invalid_inst_src)
5593 return ag->codegen->invalid_inst_src;
5594
5595 return ir_build_bool_not(ag, scope, node, value);
5596}
5597
5598static IrInstSrc *astgen_prefix_op_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
5599 ResultLoc *result_loc)
5600{
5601 assert(node->type == NodeTypePrefixOpExpr);
5602
5603 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op;
5604
5605 switch (prefix_op) {
5606 case PrefixOpInvalid:
5607 zig_unreachable();
5608 case PrefixOpBoolNot:
5609 return ir_lval_wrap(ag, scope, astgen_bool_not(ag, scope, node), lval, result_loc);
5610 case PrefixOpBinNot:
5611 return ir_lval_wrap(ag, scope, astgen_prefix_op_id(ag, scope, node, IrUnOpBinNot), lval, result_loc);
5612 case PrefixOpNegation:
5613 return ir_lval_wrap(ag, scope, astgen_prefix_op_id(ag, scope, node, IrUnOpNegation), lval, result_loc);
5614 case PrefixOpNegationWrap:
5615 return ir_lval_wrap(ag, scope, astgen_prefix_op_id(ag, scope, node, IrUnOpNegationWrap), lval, result_loc);
5616 case PrefixOpOptional:
5617 return ir_lval_wrap(ag, scope, astgen_prefix_op_id(ag, scope, node, IrUnOpOptional), lval, result_loc);
5618 case PrefixOpAddrOf: {
5619 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
5620 return ir_lval_wrap(ag, scope, astgen_node_extra(ag, expr_node, scope, LValPtr, nullptr), lval, result_loc);
5621 }
5622 }
5623 zig_unreachable();
5624}
5625
5626static IrInstSrc *astgen_union_init_expr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
5627 IrInstSrc *union_type, IrInstSrc *field_name, AstNode *expr_node,
5628 LVal lval, ResultLoc *parent_result_loc)
5629{
5630 IrInstSrc *container_ptr = ir_build_resolve_result(ag, scope, source_node, parent_result_loc, union_type);
5631 IrInstSrc *field_ptr = ir_build_field_ptr_instruction(ag, scope, source_node, container_ptr,
5632 field_name, true);
5633
5634 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
5635 result_loc_inst->base.id = ResultLocIdInstruction;
5636 result_loc_inst->base.source_instruction = field_ptr;
5637 ir_ref_instruction(field_ptr, ag->current_basic_block);
5638 ir_build_reset_result(ag, scope, expr_node, &result_loc_inst->base);
5639
5640 IrInstSrc *expr_value = astgen_node_extra(ag, expr_node, scope, LValNone,
5641 &result_loc_inst->base);
5642 if (expr_value == ag->codegen->invalid_inst_src)
5643 return expr_value;
5644
5645 IrInstSrc *init_union = ir_build_union_init_named_field(ag, scope, source_node, union_type,
5646 field_name, field_ptr, container_ptr);
5647
5648 return ir_lval_wrap(ag, scope, init_union, lval, parent_result_loc);
5649}
5650
5651static IrInstSrc *astgen_container_init_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
5652 ResultLoc *parent_result_loc)
5653{
5654 assert(node->type == NodeTypeContainerInitExpr);
5655
5656 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
5657 ContainerInitKind kind = container_init_expr->kind;
5658
5659 ResultLocCast *result_loc_cast = nullptr;
5660 ResultLoc *child_result_loc;
5661 AstNode *init_array_type_source_node;
5662 if (container_init_expr->type != nullptr) {
5663 IrInstSrc *container_type;
5664 if (container_init_expr->type->type == NodeTypeInferredArrayType) {
5665 if (kind == ContainerInitKindStruct) {
5666 add_node_error(ag->codegen, container_init_expr->type,
5667 buf_sprintf("initializing array with struct syntax"));
5668 return ag->codegen->invalid_inst_src;
5669 }
5670 IrInstSrc *sentinel;
5671 if (container_init_expr->type->data.inferred_array_type.sentinel != nullptr) {
5672 sentinel = astgen_node(ag, container_init_expr->type->data.inferred_array_type.sentinel, scope);
5673 if (sentinel == ag->codegen->invalid_inst_src)
5674 return sentinel;
5675 } else {
5676 sentinel = nullptr;
5677 }
5678
5679 IrInstSrc *elem_type = astgen_node(ag,
5680 container_init_expr->type->data.inferred_array_type.child_type, scope);
5681 if (elem_type == ag->codegen->invalid_inst_src)
5682 return elem_type;
5683 size_t item_count = container_init_expr->entries.length;
5684 IrInstSrc *item_count_inst = ir_build_const_usize(ag, scope, node, item_count);
5685 container_type = ir_build_array_type(ag, scope, node, item_count_inst, sentinel, elem_type);
5686 } else {
5687 container_type = astgen_node(ag, container_init_expr->type, scope);
5688 if (container_type == ag->codegen->invalid_inst_src)
5689 return container_type;
5690 }
5691
5692 result_loc_cast = ir_build_cast_result_loc(ag, container_type, parent_result_loc);
5693 child_result_loc = &result_loc_cast->base;
5694 init_array_type_source_node = container_type->base.source_node;
5695 } else {
5696 child_result_loc = parent_result_loc;
5697 if (parent_result_loc->source_instruction != nullptr) {
5698 init_array_type_source_node = parent_result_loc->source_instruction->base.source_node;
5699 } else {
5700 init_array_type_source_node = node;
5701 }
5702 }
5703
5704 switch (kind) {
5705 case ContainerInitKindStruct: {
5706 IrInstSrc *container_ptr = ir_build_resolve_result(ag, scope, node, child_result_loc,
5707 nullptr);
5708
5709 size_t field_count = container_init_expr->entries.length;
5710 IrInstSrcContainerInitFieldsField *fields = heap::c_allocator.allocate<IrInstSrcContainerInitFieldsField>(field_count);
5711 for (size_t i = 0; i < field_count; i += 1) {
5712 AstNode *entry_node = container_init_expr->entries.at(i);
5713 assert(entry_node->type == NodeTypeStructValueField);
5714
5715 Buf *name = entry_node->data.struct_val_field.name;
5716 AstNode *expr_node = entry_node->data.struct_val_field.expr;
5717
5718 IrInstSrc *field_ptr = ir_build_field_ptr(ag, scope, entry_node, container_ptr, name, true);
5719 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
5720 result_loc_inst->base.id = ResultLocIdInstruction;
5721 result_loc_inst->base.source_instruction = field_ptr;
5722 result_loc_inst->base.allow_write_through_const = true;
5723 ir_ref_instruction(field_ptr, ag->current_basic_block);
5724 ir_build_reset_result(ag, scope, expr_node, &result_loc_inst->base);
5725
5726 IrInstSrc *expr_value = astgen_node_extra(ag, expr_node, scope, LValNone,
5727 &result_loc_inst->base);
5728 if (expr_value == ag->codegen->invalid_inst_src)
5729 return expr_value;
5730
5731 fields[i].name = name;
5732 fields[i].source_node = entry_node;
5733 fields[i].result_loc = field_ptr;
5734 }
5735 IrInstSrc *result = ir_build_container_init_fields(ag, scope, node, field_count,
5736 fields, container_ptr);
5737
5738 if (result_loc_cast != nullptr) {
5739 result = ir_build_implicit_cast(ag, scope, node, result, result_loc_cast);
5740 }
5741 return ir_lval_wrap(ag, scope, result, lval, parent_result_loc);
5742 }
5743 case ContainerInitKindArray: {
5744 size_t item_count = container_init_expr->entries.length;
5745
5746 IrInstSrc *container_ptr = ir_build_resolve_result(ag, scope, node, child_result_loc,
5747 nullptr);
5748
5749 IrInstSrc **result_locs = heap::c_allocator.allocate<IrInstSrc *>(item_count);
5750 for (size_t i = 0; i < item_count; i += 1) {
5751 AstNode *expr_node = container_init_expr->entries.at(i);
5752
5753 IrInstSrc *elem_index = ir_build_const_usize(ag, scope, expr_node, i);
5754 IrInstSrc *elem_ptr = ir_build_elem_ptr(ag, scope, expr_node, container_ptr,
5755 elem_index, false, PtrLenSingle, init_array_type_source_node);
5756 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
5757 result_loc_inst->base.id = ResultLocIdInstruction;
5758 result_loc_inst->base.source_instruction = elem_ptr;
5759 result_loc_inst->base.allow_write_through_const = true;
5760 ir_ref_instruction(elem_ptr, ag->current_basic_block);
5761 ir_build_reset_result(ag, scope, expr_node, &result_loc_inst->base);
5762
5763 IrInstSrc *expr_value = astgen_node_extra(ag, expr_node, scope, LValNone,
5764 &result_loc_inst->base);
5765 if (expr_value == ag->codegen->invalid_inst_src)
5766 return expr_value;
5767
5768 result_locs[i] = elem_ptr;
5769 }
5770 IrInstSrc *result = ir_build_container_init_list(ag, scope, node, item_count,
5771 result_locs, container_ptr, init_array_type_source_node);
5772 if (result_loc_cast != nullptr) {
5773 result = ir_build_implicit_cast(ag, scope, node, result, result_loc_cast);
5774 }
5775 return ir_lval_wrap(ag, scope, result, lval, parent_result_loc);
5776 }
5777 }
5778 zig_unreachable();
5779}
5780
5781static ResultLocVar *ir_build_var_result_loc(Stage1AstGen *ag, IrInstSrc *alloca, ZigVar *var) {
5782 ResultLocVar *result_loc_var = heap::c_allocator.create<ResultLocVar>();
5783 result_loc_var->base.id = ResultLocIdVar;
5784 result_loc_var->base.source_instruction = alloca;
5785 result_loc_var->base.allow_write_through_const = true;
5786 result_loc_var->var = var;
5787
5788 ir_build_reset_result(ag, alloca->base.scope, alloca->base.source_node, &result_loc_var->base);
5789
5790 return result_loc_var;
5791}
5792
5793static ResultLocCast *ir_build_cast_result_loc(Stage1AstGen *ag, IrInstSrc *dest_type,
5794 ResultLoc *parent_result_loc)
5795{
5796 ResultLocCast *result_loc_cast = heap::c_allocator.create<ResultLocCast>();
5797 result_loc_cast->base.id = ResultLocIdCast;
5798 result_loc_cast->base.source_instruction = dest_type;
5799 result_loc_cast->base.allow_write_through_const = parent_result_loc->allow_write_through_const;
5800 ir_ref_instruction(dest_type, ag->current_basic_block);
5801 result_loc_cast->parent = parent_result_loc;
5802
5803 ir_build_reset_result(ag, dest_type->base.scope, dest_type->base.source_node, &result_loc_cast->base);
5804
5805 return result_loc_cast;
5806}
5807
5808static void build_decl_var_and_init(Stage1AstGen *ag, Scope *scope, AstNode *source_node, ZigVar *var,
5809 IrInstSrc *init, const char *name_hint, IrInstSrc *is_comptime)
5810{
5811 IrInstSrc *alloca = ir_build_alloca_src(ag, scope, source_node, nullptr, name_hint, is_comptime);
5812 ResultLocVar *var_result_loc = ir_build_var_result_loc(ag, alloca, var);
5813 ir_build_end_expr(ag, scope, source_node, init, &var_result_loc->base);
5814 ir_build_var_decl_src(ag, scope, source_node, var, nullptr, alloca);
5815}
5816
5817static IrInstSrc *astgen_var_decl(Stage1AstGen *ag, Scope *scope, AstNode *node) {
5818 assert(node->type == NodeTypeVariableDeclaration);
5819
5820 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration;
5821
5822 if (buf_eql_str(variable_declaration->symbol, "_")) {
5823 add_node_error(ag->codegen, node, buf_sprintf("`_` is not a declarable symbol"));
5824 return ag->codegen->invalid_inst_src;
5825 }
5826
5827 // Used for the type expr and the align expr
5828 Scope *comptime_scope = create_comptime_scope(ag->codegen, node, scope);
5829
5830 IrInstSrc *type_instruction;
5831 if (variable_declaration->type != nullptr) {
5832 type_instruction = astgen_node(ag, variable_declaration->type, comptime_scope);
5833 if (type_instruction == ag->codegen->invalid_inst_src)
5834 return type_instruction;
5835 } else {
5836 type_instruction = nullptr;
5837 }
5838
5839 bool is_shadowable = false;
5840 bool is_const = variable_declaration->is_const;
5841 bool is_extern = variable_declaration->is_extern;
5842
5843 bool is_comptime_scalar = ir_should_inline(ag->exec, scope) || variable_declaration->is_comptime;
5844 IrInstSrc *is_comptime = ir_build_const_bool(ag, scope, node, is_comptime_scalar);
5845 ZigVar *var = ir_create_var(ag, node, scope, variable_declaration->symbol,
5846 is_const, is_const, is_shadowable, is_comptime);
5847 // we detect IrInstSrcDeclVar in gen_block to make sure the next node
5848 // is inside var->child_scope
5849
5850 if (!is_extern && !variable_declaration->expr) {
5851 var->var_type = ag->codegen->builtin_types.entry_invalid;
5852 add_node_error(ag->codegen, node, buf_sprintf("variables must be initialized"));
5853 return ag->codegen->invalid_inst_src;
5854 }
5855
5856 IrInstSrc *align_value = nullptr;
5857 if (variable_declaration->align_expr != nullptr) {
5858 align_value = astgen_node(ag, variable_declaration->align_expr, comptime_scope);
5859 if (align_value == ag->codegen->invalid_inst_src)
5860 return align_value;
5861 }
5862
5863 if (variable_declaration->section_expr != nullptr) {
5864 add_node_error(ag->codegen, variable_declaration->section_expr,
5865 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol)));
5866 }
5867
5868 // Parser should ensure that this never happens
5869 assert(variable_declaration->threadlocal_tok == 0);
5870
5871 IrInstSrc *alloca = ir_build_alloca_src(ag, scope, node, align_value,
5872 buf_ptr(variable_declaration->symbol), is_comptime);
5873
5874 // Create a result location for the initialization expression.
5875 ResultLocVar *result_loc_var = ir_build_var_result_loc(ag, alloca, var);
5876 ResultLoc *init_result_loc;
5877 ResultLocCast *result_loc_cast;
5878 if (type_instruction != nullptr) {
5879 result_loc_cast = ir_build_cast_result_loc(ag, type_instruction, &result_loc_var->base);
5880 init_result_loc = &result_loc_cast->base;
5881 } else {
5882 result_loc_cast = nullptr;
5883 init_result_loc = &result_loc_var->base;
5884 }
5885
5886 Scope *init_scope = is_comptime_scalar ?
5887 create_comptime_scope(ag->codegen, variable_declaration->expr, scope) : scope;
5888
5889 // Temporarily set the name of the Stage1Zir to the VariableDeclaration
5890 // so that the struct or enum from the init expression inherits the name.
5891 Buf *old_exec_name = ag->exec->name;
5892 ag->exec->name = variable_declaration->symbol;
5893 IrInstSrc *init_value = astgen_node_extra(ag, variable_declaration->expr, init_scope,
5894 LValNone, init_result_loc);
5895 ag->exec->name = old_exec_name;
5896
5897 if (init_value == ag->codegen->invalid_inst_src)
5898 return ag->codegen->invalid_inst_src;
5899
5900 if (result_loc_cast != nullptr) {
5901 IrInstSrc *implicit_cast = ir_build_implicit_cast(ag, scope, init_value->base.source_node,
5902 init_value, result_loc_cast);
5903 ir_build_end_expr(ag, scope, node, implicit_cast, &result_loc_var->base);
5904 }
5905
5906 return ir_build_var_decl_src(ag, scope, node, var, align_value, alloca);
5907}
5908
5909static IrInstSrc *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
5910 ResultLoc *result_loc)
5911{
5912 assert(node->type == NodeTypeWhileExpr);
5913
5914 AstNode *continue_expr_node = node->data.while_expr.continue_expr;
5915 AstNode *else_node = node->data.while_expr.else_node;
5916
5917 Stage1ZirBasicBlock *cond_block = ir_create_basic_block(ag, scope, "WhileCond");
5918 Stage1ZirBasicBlock *body_block = ir_create_basic_block(ag, scope, "WhileBody");
5919 Stage1ZirBasicBlock *continue_block = continue_expr_node ?
5920 ir_create_basic_block(ag, scope, "WhileContinue") : cond_block;
5921 Stage1ZirBasicBlock *end_block = ir_create_basic_block(ag, scope, "WhileEnd");
5922 Stage1ZirBasicBlock *else_block = else_node ?
5923 ir_create_basic_block(ag, scope, "WhileElse") : end_block;
5924
5925 IrInstSrc *is_comptime = ir_build_const_bool(ag, scope, node,
5926 ir_should_inline(ag->exec, scope) || node->data.while_expr.is_inline);
5927 ir_build_br(ag, scope, node, cond_block, is_comptime);
5928
5929 Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, scope, is_comptime);
5930 Buf *var_symbol = node->data.while_expr.var_symbol;
5931 Buf *err_symbol = node->data.while_expr.err_symbol;
5932 if (err_symbol != nullptr) {
5933 ir_set_cursor_at_end_and_append_block(ag, cond_block);
5934
5935 Scope *payload_scope;
5936 AstNode *symbol_node = node; // TODO make more accurate
5937 ZigVar *payload_var;
5938 if (var_symbol) {
5939 // TODO make it an error to write to payload variable
5940 payload_var = ir_create_var(ag, symbol_node, subexpr_scope, var_symbol,
5941 true, false, false, is_comptime);
5942 payload_scope = payload_var->child_scope;
5943 } else {
5944 payload_scope = subexpr_scope;
5945 }
5946 ScopeExpr *spill_scope = create_expr_scope(ag->codegen, node, payload_scope);
5947 IrInstSrc *err_val_ptr = astgen_node_extra(ag, node->data.while_expr.condition, subexpr_scope,
5948 LValPtr, nullptr);
5949 if (err_val_ptr == ag->codegen->invalid_inst_src)
5950 return err_val_ptr;
5951 IrInstSrc *is_err = ir_build_test_err_src(ag, scope, node->data.while_expr.condition, err_val_ptr,
5952 true, false);
5953 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
5954 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(ag, scope, node));
5955 IrInstSrc *cond_br_inst;
5956 if (!instr_is_unreachable(is_err)) {
5957 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_err,
5958 else_block, body_block, is_comptime);
5959 cond_br_inst->is_gen = true;
5960 } else {
5961 // for the purposes of the source instruction to ir_build_result_peers
5962 cond_br_inst = ag->current_basic_block->instruction_list.last();
5963 }
5964
5965 ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, result_loc,
5966 is_comptime);
5967
5968 ir_set_cursor_at_end_and_append_block(ag, body_block);
5969 if (var_symbol) {
5970 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(ag, &spill_scope->base, symbol_node,
5971 err_val_ptr, false, false);
5972 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ?
5973 payload_ptr : ir_build_load_ptr(ag, &spill_scope->base, symbol_node, payload_ptr);
5974 build_decl_var_and_init(ag, payload_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime);
5975 }
5976
5977 ZigList<IrInstSrc *> incoming_values = {0};
5978 ZigList<Stage1ZirBasicBlock *> incoming_blocks = {0};
5979
5980 if (is_duplicate_label(ag->codegen, payload_scope, node, node->data.while_expr.name))
5981 return ag->codegen->invalid_inst_src;
5982
5983 ScopeLoop *loop_scope = create_loop_scope(ag->codegen, node, payload_scope);
5984 loop_scope->break_block = end_block;
5985 loop_scope->continue_block = continue_block;
5986 loop_scope->is_comptime = is_comptime;
5987 loop_scope->incoming_blocks = &incoming_blocks;
5988 loop_scope->incoming_values = &incoming_values;
5989 loop_scope->lval = lval;
5990 loop_scope->peer_parent = peer_parent;
5991 loop_scope->spill_scope = spill_scope;
5992
5993 // Note the body block of the loop is not the place that lval and result_loc are used -
5994 // it's actually in break statements, handled similarly to return statements.
5995 // That is why we set those values in loop_scope above and not in this astgen_node call.
5996 IrInstSrc *body_result = astgen_node(ag, node->data.while_expr.body, &loop_scope->base);
5997 if (body_result == ag->codegen->invalid_inst_src)
5998 return body_result;
5999
6000 if (loop_scope->name != nullptr && loop_scope->name_used == false) {
6001 add_node_error(ag->codegen, node, buf_sprintf("unused while label"));
6002 }
6003
6004 if (!instr_is_unreachable(body_result)) {
6005 ir_mark_gen(ir_build_check_statement_is_void(ag, payload_scope, node->data.while_expr.body, body_result));
6006 ir_mark_gen(ir_build_br(ag, payload_scope, node, continue_block, is_comptime));
6007 }
6008
6009 if (continue_expr_node) {
6010 ir_set_cursor_at_end_and_append_block(ag, continue_block);
6011 IrInstSrc *expr_result = astgen_node(ag, continue_expr_node, payload_scope);
6012 if (expr_result == ag->codegen->invalid_inst_src)
6013 return expr_result;
6014 if (!instr_is_unreachable(expr_result)) {
6015 ir_mark_gen(ir_build_check_statement_is_void(ag, payload_scope, continue_expr_node, expr_result));
6016 ir_mark_gen(ir_build_br(ag, payload_scope, node, cond_block, is_comptime));
6017 }
6018 }
6019
6020 ir_set_cursor_at_end_and_append_block(ag, else_block);
6021 assert(else_node != nullptr);
6022
6023 // TODO make it an error to write to error variable
6024 AstNode *err_symbol_node = else_node; // TODO make more accurate
6025 ZigVar *err_var = ir_create_var(ag, err_symbol_node, scope, err_symbol,
6026 true, false, false, is_comptime);
6027 Scope *err_scope = err_var->child_scope;
6028 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(ag, err_scope, err_symbol_node, err_val_ptr);
6029 IrInstSrc *err_value = ir_build_load_ptr(ag, err_scope, err_symbol_node, err_ptr);
6030 build_decl_var_and_init(ag, err_scope, err_symbol_node, err_var, err_value, buf_ptr(err_symbol), is_comptime);
6031
6032 if (peer_parent->peers.length != 0) {
6033 peer_parent->peers.last()->next_bb = else_block;
6034 }
6035 ResultLocPeer *peer_result = create_peer_result(peer_parent);
6036 peer_parent->peers.append(peer_result);
6037 IrInstSrc *else_result = astgen_node_extra(ag, else_node, err_scope, lval, &peer_result->base);
6038 if (else_result == ag->codegen->invalid_inst_src)
6039 return else_result;
6040 if (!instr_is_unreachable(else_result))
6041 ir_mark_gen(ir_build_br(ag, scope, node, end_block, is_comptime));
6042 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6043 ir_set_cursor_at_end_and_append_block(ag, end_block);
6044 if (else_result) {
6045 incoming_blocks.append(after_else_block);
6046 incoming_values.append(else_result);
6047 } else {
6048 incoming_blocks.append(after_cond_block);
6049 incoming_values.append(void_else_result);
6050 }
6051 if (peer_parent->peers.length != 0) {
6052 peer_parent->peers.last()->next_bb = end_block;
6053 }
6054
6055 IrInstSrc *phi = ir_build_phi(ag, scope, node, incoming_blocks.length,
6056 incoming_blocks.items, incoming_values.items, peer_parent);
6057 return ir_expr_wrap(ag, scope, phi, result_loc);
6058 } else if (var_symbol != nullptr) {
6059 ir_set_cursor_at_end_and_append_block(ag, cond_block);
6060 Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, scope, is_comptime);
6061 // TODO make it an error to write to payload variable
6062 AstNode *symbol_node = node; // TODO make more accurate
6063
6064 ZigVar *payload_var = ir_create_var(ag, symbol_node, subexpr_scope, var_symbol,
6065 true, false, false, is_comptime);
6066 Scope *child_scope = payload_var->child_scope;
6067 ScopeExpr *spill_scope = create_expr_scope(ag->codegen, node, child_scope);
6068 IrInstSrc *maybe_val_ptr = astgen_node_extra(ag, node->data.while_expr.condition, subexpr_scope,
6069 LValPtr, nullptr);
6070 if (maybe_val_ptr == ag->codegen->invalid_inst_src)
6071 return maybe_val_ptr;
6072 IrInstSrc *maybe_val = ir_build_load_ptr(ag, scope, node->data.while_expr.condition, maybe_val_ptr);
6073 IrInstSrc *is_non_null = ir_build_test_non_null_src(ag, scope, node->data.while_expr.condition, maybe_val);
6074 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
6075 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(ag, scope, node));
6076 IrInstSrc *cond_br_inst;
6077 if (!instr_is_unreachable(is_non_null)) {
6078 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_non_null,
6079 body_block, else_block, is_comptime);
6080 cond_br_inst->is_gen = true;
6081 } else {
6082 // for the purposes of the source instruction to ir_build_result_peers
6083 cond_br_inst = ag->current_basic_block->instruction_list.last();
6084 }
6085
6086 ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, result_loc,
6087 is_comptime);
6088
6089 ir_set_cursor_at_end_and_append_block(ag, body_block);
6090 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(ag, &spill_scope->base, symbol_node, maybe_val_ptr, false);
6091 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ?
6092 payload_ptr : ir_build_load_ptr(ag, &spill_scope->base, symbol_node, payload_ptr);
6093 build_decl_var_and_init(ag, child_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime);
6094
6095 ZigList<IrInstSrc *> incoming_values = {0};
6096 ZigList<Stage1ZirBasicBlock *> incoming_blocks = {0};
6097
6098 if (is_duplicate_label(ag->codegen, child_scope, node, node->data.while_expr.name))
6099 return ag->codegen->invalid_inst_src;
6100
6101 ScopeLoop *loop_scope = create_loop_scope(ag->codegen, node, child_scope);
6102 loop_scope->break_block = end_block;
6103 loop_scope->continue_block = continue_block;
6104 loop_scope->is_comptime = is_comptime;
6105 loop_scope->incoming_blocks = &incoming_blocks;
6106 loop_scope->incoming_values = &incoming_values;
6107 loop_scope->lval = lval;
6108 loop_scope->peer_parent = peer_parent;
6109 loop_scope->spill_scope = spill_scope;
6110
6111 // Note the body block of the loop is not the place that lval and result_loc are used -
6112 // it's actually in break statements, handled similarly to return statements.
6113 // That is why we set those values in loop_scope above and not in this astgen_node call.
6114 IrInstSrc *body_result = astgen_node(ag, node->data.while_expr.body, &loop_scope->base);
6115 if (body_result == ag->codegen->invalid_inst_src)
6116 return body_result;
6117
6118 if (loop_scope->name != nullptr && loop_scope->name_used == false) {
6119 add_node_error(ag->codegen, node, buf_sprintf("unused while label"));
6120 }
6121
6122 if (!instr_is_unreachable(body_result)) {
6123 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, node->data.while_expr.body, body_result));
6124 ir_mark_gen(ir_build_br(ag, child_scope, node, continue_block, is_comptime));
6125 }
6126
6127 if (continue_expr_node) {
6128 ir_set_cursor_at_end_and_append_block(ag, continue_block);
6129 IrInstSrc *expr_result = astgen_node(ag, continue_expr_node, child_scope);
6130 if (expr_result == ag->codegen->invalid_inst_src)
6131 return expr_result;
6132 if (!instr_is_unreachable(expr_result)) {
6133 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, continue_expr_node, expr_result));
6134 ir_mark_gen(ir_build_br(ag, child_scope, node, cond_block, is_comptime));
6135 }
6136 }
6137
6138 IrInstSrc *else_result = nullptr;
6139 if (else_node) {
6140 ir_set_cursor_at_end_and_append_block(ag, else_block);
6141
6142 if (peer_parent->peers.length != 0) {
6143 peer_parent->peers.last()->next_bb = else_block;
6144 }
6145 ResultLocPeer *peer_result = create_peer_result(peer_parent);
6146 peer_parent->peers.append(peer_result);
6147 else_result = astgen_node_extra(ag, else_node, scope, lval, &peer_result->base);
6148 if (else_result == ag->codegen->invalid_inst_src)
6149 return else_result;
6150 if (!instr_is_unreachable(else_result))
6151 ir_mark_gen(ir_build_br(ag, scope, node, end_block, is_comptime));
6152 }
6153 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6154 ir_set_cursor_at_end_and_append_block(ag, end_block);
6155 if (else_result) {
6156 incoming_blocks.append(after_else_block);
6157 incoming_values.append(else_result);
6158 } else {
6159 incoming_blocks.append(after_cond_block);
6160 incoming_values.append(void_else_result);
6161 }
6162 if (peer_parent->peers.length != 0) {
6163 peer_parent->peers.last()->next_bb = end_block;
6164 }
6165
6166 IrInstSrc *phi = ir_build_phi(ag, scope, node, incoming_blocks.length,
6167 incoming_blocks.items, incoming_values.items, peer_parent);
6168 return ir_expr_wrap(ag, scope, phi, result_loc);
6169 } else {
6170 ir_set_cursor_at_end_and_append_block(ag, cond_block);
6171 IrInstSrc *cond_val = astgen_node(ag, node->data.while_expr.condition, scope);
6172 if (cond_val == ag->codegen->invalid_inst_src)
6173 return cond_val;
6174 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
6175 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(ag, scope, node));
6176 IrInstSrc *cond_br_inst;
6177 if (!instr_is_unreachable(cond_val)) {
6178 cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, cond_val,
6179 body_block, else_block, is_comptime);
6180 cond_br_inst->is_gen = true;
6181 } else {
6182 // for the purposes of the source instruction to ir_build_result_peers
6183 cond_br_inst = ag->current_basic_block->instruction_list.last();
6184 }
6185
6186 ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, result_loc,
6187 is_comptime);
6188 ir_set_cursor_at_end_and_append_block(ag, body_block);
6189
6190 ZigList<IrInstSrc *> incoming_values = {0};
6191 ZigList<Stage1ZirBasicBlock *> incoming_blocks = {0};
6192
6193 Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, scope, is_comptime);
6194
6195 if (is_duplicate_label(ag->codegen, subexpr_scope, node, node->data.while_expr.name))
6196 return ag->codegen->invalid_inst_src;
6197
6198 ScopeLoop *loop_scope = create_loop_scope(ag->codegen, node, subexpr_scope);
6199 loop_scope->break_block = end_block;
6200 loop_scope->continue_block = continue_block;
6201 loop_scope->is_comptime = is_comptime;
6202 loop_scope->incoming_blocks = &incoming_blocks;
6203 loop_scope->incoming_values = &incoming_values;
6204 loop_scope->lval = lval;
6205 loop_scope->peer_parent = peer_parent;
6206
6207 // Note the body block of the loop is not the place that lval and result_loc are used -
6208 // it's actually in break statements, handled similarly to return statements.
6209 // That is why we set those values in loop_scope above and not in this astgen_node call.
6210 IrInstSrc *body_result = astgen_node(ag, node->data.while_expr.body, &loop_scope->base);
6211 if (body_result == ag->codegen->invalid_inst_src)
6212 return body_result;
6213
6214 if (loop_scope->name != nullptr && loop_scope->name_used == false) {
6215 add_node_error(ag->codegen, node, buf_sprintf("unused while label"));
6216 }
6217
6218 if (!instr_is_unreachable(body_result)) {
6219 ir_mark_gen(ir_build_check_statement_is_void(ag, scope, node->data.while_expr.body, body_result));
6220 ir_mark_gen(ir_build_br(ag, scope, node, continue_block, is_comptime));
6221 }
6222
6223 if (continue_expr_node) {
6224 ir_set_cursor_at_end_and_append_block(ag, continue_block);
6225 IrInstSrc *expr_result = astgen_node(ag, continue_expr_node, subexpr_scope);
6226 if (expr_result == ag->codegen->invalid_inst_src)
6227 return expr_result;
6228 if (!instr_is_unreachable(expr_result)) {
6229 ir_mark_gen(ir_build_check_statement_is_void(ag, scope, continue_expr_node, expr_result));
6230 ir_mark_gen(ir_build_br(ag, scope, node, cond_block, is_comptime));
6231 }
6232 }
6233
6234 IrInstSrc *else_result = nullptr;
6235 if (else_node) {
6236 ir_set_cursor_at_end_and_append_block(ag, else_block);
6237
6238 if (peer_parent->peers.length != 0) {
6239 peer_parent->peers.last()->next_bb = else_block;
6240 }
6241 ResultLocPeer *peer_result = create_peer_result(peer_parent);
6242 peer_parent->peers.append(peer_result);
6243
6244 else_result = astgen_node_extra(ag, else_node, subexpr_scope, lval, &peer_result->base);
6245 if (else_result == ag->codegen->invalid_inst_src)
6246 return else_result;
6247 if (!instr_is_unreachable(else_result))
6248 ir_mark_gen(ir_build_br(ag, scope, node, end_block, is_comptime));
6249 }
6250 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6251 ir_set_cursor_at_end_and_append_block(ag, end_block);
6252 if (else_result) {
6253 incoming_blocks.append(after_else_block);
6254 incoming_values.append(else_result);
6255 } else {
6256 incoming_blocks.append(after_cond_block);
6257 incoming_values.append(void_else_result);
6258 }
6259 if (peer_parent->peers.length != 0) {
6260 peer_parent->peers.last()->next_bb = end_block;
6261 }
6262
6263 IrInstSrc *phi = ir_build_phi(ag, scope, node, incoming_blocks.length,
6264 incoming_blocks.items, incoming_values.items, peer_parent);
6265 return ir_expr_wrap(ag, scope, phi, result_loc);
6266 }
6267}
6268
6269static IrInstSrc *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode *node, LVal lval,
6270 ResultLoc *result_loc)
6271{
6272 assert(node->type == NodeTypeForExpr);
6273
6274 AstNode *array_node = node->data.for_expr.array_expr;
6275 AstNode *elem_node = node->data.for_expr.elem_node;
6276 AstNode *index_node = node->data.for_expr.index_node;
6277 AstNode *body_node = node->data.for_expr.body;
6278 AstNode *else_node = node->data.for_expr.else_node;
6279
6280 if (!elem_node) {
6281 add_node_error(ag->codegen, node, buf_sprintf("for loop expression missing element parameter"));
6282 return ag->codegen->invalid_inst_src;
6283 }
6284 assert(elem_node->type == NodeTypeIdentifier);
6285
6286 ScopeExpr *spill_scope = create_expr_scope(ag->codegen, node, parent_scope);
6287
6288 IrInstSrc *array_val_ptr = astgen_node_extra(ag, array_node, &spill_scope->base, LValPtr, nullptr);
6289 if (array_val_ptr == ag->codegen->invalid_inst_src)
6290 return array_val_ptr;
6291
6292 IrInstSrc *is_comptime = ir_build_const_bool(ag, parent_scope, node,
6293 ir_should_inline(ag->exec, parent_scope) || node->data.for_expr.is_inline);
6294
6295 AstNode *index_var_source_node;
6296 ZigVar *index_var;
6297 const char *index_var_name;
6298 if (index_node) {
6299 index_var_source_node = index_node;
6300 Buf *index_var_name_buf = node_identifier_buf(index_node);
6301 index_var = ir_create_var(ag, index_node, parent_scope, index_var_name_buf, true, false, false, is_comptime);
6302 index_var_name = buf_ptr(index_var_name_buf);
6303 } else {
6304 index_var_source_node = node;
6305 index_var = ir_create_var(ag, node, parent_scope, nullptr, true, false, true, is_comptime);
6306 index_var_name = "i";
6307 }
6308
6309 IrInstSrc *zero = ir_build_const_usize(ag, parent_scope, node, 0);
6310 build_decl_var_and_init(ag, parent_scope, index_var_source_node, index_var, zero, index_var_name, is_comptime);
6311 parent_scope = index_var->child_scope;
6312
6313 IrInstSrc *one = ir_build_const_usize(ag, parent_scope, node, 1);
6314 IrInstSrc *index_ptr = ir_build_var_ptr(ag, parent_scope, node, index_var);
6315
6316
6317 Stage1ZirBasicBlock *cond_block = ir_create_basic_block(ag, parent_scope, "ForCond");
6318 Stage1ZirBasicBlock *body_block = ir_create_basic_block(ag, parent_scope, "ForBody");
6319 Stage1ZirBasicBlock *end_block = ir_create_basic_block(ag, parent_scope, "ForEnd");
6320 Stage1ZirBasicBlock *else_block = else_node ? ir_create_basic_block(ag, parent_scope, "ForElse") : end_block;
6321 Stage1ZirBasicBlock *continue_block = ir_create_basic_block(ag, parent_scope, "ForContinue");
6322
6323 Buf *len_field_name = buf_create_from_str("len");
6324 IrInstSrc *len_ref = ir_build_field_ptr(ag, parent_scope, node, array_val_ptr, len_field_name, false);
6325 IrInstSrc *len_val = ir_build_load_ptr(ag, &spill_scope->base, node, len_ref);
6326 ir_build_br(ag, parent_scope, node, cond_block, is_comptime);
6327
6328 ir_set_cursor_at_end_and_append_block(ag, cond_block);
6329 IrInstSrc *index_val = ir_build_load_ptr(ag, &spill_scope->base, node, index_ptr);
6330 IrInstSrc *cond = ir_build_bin_op(ag, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
6331 Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
6332 IrInstSrc *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(ag, parent_scope, node));
6333 IrInstSrc *cond_br_inst = ir_mark_gen(ir_build_cond_br(ag, parent_scope, node, cond,
6334 body_block, else_block, is_comptime));
6335
6336 ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, result_loc, is_comptime);
6337
6338 ir_set_cursor_at_end_and_append_block(ag, body_block);
6339 IrInstSrc *elem_ptr = ir_build_elem_ptr(ag, &spill_scope->base, node, array_val_ptr, index_val,
6340 false, PtrLenSingle, nullptr);
6341 // TODO make it an error to write to element variable or i variable.
6342 Buf *elem_var_name = node_identifier_buf(elem_node);
6343 ZigVar *elem_var = ir_create_var(ag, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime);
6344 Scope *child_scope = elem_var->child_scope;
6345
6346 IrInstSrc *elem_value = node->data.for_expr.elem_is_ptr ?
6347 elem_ptr : ir_build_load_ptr(ag, &spill_scope->base, elem_node, elem_ptr);
6348 build_decl_var_and_init(ag, parent_scope, elem_node, elem_var, elem_value, buf_ptr(elem_var_name), is_comptime);
6349
6350 if (is_duplicate_label(ag->codegen, child_scope, node, node->data.for_expr.name))
6351 return ag->codegen->invalid_inst_src;
6352
6353 ZigList<IrInstSrc *> incoming_values = {0};
6354 ZigList<Stage1ZirBasicBlock *> incoming_blocks = {0};
6355 ScopeLoop *loop_scope = create_loop_scope(ag->codegen, node, child_scope);
6356 loop_scope->break_block = end_block;
6357 loop_scope->continue_block = continue_block;
6358 loop_scope->is_comptime = is_comptime;
6359 loop_scope->incoming_blocks = &incoming_blocks;
6360 loop_scope->incoming_values = &incoming_values;
6361 loop_scope->lval = LValNone;
6362 loop_scope->peer_parent = peer_parent;
6363 loop_scope->spill_scope = spill_scope;
6364
6365 // Note the body block of the loop is not the place that lval and result_loc are used -
6366 // it's actually in break statements, handled similarly to return statements.
6367 // That is why we set those values in loop_scope above and not in this astgen_node call.
6368 IrInstSrc *body_result = astgen_node(ag, body_node, &loop_scope->base);
6369 if (body_result == ag->codegen->invalid_inst_src)
6370 return ag->codegen->invalid_inst_src;
6371
6372 if (loop_scope->name != nullptr && loop_scope->name_used == false) {
6373 add_node_error(ag->codegen, node, buf_sprintf("unused for label"));
6374 }
6375
6376 if (!instr_is_unreachable(body_result)) {
6377 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, node->data.for_expr.body, body_result));
6378 ir_mark_gen(ir_build_br(ag, child_scope, node, continue_block, is_comptime));
6379 }
6380
6381 ir_set_cursor_at_end_and_append_block(ag, continue_block);
6382 IrInstSrc *new_index_val = ir_build_bin_op(ag, child_scope, node, IrBinOpAdd, index_val, one, false);
6383 ir_build_store_ptr(ag, child_scope, node, index_ptr, new_index_val)->allow_write_through_const = true;
6384 ir_build_br(ag, child_scope, node, cond_block, is_comptime);
6385
6386 IrInstSrc *else_result = nullptr;
6387 if (else_node) {
6388 ir_set_cursor_at_end_and_append_block(ag, else_block);
6389
6390 if (peer_parent->peers.length != 0) {
6391 peer_parent->peers.last()->next_bb = else_block;
6392 }
6393 ResultLocPeer *peer_result = create_peer_result(peer_parent);
6394 peer_parent->peers.append(peer_result);
6395 else_result = astgen_node_extra(ag, else_node, parent_scope, LValNone, &peer_result->base);
6396 if (else_result == ag->codegen->invalid_inst_src)
6397 return else_result;
6398 if (!instr_is_unreachable(else_result))
6399 ir_mark_gen(ir_build_br(ag, parent_scope, node, end_block, is_comptime));
6400 }
6401 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6402 ir_set_cursor_at_end_and_append_block(ag, end_block);
6403
6404 if (else_result) {
6405 incoming_blocks.append(after_else_block);
6406 incoming_values.append(else_result);
6407 } else {
6408 incoming_blocks.append(after_cond_block);
6409 incoming_values.append(void_else_value);
6410 }
6411 if (peer_parent->peers.length != 0) {
6412 peer_parent->peers.last()->next_bb = end_block;
6413 }
6414
6415 IrInstSrc *phi = ir_build_phi(ag, parent_scope, node, incoming_blocks.length,
6416 incoming_blocks.items, incoming_values.items, peer_parent);
6417 return ir_lval_wrap(ag, parent_scope, phi, lval, result_loc);
6418}
6419
6420static IrInstSrc *astgen_bool_literal(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6421 assert(node->type == NodeTypeBoolLiteral);
6422 return ir_build_const_bool(ag, scope, node, node->data.bool_literal.value);
6423}
6424
6425static IrInstSrc *astgen_enum_literal(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6426 assert(node->type == NodeTypeEnumLiteral);
6427 // Currently, stage1 runs astgen for every comptime function call,
6428 // resulting the allocation here wasting memory. As a workaround until
6429 // the code is adjusted to make astgen run only once per source node,
6430 // we memoize the result into the AST here.
6431 if (node->data.enum_literal.name == nullptr) {
6432 RootStruct *root_struct = node->owner->data.structure.root_struct;
6433 node->data.enum_literal.name = token_identifier_buf(root_struct, node->main_token + 1);
6434 }
6435 return ir_build_const_enum_literal(ag, scope, node, node->data.enum_literal.name);
6436}
6437
6438static IrInstSrc *astgen_string_literal(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6439 Error err;
6440 assert(node->type == NodeTypeStringLiteral);
6441
6442 RootStruct *root_struct = node->owner->data.structure.root_struct;
6443 const char *source = buf_ptr(root_struct->source_code);
6444
6445 TokenId *token_ids = root_struct->token_ids;
6446
6447 Buf *str = buf_alloc();
6448 if (token_ids[node->main_token] == TokenIdStringLiteral) {
6449 size_t byte_offset = root_struct->token_locs[node->main_token].offset;
6450 size_t bad_index;
6451 if ((err = source_string_literal_buf(source + byte_offset, str, &bad_index))) {
6452 add_token_error_offset(ag->codegen, node->owner, node->main_token,
6453 buf_create_from_str("invalid string literal character"), bad_index);
6454 }
6455 src_assert(source[byte_offset] == '"', node);
6456 byte_offset += 1;
6457 } else if (token_ids[node->main_token] == TokenIdMultilineStringLiteralLine) {
6458 TokenIndex tok_index = node->main_token;
6459 bool first = true;
6460 for (;token_ids[tok_index] == TokenIdMultilineStringLiteralLine; tok_index += 1) {
6461 size_t byte_offset = root_struct->token_locs[tok_index].offset;
6462 size_t end = byte_offset;
6463 while (source[end] != 0 && source[end] != '\n') {
6464 end += 1;
6465 }
6466 if (!first) {
6467 buf_append_char(str, '\n');
6468 } else {
6469 first = false;
6470 }
6471 buf_append_mem(str, source + byte_offset + 2, end - byte_offset - 2);
6472 }
6473 } else {
6474 zig_unreachable();
6475 }
6476
6477 return ir_build_const_str_lit(ag, scope, node, str);
6478}
6479
6480static IrInstSrc *astgen_array_type(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6481 assert(node->type == NodeTypeArrayType);
6482
6483 AstNode *size_node = node->data.array_type.size;
6484 AstNode *child_type_node = node->data.array_type.child_type;
6485 bool is_const = node->data.array_type.is_const;
6486 bool is_volatile = node->data.array_type.is_volatile;
6487 bool is_allow_zero = node->data.array_type.allow_zero_token != 0;
6488 AstNode *sentinel_expr = node->data.array_type.sentinel;
6489 AstNode *align_expr = node->data.array_type.align_expr;
6490
6491 Scope *comptime_scope = create_comptime_scope(ag->codegen, node, scope);
6492
6493 IrInstSrc *sentinel;
6494 if (sentinel_expr != nullptr) {
6495 sentinel = astgen_node(ag, sentinel_expr, comptime_scope);
6496 if (sentinel == ag->codegen->invalid_inst_src)
6497 return sentinel;
6498 } else {
6499 sentinel = nullptr;
6500 }
6501
6502 if (size_node) {
6503 if (is_const) {
6504 add_node_error(ag->codegen, node, buf_create_from_str("const qualifier invalid on array type"));
6505 return ag->codegen->invalid_inst_src;
6506 }
6507 if (is_volatile) {
6508 add_node_error(ag->codegen, node, buf_create_from_str("volatile qualifier invalid on array type"));
6509 return ag->codegen->invalid_inst_src;
6510 }
6511 if (is_allow_zero) {
6512 add_node_error(ag->codegen, node, buf_create_from_str("allowzero qualifier invalid on array type"));
6513 return ag->codegen->invalid_inst_src;
6514 }
6515 if (align_expr != nullptr) {
6516 add_node_error(ag->codegen, node, buf_create_from_str("align qualifier invalid on array type"));
6517 return ag->codegen->invalid_inst_src;
6518 }
6519
6520 IrInstSrc *size_value = astgen_node(ag, size_node, comptime_scope);
6521 if (size_value == ag->codegen->invalid_inst_src)
6522 return size_value;
6523
6524 IrInstSrc *child_type = astgen_node(ag, child_type_node, comptime_scope);
6525 if (child_type == ag->codegen->invalid_inst_src)
6526 return child_type;
6527
6528 return ir_build_array_type(ag, scope, node, size_value, sentinel, child_type);
6529 } else {
6530 IrInstSrc *align_value;
6531 if (align_expr != nullptr) {
6532 align_value = astgen_node(ag, align_expr, comptime_scope);
6533 if (align_value == ag->codegen->invalid_inst_src)
6534 return align_value;
6535 } else {
6536 align_value = nullptr;
6537 }
6538
6539 IrInstSrc *child_type = astgen_node(ag, child_type_node, comptime_scope);
6540 if (child_type == ag->codegen->invalid_inst_src)
6541 return child_type;
6542
6543 return ir_build_slice_type(ag, scope, node, child_type, is_const, is_volatile, sentinel,
6544 align_value, is_allow_zero);
6545 }
6546}
6547
6548static IrInstSrc *astgen_anyframe_type(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6549 assert(node->type == NodeTypeAnyFrameType);
6550
6551 AstNode *payload_type_node = node->data.anyframe_type.payload_type;
6552 IrInstSrc *payload_type_value = nullptr;
6553
6554 if (payload_type_node != nullptr) {
6555 payload_type_value = astgen_node(ag, payload_type_node, scope);
6556 if (payload_type_value == ag->codegen->invalid_inst_src)
6557 return payload_type_value;
6558
6559 }
6560
6561 return ir_build_anyframe_type(ag, scope, node, payload_type_value);
6562}
6563
6564static IrInstSrc *astgen_undefined_literal(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6565 assert(node->type == NodeTypeUndefinedLiteral);
6566 return ir_build_const_undefined(ag, scope, node);
6567}
6568
6569static IrInstSrc *astgen_asm_expr(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6570 assert(node->type == NodeTypeAsmExpr);
6571 AstNodeAsmExpr *asm_expr = &node->data.asm_expr;
6572
6573 IrInstSrc *asm_template = astgen_node(ag, asm_expr->asm_template, scope);
6574 if (asm_template == ag->codegen->invalid_inst_src)
6575 return ag->codegen->invalid_inst_src;
6576
6577 bool is_volatile = asm_expr->volatile_token != 0;
6578 bool in_fn_scope = (scope_fn_entry(scope) != nullptr);
6579
6580 if (!in_fn_scope) {
6581 if (is_volatile) {
6582 add_token_error(ag->codegen, node->owner, asm_expr->volatile_token,
6583 buf_sprintf("volatile is meaningless on global assembly"));
6584 return ag->codegen->invalid_inst_src;
6585 }
6586
6587 if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 ||
6588 asm_expr->clobber_list.length != 0)
6589 {
6590 add_node_error(ag->codegen, node,
6591 buf_sprintf("global assembly cannot have inputs, outputs, or clobbers"));
6592 return ag->codegen->invalid_inst_src;
6593 }
6594
6595 return ir_build_asm_src(ag, scope, node, asm_template, nullptr, nullptr,
6596 nullptr, 0, is_volatile, true);
6597 }
6598
6599 IrInstSrc **input_list = heap::c_allocator.allocate<IrInstSrc *>(asm_expr->input_list.length);
6600 IrInstSrc **output_types = heap::c_allocator.allocate<IrInstSrc *>(asm_expr->output_list.length);
6601 ZigVar **output_vars = heap::c_allocator.allocate<ZigVar *>(asm_expr->output_list.length);
6602 size_t return_count = 0;
6603 if (!is_volatile && asm_expr->output_list.length == 0) {
6604 add_node_error(ag->codegen, node,
6605 buf_sprintf("assembly expression with no output must be marked volatile"));
6606 return ag->codegen->invalid_inst_src;
6607 }
6608 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) {
6609 AsmOutput *asm_output = asm_expr->output_list.at(i);
6610 if (asm_output->return_type) {
6611 return_count += 1;
6612
6613 IrInstSrc *return_type = astgen_node(ag, asm_output->return_type, scope);
6614 if (return_type == ag->codegen->invalid_inst_src)
6615 return ag->codegen->invalid_inst_src;
6616 if (return_count > 1) {
6617 add_node_error(ag->codegen, node,
6618 buf_sprintf("inline assembly allows up to one output value"));
6619 return ag->codegen->invalid_inst_src;
6620 }
6621 output_types[i] = return_type;
6622 } else {
6623 Buf *variable_name = asm_output->variable_name;
6624 // TODO there is some duplication here with astgen_identifier. I need to do a full audit of how
6625 // inline assembly works. https://github.com/ziglang/zig/issues/215
6626 ZigVar *var = find_variable(ag->codegen, scope, variable_name, nullptr);
6627 if (var) {
6628 output_vars[i] = var;
6629 } else {
6630 add_node_error(ag->codegen, node,
6631 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
6632 return ag->codegen->invalid_inst_src;
6633 }
6634 }
6635
6636 const char modifier = *buf_ptr(asm_output->constraint);
6637 if (modifier != '=') {
6638 add_node_error(ag->codegen, node,
6639 buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported."
6640 " Compiler TODO: see https://github.com/ziglang/zig/issues/215",
6641 buf_ptr(asm_output->asm_symbolic_name), modifier));
6642 return ag->codegen->invalid_inst_src;
6643 }
6644 }
6645 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) {
6646 AsmInput *asm_input = asm_expr->input_list.at(i);
6647 IrInstSrc *input_value = astgen_node(ag, asm_input->expr, scope);
6648 if (input_value == ag->codegen->invalid_inst_src)
6649 return ag->codegen->invalid_inst_src;
6650
6651 input_list[i] = input_value;
6652 }
6653
6654 return ir_build_asm_src(ag, scope, node, asm_template, input_list, output_types,
6655 output_vars, return_count, is_volatile, false);
6656}
6657
6658static IrInstSrc *astgen_if_optional_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
6659 ResultLoc *result_loc)
6660{
6661 assert(node->type == NodeTypeIfOptional);
6662
6663 Buf *var_symbol = node->data.test_expr.var_symbol;
6664 AstNode *expr_node = node->data.test_expr.target_node;
6665 AstNode *then_node = node->data.test_expr.then_node;
6666 AstNode *else_node = node->data.test_expr.else_node;
6667 bool var_is_ptr = node->data.test_expr.var_is_ptr;
6668
6669 ScopeExpr *spill_scope = create_expr_scope(ag->codegen, expr_node, scope);
6670 spill_scope->spill_harder = true;
6671
6672 IrInstSrc *maybe_val_ptr = astgen_node_extra(ag, expr_node, &spill_scope->base, LValPtr, nullptr);
6673 if (maybe_val_ptr == ag->codegen->invalid_inst_src)
6674 return maybe_val_ptr;
6675
6676 IrInstSrc *maybe_val = ir_build_load_ptr(ag, scope, node, maybe_val_ptr);
6677 IrInstSrc *is_non_null = ir_build_test_non_null_src(ag, scope, node, maybe_val);
6678
6679 Stage1ZirBasicBlock *then_block = ir_create_basic_block(ag, scope, "OptionalThen");
6680 Stage1ZirBasicBlock *else_block = ir_create_basic_block(ag, scope, "OptionalElse");
6681 Stage1ZirBasicBlock *endif_block = ir_create_basic_block(ag, scope, "OptionalEndIf");
6682
6683 IrInstSrc *is_comptime;
6684 if (ir_should_inline(ag->exec, scope)) {
6685 is_comptime = ir_build_const_bool(ag, scope, node, true);
6686 } else {
6687 is_comptime = ir_build_test_comptime(ag, scope, node, is_non_null);
6688 }
6689 IrInstSrc *cond_br_inst = ir_build_cond_br(ag, scope, node, is_non_null,
6690 then_block, else_block, is_comptime);
6691
6692 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(ag, cond_br_inst, else_block, endif_block,
6693 result_loc, is_comptime);
6694
6695 ir_set_cursor_at_end_and_append_block(ag, then_block);
6696
6697 Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, &spill_scope->base, is_comptime);
6698 Scope *var_scope;
6699 if (var_symbol) {
6700 bool is_shadowable = false;
6701 bool is_const = true;
6702 ZigVar *var = ir_create_var(ag, node, subexpr_scope,
6703 var_symbol, is_const, is_const, is_shadowable, is_comptime);
6704
6705 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(ag, subexpr_scope, node, maybe_val_ptr, false);
6706 IrInstSrc *var_value = var_is_ptr ?
6707 payload_ptr : ir_build_load_ptr(ag, &spill_scope->base, node, payload_ptr);
6708 build_decl_var_and_init(ag, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), is_comptime);
6709 var_scope = var->child_scope;
6710 } else {
6711 var_scope = subexpr_scope;
6712 }
6713 IrInstSrc *then_expr_result = astgen_node_extra(ag, then_node, var_scope, lval,
6714 &peer_parent->peers.at(0)->base);
6715 if (then_expr_result == ag->codegen->invalid_inst_src)
6716 return then_expr_result;
6717 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
6718 if (!instr_is_unreachable(then_expr_result))
6719 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));
6720
6721 ir_set_cursor_at_end_and_append_block(ag, else_block);
6722 IrInstSrc *else_expr_result;
6723 if (else_node) {
6724 else_expr_result = astgen_node_extra(ag, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base);
6725 if (else_expr_result == ag->codegen->invalid_inst_src)
6726 return else_expr_result;
6727 } else {
6728 else_expr_result = ir_build_const_void(ag, scope, node);
6729 ir_build_end_expr(ag, scope, node, else_expr_result, &peer_parent->peers.at(1)->base);
6730 }
6731 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6732 if (!instr_is_unreachable(else_expr_result))
6733 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));
6734
6735 ir_set_cursor_at_end_and_append_block(ag, endif_block);
6736 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
6737 incoming_values[0] = then_expr_result;
6738 incoming_values[1] = else_expr_result;
6739 Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
6740 incoming_blocks[0] = after_then_block;
6741 incoming_blocks[1] = after_else_block;
6742
6743 IrInstSrc *phi = ir_build_phi(ag, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
6744 return ir_expr_wrap(ag, scope, phi, result_loc);
6745}
6746
6747static IrInstSrc *astgen_if_err_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
6748 ResultLoc *result_loc)
6749{
6750 assert(node->type == NodeTypeIfErrorExpr);
6751
6752 AstNode *target_node = node->data.if_err_expr.target_node;
6753 AstNode *then_node = node->data.if_err_expr.then_node;
6754 AstNode *else_node = node->data.if_err_expr.else_node;
6755 bool var_is_ptr = node->data.if_err_expr.var_is_ptr;
6756 bool var_is_const = true;
6757 Buf *var_symbol = node->data.if_err_expr.var_symbol;
6758 Buf *err_symbol = node->data.if_err_expr.err_symbol;
6759
6760 IrInstSrc *err_val_ptr = astgen_node_extra(ag, target_node, scope, LValPtr, nullptr);
6761 if (err_val_ptr == ag->codegen->invalid_inst_src)
6762 return err_val_ptr;
6763
6764 IrInstSrc *err_val = ir_build_load_ptr(ag, scope, node, err_val_ptr);
6765 IrInstSrc *is_err = ir_build_test_err_src(ag, scope, node, err_val_ptr, true, false);
6766
6767 Stage1ZirBasicBlock *ok_block = ir_create_basic_block(ag, scope, "TryOk");
6768 Stage1ZirBasicBlock *else_block = ir_create_basic_block(ag, scope, "TryElse");
6769 Stage1ZirBasicBlock *endif_block = ir_create_basic_block(ag, scope, "TryEnd");
6770
6771 bool force_comptime = ir_should_inline(ag->exec, scope);
6772 IrInstSrc *is_comptime = force_comptime ? ir_build_const_bool(ag, scope, node, true) : ir_build_test_comptime(ag, scope, node, is_err);
6773 IrInstSrc *cond_br_inst = ir_build_cond_br(ag, scope, node, is_err, else_block, ok_block, is_comptime);
6774
6775 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(ag, cond_br_inst, else_block, endif_block,
6776 result_loc, is_comptime);
6777
6778 ir_set_cursor_at_end_and_append_block(ag, ok_block);
6779
6780 Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, scope, is_comptime);
6781 Scope *var_scope;
6782 if (var_symbol) {
6783 bool is_shadowable = false;
6784 IrInstSrc *var_is_comptime = force_comptime ? ir_build_const_bool(ag, subexpr_scope, node, true) : ir_build_test_comptime(ag, subexpr_scope, node, err_val);
6785 ZigVar *var = ir_create_var(ag, node, subexpr_scope,
6786 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime);
6787
6788 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(ag, subexpr_scope, node, err_val_ptr, false, false);
6789 IrInstSrc *var_value = var_is_ptr ?
6790 payload_ptr : ir_build_load_ptr(ag, subexpr_scope, node, payload_ptr);
6791 build_decl_var_and_init(ag, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), var_is_comptime);
6792 var_scope = var->child_scope;
6793 } else {
6794 var_scope = subexpr_scope;
6795 }
6796 IrInstSrc *then_expr_result = astgen_node_extra(ag, then_node, var_scope, lval,
6797 &peer_parent->peers.at(0)->base);
6798 if (then_expr_result == ag->codegen->invalid_inst_src)
6799 return then_expr_result;
6800 Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
6801 if (!instr_is_unreachable(then_expr_result))
6802 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));
6803
6804 ir_set_cursor_at_end_and_append_block(ag, else_block);
6805
6806 IrInstSrc *else_expr_result;
6807 if (else_node) {
6808 Scope *err_var_scope;
6809 if (err_symbol) {
6810 bool is_shadowable = false;
6811 bool is_const = true;
6812 ZigVar *var = ir_create_var(ag, node, subexpr_scope,
6813 err_symbol, is_const, is_const, is_shadowable, is_comptime);
6814
6815 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(ag, subexpr_scope, node, err_val_ptr);
6816 IrInstSrc *err_value = ir_build_load_ptr(ag, subexpr_scope, node, err_ptr);
6817 build_decl_var_and_init(ag, subexpr_scope, node, var, err_value, buf_ptr(err_symbol), is_comptime);
6818 err_var_scope = var->child_scope;
6819 } else {
6820 err_var_scope = subexpr_scope;
6821 }
6822 else_expr_result = astgen_node_extra(ag, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base);
6823 if (else_expr_result == ag->codegen->invalid_inst_src)
6824 return else_expr_result;
6825 } else {
6826 else_expr_result = ir_build_const_void(ag, scope, node);
6827 ir_build_end_expr(ag, scope, node, else_expr_result, &peer_parent->peers.at(1)->base);
6828 }
6829 Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6830 if (!instr_is_unreachable(else_expr_result))
6831 ir_mark_gen(ir_build_br(ag, scope, node, endif_block, is_comptime));
6832
6833 ir_set_cursor_at_end_and_append_block(ag, endif_block);
6834 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
6835 incoming_values[0] = then_expr_result;
6836 incoming_values[1] = else_expr_result;
6837 Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
6838 incoming_blocks[0] = after_then_block;
6839 incoming_blocks[1] = after_else_block;
6840
6841 IrInstSrc *phi = ir_build_phi(ag, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
6842 return ir_expr_wrap(ag, scope, phi, result_loc);
6843}
6844
6845static bool astgen_switch_prong_expr(Stage1AstGen *ag, Scope *scope, AstNode *switch_node, AstNode *prong_node,
6846 Stage1ZirBasicBlock *end_block, IrInstSrc *is_comptime, IrInstSrc *var_is_comptime,
6847 IrInstSrc *target_value_ptr, IrInstSrc **prong_values, size_t prong_values_len,
6848 ZigList<Stage1ZirBasicBlock *> *incoming_blocks, ZigList<IrInstSrc *> *incoming_values,
6849 IrInstSrcSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc)
6850{
6851 assert(switch_node->type == NodeTypeSwitchExpr);
6852 assert(prong_node->type == NodeTypeSwitchProng);
6853
6854 AstNode *expr_node = prong_node->data.switch_prong.expr;
6855 AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol;
6856 Scope *child_scope;
6857 if (var_symbol_node) {
6858 assert(var_symbol_node->type == NodeTypeIdentifier);
6859 Buf *var_name = node_identifier_buf(var_symbol_node);
6860 bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr;
6861
6862 bool is_shadowable = false;
6863 bool is_const = true;
6864 ZigVar *var = ir_create_var(ag, var_symbol_node, scope,
6865 var_name, is_const, is_const, is_shadowable, var_is_comptime);
6866 child_scope = var->child_scope;
6867 IrInstSrc *var_value;
6868 if (out_switch_else_var != nullptr) {
6869 IrInstSrcSwitchElseVar *switch_else_var = ir_build_switch_else_var(ag, scope, var_symbol_node,
6870 target_value_ptr);
6871 *out_switch_else_var = switch_else_var;
6872 IrInstSrc *payload_ptr = &switch_else_var->base;
6873 var_value = var_is_ptr ?
6874 payload_ptr : ir_build_load_ptr(ag, scope, var_symbol_node, payload_ptr);
6875 } else if (prong_values != nullptr) {
6876 IrInstSrc *payload_ptr = ir_build_switch_var(ag, scope, var_symbol_node, target_value_ptr,
6877 prong_values, prong_values_len);
6878 var_value = var_is_ptr ?
6879 payload_ptr : ir_build_load_ptr(ag, scope, var_symbol_node, payload_ptr);
6880 } else {
6881 var_value = var_is_ptr ?
6882 target_value_ptr : ir_build_load_ptr(ag, scope, var_symbol_node, target_value_ptr);
6883 }
6884 build_decl_var_and_init(ag, scope, var_symbol_node, var, var_value, buf_ptr(var_name), var_is_comptime);
6885 } else {
6886 child_scope = scope;
6887 }
6888
6889 IrInstSrc *expr_result = astgen_node_extra(ag, expr_node, child_scope, lval, result_loc);
6890 if (expr_result == ag->codegen->invalid_inst_src)
6891 return false;
6892 if (!instr_is_unreachable(expr_result))
6893 ir_mark_gen(ir_build_br(ag, scope, switch_node, end_block, is_comptime));
6894 incoming_blocks->append(ag->current_basic_block);
6895 incoming_values->append(expr_result);
6896 return true;
6897}
6898
6899static IrInstSrc *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
6900 ResultLoc *result_loc)
6901{
6902 assert(node->type == NodeTypeSwitchExpr);
6903
6904 AstNode *target_node = node->data.switch_expr.expr;
6905 IrInstSrc *target_value_ptr = astgen_node_extra(ag, target_node, scope, LValPtr, nullptr);
6906 if (target_value_ptr == ag->codegen->invalid_inst_src)
6907 return target_value_ptr;
6908 IrInstSrc *target_value = ir_build_switch_target(ag, scope, node, target_value_ptr);
6909
6910 Stage1ZirBasicBlock *else_block = ir_create_basic_block(ag, scope, "SwitchElse");
6911 Stage1ZirBasicBlock *end_block = ir_create_basic_block(ag, scope, "SwitchEnd");
6912
6913 size_t prong_count = node->data.switch_expr.prongs.length;
6914 ZigList<IrInstSrcSwitchBrCase> cases = {0};
6915
6916 IrInstSrc *is_comptime;
6917 IrInstSrc *var_is_comptime;
6918 if (ir_should_inline(ag->exec, scope)) {
6919 is_comptime = ir_build_const_bool(ag, scope, node, true);
6920 var_is_comptime = is_comptime;
6921 } else {
6922 is_comptime = ir_build_test_comptime(ag, scope, node, target_value);
6923 var_is_comptime = ir_build_test_comptime(ag, scope, node, target_value_ptr);
6924 }
6925
6926 ZigList<IrInstSrc *> incoming_values = {0};
6927 ZigList<Stage1ZirBasicBlock *> incoming_blocks = {0};
6928 ZigList<IrInstSrcCheckSwitchProngsRange> check_ranges = {0};
6929
6930 IrInstSrcSwitchElseVar *switch_else_var = nullptr;
6931
6932 ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>();
6933 peer_parent->base.id = ResultLocIdPeerParent;
6934 peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const;
6935 peer_parent->end_bb = end_block;
6936 peer_parent->is_comptime = is_comptime;
6937 peer_parent->parent = result_loc;
6938
6939 ir_build_reset_result(ag, scope, node, &peer_parent->base);
6940
6941 // First do the else and the ranges
6942 Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, scope, is_comptime);
6943 Scope *comptime_scope = create_comptime_scope(ag->codegen, node, scope);
6944 AstNode *else_prong = nullptr;
6945 AstNode *underscore_prong = nullptr;
6946 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) {
6947 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);
6948 size_t prong_item_count = prong_node->data.switch_prong.items.length;
6949 if (prong_node->data.switch_prong.any_items_are_range) {
6950 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
6951
6952 IrInstSrc *ok_bit = nullptr;
6953 AstNode *last_item_node = nullptr;
6954 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {
6955 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
6956 last_item_node = item_node;
6957 if (item_node->type == NodeTypeSwitchRange) {
6958 AstNode *start_node = item_node->data.switch_range.start;
6959 AstNode *end_node = item_node->data.switch_range.end;
6960
6961 IrInstSrc *start_value = astgen_node(ag, start_node, comptime_scope);
6962 if (start_value == ag->codegen->invalid_inst_src)
6963 return ag->codegen->invalid_inst_src;
6964
6965 IrInstSrc *end_value = astgen_node(ag, end_node, comptime_scope);
6966 if (end_value == ag->codegen->invalid_inst_src)
6967 return ag->codegen->invalid_inst_src;
6968
6969 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one();
6970 check_range->start = start_value;
6971 check_range->end = end_value;
6972
6973 IrInstSrc *lower_range_ok = ir_build_bin_op(ag, scope, item_node, IrBinOpCmpGreaterOrEq,
6974 target_value, start_value, false);
6975 IrInstSrc *upper_range_ok = ir_build_bin_op(ag, scope, item_node, IrBinOpCmpLessOrEq,
6976 target_value, end_value, false);
6977 IrInstSrc *both_ok = ir_build_bin_op(ag, scope, item_node, IrBinOpBoolAnd,
6978 lower_range_ok, upper_range_ok, false);
6979 if (ok_bit) {
6980 ok_bit = ir_build_bin_op(ag, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false);
6981 } else {
6982 ok_bit = both_ok;
6983 }
6984 } else {
6985 IrInstSrc *item_value = astgen_node(ag, item_node, comptime_scope);
6986 if (item_value == ag->codegen->invalid_inst_src)
6987 return ag->codegen->invalid_inst_src;
6988
6989 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one();
6990 check_range->start = item_value;
6991 check_range->end = item_value;
6992
6993 IrInstSrc *cmp_ok = ir_build_bin_op(ag, scope, item_node, IrBinOpCmpEq,
6994 item_value, target_value, false);
6995 if (ok_bit) {
6996 ok_bit = ir_build_bin_op(ag, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false);
6997 } else {
6998 ok_bit = cmp_ok;
6999 }
7000 }
7001 }
7002
7003 Stage1ZirBasicBlock *range_block_yes = ir_create_basic_block(ag, scope, "SwitchRangeYes");
7004 Stage1ZirBasicBlock *range_block_no = ir_create_basic_block(ag, scope, "SwitchRangeNo");
7005
7006 assert(ok_bit);
7007 assert(last_item_node);
7008 IrInstSrc *br_inst = ir_mark_gen(ir_build_cond_br(ag, scope, last_item_node, ok_bit,
7009 range_block_yes, range_block_no, is_comptime));
7010 if (peer_parent->base.source_instruction == nullptr) {
7011 peer_parent->base.source_instruction = br_inst;
7012 }
7013
7014 if (peer_parent->peers.length > 0) {
7015 peer_parent->peers.last()->next_bb = range_block_yes;
7016 }
7017 peer_parent->peers.append(this_peer_result_loc);
7018 ir_set_cursor_at_end_and_append_block(ag, range_block_yes);
7019 if (!astgen_switch_prong_expr(ag, subexpr_scope, node, prong_node, end_block,
7020 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0,
7021 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base))
7022 {
7023 return ag->codegen->invalid_inst_src;
7024 }
7025
7026 ir_set_cursor_at_end_and_append_block(ag, range_block_no);
7027 } else {
7028 if (prong_item_count == 0) {
7029 if (else_prong) {
7030 ErrorMsg *msg = add_node_error(ag->codegen, prong_node,
7031 buf_sprintf("multiple else prongs in switch expression"));
7032 add_error_note(ag->codegen, msg, else_prong,
7033 buf_sprintf("previous else prong is here"));
7034 return ag->codegen->invalid_inst_src;
7035 }
7036 else_prong = prong_node;
7037 } else if (prong_item_count == 1 &&
7038 prong_node->data.switch_prong.items.at(0)->type == NodeTypeIdentifier &&
7039 buf_eql_str(node_identifier_buf(prong_node->data.switch_prong.items.at(0)), "_")) {
7040 if (underscore_prong) {
7041 ErrorMsg *msg = add_node_error(ag->codegen, prong_node,
7042 buf_sprintf("multiple '_' prongs in switch expression"));
7043 add_error_note(ag->codegen, msg, underscore_prong,
7044 buf_sprintf("previous '_' prong is here"));
7045 return ag->codegen->invalid_inst_src;
7046 }
7047 underscore_prong = prong_node;
7048 } else {
7049 continue;
7050 }
7051 if (underscore_prong && else_prong) {
7052 ErrorMsg *msg = add_node_error(ag->codegen, prong_node,
7053 buf_sprintf("else and '_' prong in switch expression"));
7054 if (underscore_prong == prong_node)
7055 add_error_note(ag->codegen, msg, else_prong,
7056 buf_sprintf("else prong is here"));
7057 else
7058 add_error_note(ag->codegen, msg, underscore_prong,
7059 buf_sprintf("'_' prong is here"));
7060 return ag->codegen->invalid_inst_src;
7061 }
7062 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
7063
7064 Stage1ZirBasicBlock *prev_block = ag->current_basic_block;
7065 if (peer_parent->peers.length > 0) {
7066 peer_parent->peers.last()->next_bb = else_block;
7067 }
7068 peer_parent->peers.append(this_peer_result_loc);
7069 ir_set_cursor_at_end_and_append_block(ag, else_block);
7070 if (!astgen_switch_prong_expr(ag, subexpr_scope, node, prong_node, end_block,
7071 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values,
7072 &switch_else_var, LValNone, &this_peer_result_loc->base))
7073 {
7074 return ag->codegen->invalid_inst_src;
7075 }
7076 ir_set_cursor_at_end(ag, prev_block);
7077 }
7078 }
7079
7080 // next do the non-else non-ranges
7081 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) {
7082 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);
7083 size_t prong_item_count = prong_node->data.switch_prong.items.length;
7084 if (prong_item_count == 0)
7085 continue;
7086 if (prong_node->data.switch_prong.any_items_are_range)
7087 continue;
7088 if (underscore_prong == prong_node)
7089 continue;
7090
7091 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
7092
7093 Stage1ZirBasicBlock *prong_block = ir_create_basic_block(ag, scope, "SwitchProng");
7094 IrInstSrc **items = heap::c_allocator.allocate<IrInstSrc *>(prong_item_count);
7095
7096 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {
7097 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
7098 assert(item_node->type != NodeTypeSwitchRange);
7099
7100 IrInstSrc *item_value = astgen_node(ag, item_node, comptime_scope);
7101 if (item_value == ag->codegen->invalid_inst_src)
7102 return ag->codegen->invalid_inst_src;
7103
7104 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one();
7105 check_range->start = item_value;
7106 check_range->end = item_value;
7107
7108 IrInstSrcSwitchBrCase *this_case = cases.add_one();
7109 this_case->value = item_value;
7110 this_case->block = prong_block;
7111
7112 items[item_i] = item_value;
7113 }
7114
7115 Stage1ZirBasicBlock *prev_block = ag->current_basic_block;
7116 if (peer_parent->peers.length > 0) {
7117 peer_parent->peers.last()->next_bb = prong_block;
7118 }
7119 peer_parent->peers.append(this_peer_result_loc);
7120 ir_set_cursor_at_end_and_append_block(ag, prong_block);
7121 if (!astgen_switch_prong_expr(ag, subexpr_scope, node, prong_node, end_block,
7122 is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count,
7123 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base))
7124 {
7125 return ag->codegen->invalid_inst_src;
7126 }
7127
7128 ir_set_cursor_at_end(ag, prev_block);
7129
7130 }
7131
7132 IrInstSrc *switch_prongs_void = ir_build_check_switch_prongs(ag, scope, node, target_value,
7133 check_ranges.items, check_ranges.length, else_prong, underscore_prong != nullptr);
7134
7135 IrInstSrc *br_instruction;
7136 if (cases.length == 0) {
7137 br_instruction = ir_build_br(ag, scope, node, else_block, is_comptime);
7138 } else {
7139 IrInstSrcSwitchBr *switch_br = ir_build_switch_br_src(ag, scope, node, target_value, else_block,
7140 cases.length, cases.items, is_comptime, switch_prongs_void);
7141 if (switch_else_var != nullptr) {
7142 switch_else_var->switch_br = switch_br;
7143 }
7144 br_instruction = &switch_br->base;
7145 }
7146 if (peer_parent->base.source_instruction == nullptr) {
7147 peer_parent->base.source_instruction = br_instruction;
7148 }
7149 for (size_t i = 0; i < peer_parent->peers.length; i += 1) {
7150 peer_parent->peers.at(i)->base.source_instruction = peer_parent->base.source_instruction;
7151 }
7152
7153 if (!else_prong && !underscore_prong) {
7154 if (peer_parent->peers.length != 0) {
7155 peer_parent->peers.last()->next_bb = else_block;
7156 }
7157 ir_set_cursor_at_end_and_append_block(ag, else_block);
7158 ir_build_unreachable(ag, scope, node);
7159 } else {
7160 if (peer_parent->peers.length != 0) {
7161 peer_parent->peers.last()->next_bb = end_block;
7162 }
7163 }
7164
7165 ir_set_cursor_at_end_and_append_block(ag, end_block);
7166 assert(incoming_blocks.length == incoming_values.length);
7167 IrInstSrc *result_instruction;
7168 if (incoming_blocks.length == 0) {
7169 result_instruction = ir_build_const_void(ag, scope, node);
7170 } else {
7171 result_instruction = ir_build_phi(ag, scope, node, incoming_blocks.length,
7172 incoming_blocks.items, incoming_values.items, peer_parent);
7173 }
7174 return ir_lval_wrap(ag, scope, result_instruction, lval, result_loc);
7175}
7176
7177static IrInstSrc *astgen_comptime(Stage1AstGen *ag, Scope *parent_scope, AstNode *node, LVal lval) {
7178 assert(node->type == NodeTypeCompTime);
7179
7180 Scope *child_scope = create_comptime_scope(ag->codegen, node, parent_scope);
7181 // purposefully pass null for result_loc and let EndExpr handle it
7182 return astgen_node_extra(ag, node->data.comptime_expr.expr, child_scope, lval, nullptr);
7183}
7184
7185static IrInstSrc *astgen_nosuspend(Stage1AstGen *ag, Scope *parent_scope, AstNode *node, LVal lval) {
7186 assert(node->type == NodeTypeNoSuspend);
7187
7188 Scope *child_scope = create_nosuspend_scope(ag->codegen, node, parent_scope);
7189 // purposefully pass null for result_loc and let EndExpr handle it
7190 return astgen_node_extra(ag, node->data.nosuspend_expr.expr, child_scope, lval, nullptr);
7191}
7192
7193static IrInstSrc *astgen_return_from_block(Stage1AstGen *ag, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) {
7194 IrInstSrc *is_comptime;
7195 if (ir_should_inline(ag->exec, break_scope)) {
7196 is_comptime = ir_build_const_bool(ag, break_scope, node, true);
7197 } else {
7198 is_comptime = block_scope->is_comptime;
7199 }
7200
7201 IrInstSrc *result_value;
7202 if (node->data.break_expr.expr) {
7203 ResultLocPeer *peer_result = create_peer_result(block_scope->peer_parent);
7204 block_scope->peer_parent->peers.append(peer_result);
7205
7206 result_value = astgen_node_extra(ag, node->data.break_expr.expr, break_scope, block_scope->lval,
7207 &peer_result->base);
7208 if (result_value == ag->codegen->invalid_inst_src)
7209 return ag->codegen->invalid_inst_src;
7210 } else {
7211 result_value = ir_build_const_void(ag, break_scope, node);
7212 }
7213
7214 Stage1ZirBasicBlock *dest_block = block_scope->end_block;
7215 if (!astgen_defers_for_block(ag, break_scope, dest_block->scope, nullptr, nullptr))
7216 return ag->codegen->invalid_inst_src;
7217
7218 block_scope->incoming_blocks->append(ag->current_basic_block);
7219 block_scope->incoming_values->append(result_value);
7220 return ir_build_br(ag, break_scope, node, dest_block, is_comptime);
7221}
7222
7223static IrInstSrc *astgen_break(Stage1AstGen *ag, Scope *break_scope, AstNode *node) {
7224 assert(node->type == NodeTypeBreak);
7225
7226 // Search up the scope. We'll find one of these things first:
7227 // * function definition scope or global scope => error, break outside loop
7228 // * defer expression scope => error, cannot break out of defer expression
7229 // * loop scope => OK
7230 // * (if it's a labeled break) labeled block => OK
7231
7232 Scope *search_scope = break_scope;
7233 ScopeLoop *loop_scope;
7234 for (;;) {
7235 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) {
7236 if (node->data.break_expr.name != nullptr) {
7237 add_node_error(ag->codegen, node, buf_sprintf("label not found: '%s'", buf_ptr(node->data.break_expr.name)));
7238 return ag->codegen->invalid_inst_src;
7239 } else {
7240 add_node_error(ag->codegen, node, buf_sprintf("break expression outside loop"));
7241 return ag->codegen->invalid_inst_src;
7242 }
7243 } else if (search_scope->id == ScopeIdDeferExpr) {
7244 add_node_error(ag->codegen, node, buf_sprintf("cannot break out of defer expression"));
7245 return ag->codegen->invalid_inst_src;
7246 } else if (search_scope->id == ScopeIdLoop) {
7247 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope;
7248 if (node->data.break_expr.name == nullptr ||
7249 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name)))
7250 {
7251 this_loop_scope->name_used = true;
7252 loop_scope = this_loop_scope;
7253 break;
7254 }
7255 } else if (search_scope->id == ScopeIdBlock) {
7256 ScopeBlock *this_block_scope = (ScopeBlock *)search_scope;
7257 if (node->data.break_expr.name != nullptr &&
7258 (this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name)))
7259 {
7260 assert(this_block_scope->end_block != nullptr);
7261 this_block_scope->name_used = true;
7262 return astgen_return_from_block(ag, break_scope, node, this_block_scope);
7263 }
7264 } else if (search_scope->id == ScopeIdSuspend) {
7265 add_node_error(ag->codegen, node, buf_sprintf("cannot break out of suspend block"));
7266 return ag->codegen->invalid_inst_src;
7267 }
7268 search_scope = search_scope->parent;
7269 }
7270
7271 IrInstSrc *is_comptime;
7272 if (ir_should_inline(ag->exec, break_scope)) {
7273 is_comptime = ir_build_const_bool(ag, break_scope, node, true);
7274 } else {
7275 is_comptime = loop_scope->is_comptime;
7276 }
7277
7278 IrInstSrc *result_value;
7279 if (node->data.break_expr.expr) {
7280 ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent);
7281 loop_scope->peer_parent->peers.append(peer_result);
7282
7283 result_value = astgen_node_extra(ag, node->data.break_expr.expr, break_scope,
7284 loop_scope->lval, &peer_result->base);
7285 if (result_value == ag->codegen->invalid_inst_src)
7286 return ag->codegen->invalid_inst_src;
7287 } else {
7288 result_value = ir_build_const_void(ag, break_scope, node);
7289 }
7290
7291 Stage1ZirBasicBlock *dest_block = loop_scope->break_block;
7292 if (!astgen_defers_for_block(ag, break_scope, dest_block->scope, nullptr, nullptr))
7293 return ag->codegen->invalid_inst_src;
7294
7295 loop_scope->incoming_blocks->append(ag->current_basic_block);
7296 loop_scope->incoming_values->append(result_value);
7297 return ir_build_br(ag, break_scope, node, dest_block, is_comptime);
7298}
7299
7300static IrInstSrc *astgen_continue(Stage1AstGen *ag, Scope *continue_scope, AstNode *node) {
7301 assert(node->type == NodeTypeContinue);
7302
7303 // Search up the scope. We'll find one of these things first:
7304 // * function definition scope or global scope => error, break outside loop
7305 // * defer expression scope => error, cannot break out of defer expression
7306 // * loop scope => OK
7307
7308 ZigList<ScopeRuntime *> runtime_scopes = {};
7309
7310 Scope *search_scope = continue_scope;
7311 ScopeLoop *loop_scope;
7312 for (;;) {
7313 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) {
7314 if (node->data.continue_expr.name != nullptr) {
7315 add_node_error(ag->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.continue_expr.name)));
7316 return ag->codegen->invalid_inst_src;
7317 } else {
7318 add_node_error(ag->codegen, node, buf_sprintf("continue expression outside loop"));
7319 return ag->codegen->invalid_inst_src;
7320 }
7321 } else if (search_scope->id == ScopeIdDeferExpr) {
7322 add_node_error(ag->codegen, node, buf_sprintf("cannot continue out of defer expression"));
7323 return ag->codegen->invalid_inst_src;
7324 } else if (search_scope->id == ScopeIdLoop) {
7325 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope;
7326 if (node->data.continue_expr.name == nullptr ||
7327 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name)))
7328 {
7329 this_loop_scope->name_used = true;
7330 loop_scope = this_loop_scope;
7331 break;
7332 }
7333 } else if (search_scope->id == ScopeIdRuntime) {
7334 ScopeRuntime *scope_runtime = (ScopeRuntime *)search_scope;
7335 runtime_scopes.append(scope_runtime);
7336 }
7337 search_scope = search_scope->parent;
7338 }
7339
7340 IrInstSrc *is_comptime;
7341 if (ir_should_inline(ag->exec, continue_scope)) {
7342 is_comptime = ir_build_const_bool(ag, continue_scope, node, true);
7343 } else {
7344 is_comptime = loop_scope->is_comptime;
7345 }
7346
7347 for (size_t i = 0; i < runtime_scopes.length; i += 1) {
7348 ScopeRuntime *scope_runtime = runtime_scopes.at(i);
7349 ir_mark_gen(ir_build_check_runtime_scope(ag, continue_scope, node, scope_runtime->is_comptime, is_comptime));
7350 }
7351 runtime_scopes.deinit();
7352
7353 Stage1ZirBasicBlock *dest_block = loop_scope->continue_block;
7354 if (!astgen_defers_for_block(ag, continue_scope, dest_block->scope, nullptr, nullptr))
7355 return ag->codegen->invalid_inst_src;
7356 return ir_mark_gen(ir_build_br(ag, continue_scope, node, dest_block, is_comptime));
7357}
7358
7359static IrInstSrc *astgen_error_type(Stage1AstGen *ag, Scope *scope, AstNode *node) {
7360 assert(node->type == NodeTypeErrorType);
7361 return ir_build_const_type(ag, scope, node, ag->codegen->builtin_types.entry_global_error_set);
7362}
7363
7364static IrInstSrc *astgen_defer(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) {
7365 assert(node->type == NodeTypeDefer);
7366
7367 ScopeDefer *defer_child_scope = create_defer_scope(ag->codegen, node, parent_scope);
7368 node->data.defer.child_scope = &defer_child_scope->base;
7369
7370 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(ag->codegen, node, parent_scope);
7371 node->data.defer.expr_scope = &defer_expr_scope->base;
7372
7373 return ir_build_const_void(ag, parent_scope, node);
7374}
7375
7376static IrInstSrc *astgen_slice(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
7377 assert(node->type == NodeTypeSliceExpr);
7378
7379 AstNodeSliceExpr *slice_expr = &node->data.slice_expr;
7380 AstNode *array_node = slice_expr->array_ref_expr;
7381 AstNode *start_node = slice_expr->start;
7382 AstNode *end_node = slice_expr->end;
7383 AstNode *sentinel_node = slice_expr->sentinel;
7384
7385 IrInstSrc *ptr_value = astgen_node_extra(ag, array_node, scope, LValPtr, nullptr);
7386 if (ptr_value == ag->codegen->invalid_inst_src)
7387 return ag->codegen->invalid_inst_src;
7388
7389 IrInstSrc *start_value = astgen_node(ag, start_node, scope);
7390 if (start_value == ag->codegen->invalid_inst_src)
7391 return ag->codegen->invalid_inst_src;
7392
7393 IrInstSrc *end_value;
7394 if (end_node) {
7395 end_value = astgen_node(ag, end_node, scope);
7396 if (end_value == ag->codegen->invalid_inst_src)
7397 return ag->codegen->invalid_inst_src;
7398 } else {
7399 end_value = nullptr;
7400 }
7401
7402 IrInstSrc *sentinel_value;
7403 if (sentinel_node) {
7404 sentinel_value = astgen_node(ag, sentinel_node, scope);
7405 if (sentinel_value == ag->codegen->invalid_inst_src)
7406 return ag->codegen->invalid_inst_src;
7407 } else {
7408 sentinel_value = nullptr;
7409 }
7410
7411 IrInstSrc *slice = ir_build_slice_src(ag, scope, node, ptr_value, start_value, end_value,
7412 sentinel_value, true, result_loc);
7413 return ir_lval_wrap(ag, scope, slice, lval, result_loc);
7414}
7415
7416static IrInstSrc *astgen_catch(Stage1AstGen *ag, Scope *parent_scope, AstNode *node, LVal lval,
7417 ResultLoc *result_loc)
7418{
7419 assert(node->type == NodeTypeCatchExpr);
7420
7421 AstNode *op1_node = node->data.unwrap_err_expr.op1;
7422 AstNode *op2_node = node->data.unwrap_err_expr.op2;
7423 AstNode *var_node = node->data.unwrap_err_expr.symbol;
7424
7425 if (op2_node->type == NodeTypeUnreachable) {
7426 if (var_node != nullptr) {
7427 assert(var_node->type == NodeTypeIdentifier);
7428 Buf *var_name = node_identifier_buf(var_node);
7429 add_node_error(ag->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name)));
7430 return ag->codegen->invalid_inst_src;
7431 }
7432 return astgen_catch_unreachable(ag, parent_scope, node, op1_node, lval, result_loc);
7433 }
7434
7435
7436 ScopeExpr *spill_scope = create_expr_scope(ag->codegen, op1_node, parent_scope);
7437 spill_scope->spill_harder = true;
7438
7439 IrInstSrc *err_union_ptr = astgen_node_extra(ag, op1_node, &spill_scope->base, LValPtr, nullptr);
7440 if (err_union_ptr == ag->codegen->invalid_inst_src)
7441 return ag->codegen->invalid_inst_src;
7442
7443 IrInstSrc *is_err = ir_build_test_err_src(ag, parent_scope, node, err_union_ptr, true, false);
7444
7445 IrInstSrc *is_comptime;
7446 if (ir_should_inline(ag->exec, parent_scope)) {
7447 is_comptime = ir_build_const_bool(ag, parent_scope, node, true);
7448 } else {
7449 is_comptime = ir_build_test_comptime(ag, parent_scope, node, is_err);
7450 }
7451
7452 Stage1ZirBasicBlock *ok_block = ir_create_basic_block(ag, parent_scope, "UnwrapErrOk");
7453 Stage1ZirBasicBlock *err_block = ir_create_basic_block(ag, parent_scope, "UnwrapErrError");
7454 Stage1ZirBasicBlock *end_block = ir_create_basic_block(ag, parent_scope, "UnwrapErrEnd");
7455 IrInstSrc *cond_br_inst = ir_build_cond_br(ag, parent_scope, node, is_err, err_block, ok_block, is_comptime);
7456
7457 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(ag, cond_br_inst, ok_block, end_block, result_loc,
7458 is_comptime);
7459
7460 ir_set_cursor_at_end_and_append_block(ag, err_block);
7461 Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, &spill_scope->base, is_comptime);
7462 Scope *err_scope;
7463 if (var_node) {
7464 assert(var_node->type == NodeTypeIdentifier);
7465 Buf *var_name = node_identifier_buf(var_node);
7466 bool is_const = true;
7467 bool is_shadowable = false;
7468 ZigVar *var = ir_create_var(ag, node, subexpr_scope, var_name,
7469 is_const, is_const, is_shadowable, is_comptime);
7470 err_scope = var->child_scope;
7471 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(ag, err_scope, node, err_union_ptr);
7472 IrInstSrc *err_value = ir_build_load_ptr(ag, err_scope, var_node, err_ptr);
7473 build_decl_var_and_init(ag, err_scope, var_node, var, err_value, buf_ptr(var_name), is_comptime);
7474 } else {
7475 err_scope = subexpr_scope;
7476 }
7477 IrInstSrc *err_result = astgen_node_extra(ag, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base);
7478 if (err_result == ag->codegen->invalid_inst_src)
7479 return ag->codegen->invalid_inst_src;
7480 Stage1ZirBasicBlock *after_err_block = ag->current_basic_block;
7481 if (!instr_is_unreachable(err_result))
7482 ir_mark_gen(ir_build_br(ag, parent_scope, node, end_block, is_comptime));
7483
7484 ir_set_cursor_at_end_and_append_block(ag, ok_block);
7485 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(ag, parent_scope, node, err_union_ptr, false, false);
7486 IrInstSrc *unwrapped_payload = ir_build_load_ptr(ag, parent_scope, node, unwrapped_ptr);
7487 ir_build_end_expr(ag, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base);
7488 Stage1ZirBasicBlock *after_ok_block = ag->current_basic_block;
7489 ir_build_br(ag, parent_scope, node, end_block, is_comptime);
7490
7491 ir_set_cursor_at_end_and_append_block(ag, end_block);
7492 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
7493 incoming_values[0] = err_result;
7494 incoming_values[1] = unwrapped_payload;
7495 Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
7496 incoming_blocks[0] = after_err_block;
7497 incoming_blocks[1] = after_ok_block;
7498 IrInstSrc *phi = ir_build_phi(ag, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent);
7499 return ir_lval_wrap(ag, parent_scope, phi, lval, result_loc);
7500}
7501
7502static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) {
7503 if (inner_scope == nullptr || inner_scope == outer_scope) return false;
7504 bool need_comma = render_instance_name_recursive(codegen, name, outer_scope, inner_scope->parent);
7505 if (inner_scope->id != ScopeIdVarDecl)
7506 return need_comma;
7507
7508 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope;
7509 if (need_comma)
7510 buf_append_char(name, ',');
7511 // TODO: const ptr reinterpret here to make the var type agree with the value?
7512 render_const_value(codegen, name, var_scope->var->const_value);
7513 return true;
7514}
7515
7516Buf *get_anon_type_name(CodeGen *codegen, Stage1Zir *exec, const char *kind_name,
7517 Scope *scope, AstNode *source_node, Buf *out_bare_name)
7518{
7519 if (exec != nullptr && exec->name) {
7520 ZigType *import = get_scope_import(scope);
7521 Buf *namespace_name = buf_alloc();
7522 append_namespace_qualification(codegen, namespace_name, import);
7523 buf_append_buf(namespace_name, exec->name);
7524 buf_init_from_buf(out_bare_name, exec->name);
7525 return namespace_name;
7526 } else if (exec != nullptr && exec->name_fn != nullptr) {
7527 Buf *name = buf_alloc();
7528 buf_append_buf(name, &exec->name_fn->symbol_name);
7529 buf_appendf(name, "(");
7530 render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope);
7531 buf_appendf(name, ")");
7532 buf_init_from_buf(out_bare_name, name);
7533 return name;
7534 } else {
7535 ZigType *import = get_scope_import(scope);
7536 Buf *namespace_name = buf_alloc();
7537 append_namespace_qualification(codegen, namespace_name, import);
7538 RootStruct *root_struct = source_node->owner->data.structure.root_struct;
7539 TokenLoc tok_loc = root_struct->token_locs[source_node->main_token];
7540 buf_appendf(namespace_name, "%s:%u:%u", kind_name,
7541 tok_loc.line + 1, tok_loc.column + 1);
7542 buf_init_from_buf(out_bare_name, namespace_name);
7543 return namespace_name;
7544 }
7545}
7546
7547static IrInstSrc *astgen_container_decl(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) {
7548 assert(node->type == NodeTypeContainerDecl);
7549
7550 ContainerKind kind = node->data.container_decl.kind;
7551 Buf *bare_name = buf_alloc();
7552 Buf *name = get_anon_type_name(ag->codegen, ag->exec, container_string(kind), parent_scope, node, bare_name);
7553
7554 ContainerLayout layout = node->data.container_decl.layout;
7555 ZigType *container_type = get_partial_container_type(ag->codegen, parent_scope,
7556 kind, node, buf_ptr(name), bare_name, layout);
7557 ScopeDecls *child_scope = get_container_scope(container_type);
7558
7559 for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) {
7560 AstNode *child_node = node->data.container_decl.decls.at(i);
7561 scan_decls(ag->codegen, child_scope, child_node);
7562 }
7563
7564 TldContainer *tld_container = heap::c_allocator.create<TldContainer>();
7565 init_tld(&tld_container->base, TldIdContainer, bare_name, VisibModPub, node, parent_scope);
7566 tld_container->type_entry = container_type;
7567 tld_container->decls_scope = child_scope;
7568 ag->codegen->resolve_queue.append(&tld_container->base);
7569
7570 // Add this to the list to mark as invalid if analyzing this exec fails.
7571 ag->exec->tld_list.append(&tld_container->base);
7572
7573 return ir_build_const_type(ag, parent_scope, node, container_type);
7574}
7575
7576static IrInstSrc *astgen_err_set_decl(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) {
7577 assert(node->type == NodeTypeErrorSetDecl);
7578
7579 uint32_t err_count = node->data.err_set_decl.decls.length;
7580
7581 Buf bare_name = BUF_INIT;
7582 Buf *type_name = get_anon_type_name(ag->codegen, ag->exec, "error", parent_scope, node, &bare_name);
7583 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);
7584 buf_init_from_buf(&err_set_type->name, type_name);
7585 err_set_type->data.error_set.err_count = err_count;
7586 err_set_type->size_in_bits = ag->codegen->builtin_types.entry_global_error_set->size_in_bits;
7587 err_set_type->abi_align = ag->codegen->builtin_types.entry_global_error_set->abi_align;
7588 err_set_type->abi_size = ag->codegen->builtin_types.entry_global_error_set->abi_size;
7589 err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(err_count);
7590
7591 size_t errors_count = ag->codegen->errors_by_index.length + err_count;
7592 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count);
7593
7594 for (uint32_t i = 0; i < err_count; i += 1) {
7595 AstNode *field_node = node->data.err_set_decl.decls.at(i);
7596 AstNode *symbol_node = ast_field_to_symbol_node(field_node);
7597 Buf *err_name = node_identifier_buf(symbol_node);
7598 ErrorTableEntry *err = heap::c_allocator.create<ErrorTableEntry>();
7599 err->decl_node = field_node;
7600 buf_init_from_buf(&err->name, err_name);
7601
7602 auto existing_entry = ag->codegen->error_table.put_unique(err_name, err);
7603 if (existing_entry) {
7604 err->value = existing_entry->value->value;
7605 } else {
7606 size_t error_value_count = ag->codegen->errors_by_index.length;
7607 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ag->codegen->err_tag_type->data.integral.bit_count));
7608 err->value = error_value_count;
7609 ag->codegen->errors_by_index.append(err);
7610 }
7611 err_set_type->data.error_set.errors[i] = err;
7612
7613 ErrorTableEntry *prev_err = errors[err->value];
7614 if (prev_err != nullptr) {
7615 ErrorMsg *msg = add_node_error(ag->codegen, ast_field_to_symbol_node(err->decl_node),
7616 buf_sprintf("duplicate error: '%s'", buf_ptr(&err->name)));
7617 add_error_note(ag->codegen, msg, ast_field_to_symbol_node(prev_err->decl_node),
7618 buf_sprintf("other error here"));
7619 return ag->codegen->invalid_inst_src;
7620 }
7621 errors[err->value] = err;
7622 }
7623 heap::c_allocator.deallocate(errors, errors_count);
7624 return ir_build_const_type(ag, parent_scope, node, err_set_type);
7625}
7626
7627static IrInstSrc *astgen_fn_proto(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) {
7628 assert(node->type == NodeTypeFnProto);
7629
7630 size_t param_count = node->data.fn_proto.params.length;
7631 IrInstSrc **param_types = heap::c_allocator.allocate<IrInstSrc*>(param_count);
7632
7633 bool is_var_args = false;
7634 for (size_t i = 0; i < param_count; i += 1) {
7635 AstNode *param_node = node->data.fn_proto.params.at(i);
7636 if (param_node->data.param_decl.is_var_args) {
7637 is_var_args = true;
7638 break;
7639 }
7640 if (param_node->data.param_decl.anytype_token == 0) {
7641 AstNode *type_node = param_node->data.param_decl.type;
7642 IrInstSrc *type_value = astgen_node(ag, type_node, parent_scope);
7643 if (type_value == ag->codegen->invalid_inst_src)
7644 return ag->codegen->invalid_inst_src;
7645 param_types[i] = type_value;
7646 } else {
7647 param_types[i] = nullptr;
7648 }
7649 }
7650
7651 IrInstSrc *align_value = nullptr;
7652 if (node->data.fn_proto.align_expr != nullptr) {
7653 align_value = astgen_node(ag, node->data.fn_proto.align_expr, parent_scope);
7654 if (align_value == ag->codegen->invalid_inst_src)
7655 return ag->codegen->invalid_inst_src;
7656 }
7657
7658 IrInstSrc *callconv_value = nullptr;
7659 if (node->data.fn_proto.callconv_expr != nullptr) {
7660 callconv_value = astgen_node(ag, node->data.fn_proto.callconv_expr, parent_scope);
7661 if (callconv_value == ag->codegen->invalid_inst_src)
7662 return ag->codegen->invalid_inst_src;
7663 }
7664
7665 IrInstSrc *return_type;
7666 if (node->data.fn_proto.return_type == nullptr) {
7667 return_type = ir_build_const_type(ag, parent_scope, node, ag->codegen->builtin_types.entry_void);
7668 } else {
7669 return_type = astgen_node(ag, node->data.fn_proto.return_type, parent_scope);
7670 if (return_type == ag->codegen->invalid_inst_src)
7671 return ag->codegen->invalid_inst_src;
7672 }
7673
7674 return ir_build_fn_proto(ag, parent_scope, node, param_types, align_value, callconv_value, return_type, is_var_args);
7675}
7676
7677static IrInstSrc *astgen_resume(Stage1AstGen *ag, Scope *scope, AstNode *node) {
7678 assert(node->type == NodeTypeResume);
7679
7680 IrInstSrc *target_inst = astgen_node_extra(ag, node->data.resume_expr.expr, scope, LValPtr, nullptr);
7681 if (target_inst == ag->codegen->invalid_inst_src)
7682 return ag->codegen->invalid_inst_src;
7683
7684 return ir_build_resume_src(ag, scope, node, target_inst);
7685}
7686
7687static IrInstSrc *astgen_await_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
7688 ResultLoc *result_loc)
7689{
7690 assert(node->type == NodeTypeAwaitExpr);
7691
7692 bool is_nosuspend = get_scope_nosuspend(scope) != nullptr;
7693
7694 AstNode *expr_node = node->data.await_expr.expr;
7695 if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) {
7696 AstNode *fn_ref_expr = expr_node->data.fn_call_expr.fn_ref_expr;
7697 Buf *name = node_identifier_buf(fn_ref_expr);
7698 auto entry = ag->codegen->builtin_fn_table.maybe_get(name);
7699 if (entry != nullptr) {
7700 BuiltinFnEntry *builtin_fn = entry->value;
7701 if (builtin_fn->id == BuiltinFnIdAsyncCall) {
7702 return astgen_async_call(ag, scope, node, expr_node, lval, result_loc);
7703 }
7704 }
7705 }
7706
7707 if (!ag->fn) {
7708 add_node_error(ag->codegen, node, buf_sprintf("await outside function definition"));
7709 return ag->codegen->invalid_inst_src;
7710 }
7711 ScopeSuspend *existing_suspend_scope = get_scope_suspend(scope);
7712 if (existing_suspend_scope) {
7713 if (!existing_suspend_scope->reported_err) {
7714 ErrorMsg *msg = add_node_error(ag->codegen, node, buf_sprintf("cannot await inside suspend block"));
7715 add_error_note(ag->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("suspend block here"));
7716 existing_suspend_scope->reported_err = true;
7717 }
7718 return ag->codegen->invalid_inst_src;
7719 }
7720
7721 IrInstSrc *target_inst = astgen_node_extra(ag, expr_node, scope, LValPtr, nullptr);
7722 if (target_inst == ag->codegen->invalid_inst_src)
7723 return ag->codegen->invalid_inst_src;
7724
7725 IrInstSrc *await_inst = ir_build_await_src(ag, scope, node, target_inst, result_loc, is_nosuspend);
7726 return ir_lval_wrap(ag, scope, await_inst, lval, result_loc);
7727}
7728
7729static IrInstSrc *astgen_suspend(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) {
7730 assert(node->type == NodeTypeSuspend);
7731
7732 if (!ag->fn) {
7733 add_node_error(ag->codegen, node, buf_sprintf("suspend outside function definition"));
7734 return ag->codegen->invalid_inst_src;
7735 }
7736 if (get_scope_nosuspend(parent_scope) != nullptr) {
7737 add_node_error(ag->codegen, node, buf_sprintf("suspend in nosuspend scope"));
7738 return ag->codegen->invalid_inst_src;
7739 }
7740
7741 ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope);
7742 if (existing_suspend_scope) {
7743 if (!existing_suspend_scope->reported_err) {
7744 ErrorMsg *msg = add_node_error(ag->codegen, node, buf_sprintf("cannot suspend inside suspend block"));
7745 add_error_note(ag->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here"));
7746 existing_suspend_scope->reported_err = true;
7747 }
7748 return ag->codegen->invalid_inst_src;
7749 }
7750
7751 IrInstSrcSuspendBegin *begin = ir_build_suspend_begin_src(ag, parent_scope, node);
7752 ScopeSuspend *suspend_scope = create_suspend_scope(ag->codegen, node, parent_scope);
7753 Scope *child_scope = &suspend_scope->base;
7754 IrInstSrc *susp_res = astgen_node(ag, node->data.suspend.block, child_scope);
7755 if (susp_res == ag->codegen->invalid_inst_src)
7756 return ag->codegen->invalid_inst_src;
7757 ir_mark_gen(ir_build_check_statement_is_void(ag, child_scope, node->data.suspend.block, susp_res));
7758
7759 return ir_mark_gen(ir_build_suspend_finish_src(ag, parent_scope, node, begin));
7760}
7761
7762static IrInstSrc *astgen_node_raw(Stage1AstGen *ag, AstNode *node, Scope *scope,
7763 LVal lval, ResultLoc *result_loc)
7764{
7765 assert(scope);
7766 switch (node->type) {
7767 case NodeTypeStructValueField:
7768 case NodeTypeParamDecl:
7769 case NodeTypeUsingNamespace:
7770 case NodeTypeSwitchProng:
7771 case NodeTypeSwitchRange:
7772 case NodeTypeStructField:
7773 case NodeTypeErrorSetField:
7774 case NodeTypeFnDef:
7775 case NodeTypeTestDecl:
7776 zig_unreachable();
7777 case NodeTypeBlock:
7778 return astgen_block(ag, scope, node, lval, result_loc);
7779 case NodeTypeGroupedExpr:
7780 return astgen_node_raw(ag, node->data.grouped_expr, scope, lval, result_loc);
7781 case NodeTypeBinOpExpr:
7782 return astgen_bin_op(ag, scope, node, lval, result_loc);
7783 case NodeTypeIntLiteral:
7784 return ir_lval_wrap(ag, scope, astgen_int_lit(ag, scope, node), lval, result_loc);
7785 case NodeTypeFloatLiteral:
7786 return ir_lval_wrap(ag, scope, astgen_float_lit(ag, scope, node), lval, result_loc);
7787 case NodeTypeCharLiteral:
7788 return ir_lval_wrap(ag, scope, astgen_char_lit(ag, scope, node), lval, result_loc);
7789 case NodeTypeIdentifier:
7790 return astgen_identifier(ag, scope, node, lval, result_loc);
7791 case NodeTypeFnCallExpr:
7792 return astgen_fn_call(ag, scope, node, lval, result_loc);
7793 case NodeTypeIfBoolExpr:
7794 return astgen_if_bool_expr(ag, scope, node, lval, result_loc);
7795 case NodeTypePrefixOpExpr:
7796 return astgen_prefix_op_expr(ag, scope, node, lval, result_loc);
7797 case NodeTypeContainerInitExpr:
7798 return astgen_container_init_expr(ag, scope, node, lval, result_loc);
7799 case NodeTypeVariableDeclaration:
7800 return astgen_var_decl(ag, scope, node);
7801 case NodeTypeWhileExpr:
7802 return astgen_while_expr(ag, scope, node, lval, result_loc);
7803 case NodeTypeForExpr:
7804 return astgen_for_expr(ag, scope, node, lval, result_loc);
7805 case NodeTypeArrayAccessExpr:
7806 return astgen_array_access(ag, scope, node, lval, result_loc);
7807 case NodeTypeReturnExpr:
7808 return astgen_return(ag, scope, node, lval, result_loc);
7809 case NodeTypeFieldAccessExpr:
7810 {
7811 IrInstSrc *ptr_instruction = astgen_field_access(ag, scope, node);
7812 if (ptr_instruction == ag->codegen->invalid_inst_src)
7813 return ptr_instruction;
7814 if (lval == LValPtr || lval == LValAssign)
7815 return ptr_instruction;
7816
7817 IrInstSrc *load_ptr = ir_build_load_ptr(ag, scope, node, ptr_instruction);
7818 return ir_expr_wrap(ag, scope, load_ptr, result_loc);
7819 }
7820 case NodeTypePtrDeref: {
7821 AstNode *expr_node = node->data.ptr_deref_expr.target;
7822
7823 LVal child_lval = lval;
7824 if (child_lval == LValAssign)
7825 child_lval = LValPtr;
7826
7827 IrInstSrc *value = astgen_node_extra(ag, expr_node, scope, child_lval, nullptr);
7828 if (value == ag->codegen->invalid_inst_src)
7829 return value;
7830
7831 // We essentially just converted any lvalue from &(x.*) to (&x).*;
7832 // this inhibits checking that x is a pointer later, so we directly
7833 // record whether the pointer check is needed
7834 IrInstSrc *un_op = ir_build_un_op_lval(ag, scope, node, IrUnOpDereference, value, lval, result_loc);
7835 return ir_expr_wrap(ag, scope, un_op, result_loc);
7836 }
7837 case NodeTypeUnwrapOptional: {
7838 AstNode *expr_node = node->data.unwrap_optional.expr;
7839
7840 IrInstSrc *maybe_ptr = astgen_node_extra(ag, expr_node, scope, LValPtr, nullptr);
7841 if (maybe_ptr == ag->codegen->invalid_inst_src)
7842 return ag->codegen->invalid_inst_src;
7843
7844 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(ag, scope, node, maybe_ptr, true );
7845 if (lval == LValPtr || lval == LValAssign)
7846 return unwrapped_ptr;
7847
7848 IrInstSrc *load_ptr = ir_build_load_ptr(ag, scope, node, unwrapped_ptr);
7849 return ir_expr_wrap(ag, scope, load_ptr, result_loc);
7850 }
7851 case NodeTypeBoolLiteral:
7852 return ir_lval_wrap(ag, scope, astgen_bool_literal(ag, scope, node), lval, result_loc);
7853 case NodeTypeArrayType:
7854 return ir_lval_wrap(ag, scope, astgen_array_type(ag, scope, node), lval, result_loc);
7855 case NodeTypePointerType:
7856 return ir_lval_wrap(ag, scope, astgen_pointer_type(ag, scope, node), lval, result_loc);
7857 case NodeTypeAnyFrameType:
7858 return ir_lval_wrap(ag, scope, astgen_anyframe_type(ag, scope, node), lval, result_loc);
7859 case NodeTypeStringLiteral:
7860 return ir_lval_wrap(ag, scope, astgen_string_literal(ag, scope, node), lval, result_loc);
7861 case NodeTypeUndefinedLiteral:
7862 return ir_lval_wrap(ag, scope, astgen_undefined_literal(ag, scope, node), lval, result_loc);
7863 case NodeTypeAsmExpr:
7864 return ir_lval_wrap(ag, scope, astgen_asm_expr(ag, scope, node), lval, result_loc);
7865 case NodeTypeNullLiteral:
7866 return ir_lval_wrap(ag, scope, astgen_null_literal(ag, scope, node), lval, result_loc);
7867 case NodeTypeIfErrorExpr:
7868 return astgen_if_err_expr(ag, scope, node, lval, result_loc);
7869 case NodeTypeIfOptional:
7870 return astgen_if_optional_expr(ag, scope, node, lval, result_loc);
7871 case NodeTypeSwitchExpr:
7872 return astgen_switch_expr(ag, scope, node, lval, result_loc);
7873 case NodeTypeCompTime:
7874 return ir_expr_wrap(ag, scope, astgen_comptime(ag, scope, node, lval), result_loc);
7875 case NodeTypeNoSuspend:
7876 return ir_expr_wrap(ag, scope, astgen_nosuspend(ag, scope, node, lval), result_loc);
7877 case NodeTypeErrorType:
7878 return ir_lval_wrap(ag, scope, astgen_error_type(ag, scope, node), lval, result_loc);
7879 case NodeTypeBreak:
7880 return ir_lval_wrap(ag, scope, astgen_break(ag, scope, node), lval, result_loc);
7881 case NodeTypeContinue:
7882 return ir_lval_wrap(ag, scope, astgen_continue(ag, scope, node), lval, result_loc);
7883 case NodeTypeUnreachable:
7884 return ir_build_unreachable(ag, scope, node);
7885 case NodeTypeDefer:
7886 return ir_lval_wrap(ag, scope, astgen_defer(ag, scope, node), lval, result_loc);
7887 case NodeTypeSliceExpr:
7888 return astgen_slice(ag, scope, node, lval, result_loc);
7889 case NodeTypeCatchExpr:
7890 return astgen_catch(ag, scope, node, lval, result_loc);
7891 case NodeTypeContainerDecl:
7892 return ir_lval_wrap(ag, scope, astgen_container_decl(ag, scope, node), lval, result_loc);
7893 case NodeTypeFnProto:
7894 return ir_lval_wrap(ag, scope, astgen_fn_proto(ag, scope, node), lval, result_loc);
7895 case NodeTypeErrorSetDecl:
7896 return ir_lval_wrap(ag, scope, astgen_err_set_decl(ag, scope, node), lval, result_loc);
7897 case NodeTypeResume:
7898 return ir_lval_wrap(ag, scope, astgen_resume(ag, scope, node), lval, result_loc);
7899 case NodeTypeAwaitExpr:
7900 return astgen_await_expr(ag, scope, node, lval, result_loc);
7901 case NodeTypeSuspend:
7902 return ir_lval_wrap(ag, scope, astgen_suspend(ag, scope, node), lval, result_loc);
7903 case NodeTypeEnumLiteral:
7904 return ir_lval_wrap(ag, scope, astgen_enum_literal(ag, scope, node), lval, result_loc);
7905 case NodeTypeInferredArrayType:
7906 add_node_error(ag->codegen, node,
7907 buf_sprintf("inferred array size invalid here"));
7908 return ag->codegen->invalid_inst_src;
7909 case NodeTypeAnyTypeField:
7910 return ir_lval_wrap(ag, scope,
7911 ir_build_const_type(ag, scope, node, ag->codegen->builtin_types.entry_anytype), lval, result_loc);
7912 }
7913 zig_unreachable();
7914}
7915
7916ResultLoc *no_result_loc(void) {
7917 ResultLocNone *result_loc_none = heap::c_allocator.create<ResultLocNone>();
7918 result_loc_none->base.id = ResultLocIdNone;
7919 return &result_loc_none->base;
7920}
7921
7922static IrInstSrc *astgen_node_extra(Stage1AstGen *ag, AstNode *node, Scope *scope, LVal lval,
7923 ResultLoc *result_loc)
7924{
7925 if (lval == LValAssign) {
7926 switch (node->type) {
7927 case NodeTypeStructValueField:
7928 case NodeTypeParamDecl:
7929 case NodeTypeUsingNamespace:
7930 case NodeTypeSwitchProng:
7931 case NodeTypeSwitchRange:
7932 case NodeTypeStructField:
7933 case NodeTypeErrorSetField:
7934 case NodeTypeFnDef:
7935 case NodeTypeTestDecl:
7936 zig_unreachable();
7937
7938 // cannot be assigned to
7939 case NodeTypeBlock:
7940 case NodeTypeGroupedExpr:
7941 case NodeTypeBinOpExpr:
7942 case NodeTypeIntLiteral:
7943 case NodeTypeFloatLiteral:
7944 case NodeTypeCharLiteral:
7945 case NodeTypeIfBoolExpr:
7946 case NodeTypeContainerInitExpr:
7947 case NodeTypeVariableDeclaration:
7948 case NodeTypeWhileExpr:
7949 case NodeTypeForExpr:
7950 case NodeTypeReturnExpr:
7951 case NodeTypeBoolLiteral:
7952 case NodeTypeArrayType:
7953 case NodeTypePointerType:
7954 case NodeTypeAnyFrameType:
7955 case NodeTypeStringLiteral:
7956 case NodeTypeUndefinedLiteral:
7957 case NodeTypeAsmExpr:
7958 case NodeTypeNullLiteral:
7959 case NodeTypeIfErrorExpr:
7960 case NodeTypeIfOptional:
7961 case NodeTypeSwitchExpr:
7962 case NodeTypeCompTime:
7963 case NodeTypeNoSuspend:
7964 case NodeTypeErrorType:
7965 case NodeTypeBreak:
7966 case NodeTypeContinue:
7967 case NodeTypeUnreachable:
7968 case NodeTypeDefer:
7969 case NodeTypeSliceExpr:
7970 case NodeTypeCatchExpr:
7971 case NodeTypeContainerDecl:
7972 case NodeTypeFnProto:
7973 case NodeTypeErrorSetDecl:
7974 case NodeTypeResume:
7975 case NodeTypeAwaitExpr:
7976 case NodeTypeSuspend:
7977 case NodeTypeEnumLiteral:
7978 case NodeTypeInferredArrayType:
7979 case NodeTypeAnyTypeField:
7980 case NodeTypePrefixOpExpr:
7981 add_node_error(ag->codegen, node,
7982 buf_sprintf("invalid left-hand side to assignment"));
7983 return ag->codegen->invalid_inst_src;
7984
7985 // @field can be assigned to
7986 case NodeTypeFnCallExpr:
7987 if (node->data.fn_call_expr.modifier == CallModifierBuiltin) {
7988 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
7989 Buf *name = node_identifier_buf(fn_ref_expr);
7990 auto entry = ag->codegen->builtin_fn_table.maybe_get(name);
7991
7992 if (!entry) {
7993 add_node_error(ag->codegen, node,
7994 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name)));
7995 return ag->codegen->invalid_inst_src;
7996 }
7997
7998 if (entry->value->id == BuiltinFnIdField) {
7999 break;
8000 }
8001 }
8002 add_node_error(ag->codegen, node,
8003 buf_sprintf("invalid left-hand side to assignment"));
8004 return ag->codegen->invalid_inst_src;
8005
8006
8007 // can be assigned to
8008 case NodeTypeUnwrapOptional:
8009 case NodeTypePtrDeref:
8010 case NodeTypeFieldAccessExpr:
8011 case NodeTypeArrayAccessExpr:
8012 case NodeTypeIdentifier:
8013 break;
8014 }
8015 }
8016 if (result_loc == nullptr) {
8017 // Create a result location indicating there is none - but if one gets created
8018 // it will be properly distributed.
8019 result_loc = no_result_loc();
8020 ir_build_reset_result(ag, scope, node, result_loc);
8021 }
8022 Scope *child_scope;
8023 if (ag->exec->is_inline ||
8024 (ag->fn != nullptr && ag->fn->child_scope == scope))
8025 {
8026 child_scope = scope;
8027 } else {
8028 child_scope = &create_expr_scope(ag->codegen, node, scope)->base;
8029 }
8030 IrInstSrc *result = astgen_node_raw(ag, node, child_scope, lval, result_loc);
8031 if (result == ag->codegen->invalid_inst_src) {
8032 if (ag->exec->first_err_trace_msg == nullptr) {
8033 ag->exec->first_err_trace_msg = ag->codegen->trace_err;
8034 }
8035 }
8036 return result;
8037}
8038
8039static IrInstSrc *astgen_node(Stage1AstGen *ag, AstNode *node, Scope *scope) {
8040 return astgen_node_extra(ag, node, scope, LValNone, nullptr);
8041}
8042
8043bool stage1_astgen(CodeGen *codegen, AstNode *node, Scope *scope, Stage1Zir *stage1_zir,
8044 ZigFn *fn, bool in_c_import_scope)
8045{
8046 assert(node->owner);
8047
8048 Stage1AstGen ir_builder = {0};
8049 Stage1AstGen *ag = &ir_builder;
8050
8051 ag->codegen = codegen;
8052 ag->fn = fn;
8053 ag->in_c_import_scope = in_c_import_scope;
8054 ag->exec = stage1_zir;
8055 ag->main_block_node = node;
8056
8057 Stage1ZirBasicBlock *entry_block = ir_create_basic_block(ag, scope, "Entry");
8058 ir_set_cursor_at_end_and_append_block(ag, entry_block);
8059 // Entry block gets a reference because we enter it to begin.
8060 ir_ref_bb(ag->current_basic_block);
8061
8062 IrInstSrc *result = astgen_node_extra(ag, node, scope, LValNone, nullptr);
8063
8064 if (result == ag->codegen->invalid_inst_src)
8065 return false;
8066
8067 if (ag->exec->first_err_trace_msg != nullptr) {
8068 codegen->trace_err = ag->exec->first_err_trace_msg;
8069 return false;
8070 }
8071
8072 if (!instr_is_unreachable(result)) {
8073 ir_mark_gen(ir_build_add_implicit_return_type(ag, scope, result->base.source_node, result, nullptr));
8074 // no need for save_err_ret_addr because this cannot return error
8075 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
8076 result_loc_ret->base.id = ResultLocIdReturn;
8077 ir_build_reset_result(ag, scope, node, &result_loc_ret->base);
8078 ir_mark_gen(ir_build_end_expr(ag, scope, node, result, &result_loc_ret->base));
8079 ir_mark_gen(ir_build_return_src(ag, scope, result->base.source_node, result));
8080 }
8081
8082 return true;
8083}
8084
8085bool stage1_astgen_fn(CodeGen *codegen, ZigFn *fn) {
8086 assert(fn != nullptr);
8087 assert(fn->child_scope != nullptr);
8088 return stage1_astgen(codegen, fn->body_node, fn->child_scope, fn->stage1_zir, fn, false);
8089}
8090
8091void invalidate_exec(Stage1Zir *exec, ErrorMsg *msg) {
8092 if (exec->first_err_trace_msg != nullptr)
8093 return;
8094
8095 exec->first_err_trace_msg = msg;
8096
8097 for (size_t i = 0; i < exec->tld_list.length; i += 1) {
8098 exec->tld_list.items[i]->resolution = TldResolutionInvalid;
8099 }
8100}
8101
8102AstNode *ast_field_to_symbol_node(AstNode *err_set_field_node) {
8103 if (err_set_field_node->type == NodeTypeIdentifier) {
8104 return err_set_field_node;
8105 } else if (err_set_field_node->type == NodeTypeErrorSetField) {
8106 assert(err_set_field_node->data.err_set_field.field_name->type == NodeTypeIdentifier);
8107 return err_set_field_node->data.err_set_field.field_name;
8108 } else {
8109 return err_set_field_node;
8110 }
8111}
8112
8113void ir_add_call_stack_errors_gen(CodeGen *codegen, Stage1Air *exec, ErrorMsg *err_msg, int limit) {
8114 if (!exec || !exec->source_node || limit < 0) return;
8115 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here"));
8116
8117 ir_add_call_stack_errors_gen(codegen, exec->parent_exec, err_msg, limit - 1);
8118}
8119
src/stage1/astgen.hpp created+37
......@@ -0,0 +1,37 @@
1/*
2 * Copyright (c) 2021 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_ASTGEN_HPP
9#define ZIG_ASTGEN_HPP
10
11#include "all_types.hpp"
12
13bool stage1_astgen(CodeGen *g, AstNode *node, Scope *scope, Stage1Zir *stage1_zir,
14 ZigFn *fn, bool in_c_import_scope);
15bool stage1_astgen_fn(CodeGen *g, ZigFn *fn_entry);
16
17bool ir_inst_src_has_side_effects(IrInstSrc *inst);
18
19ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
20 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime,
21 bool skip_name_check);
22
23ResultLoc *no_result_loc(void);
24
25void invalidate_exec(Stage1Zir *exec, ErrorMsg *msg);
26
27AstNode *ast_field_to_symbol_node(AstNode *err_set_field_node);
28void ir_add_call_stack_errors_gen(CodeGen *codegen, Stage1Air *exec, ErrorMsg *err_msg,
29 int limit);
30
31void destroy_instruction_src(IrInstSrc *inst);
32
33bool ir_should_inline(Stage1Zir *exec, Scope *scope);
34Buf *get_anon_type_name(CodeGen *codegen, Stage1Zir *exec, const char *kind_name,
35 Scope *scope, AstNode *source_node, Buf *out_bare_name);
36
37#endif
src/stage1/bigfloat.cpp+1-2
......@@ -69,7 +69,7 @@ void bigfloat_init_bigint(BigFloat *dest, const BigInt *op) {
6969 }
7070}
7171
72Error bigfloat_init_buf(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len) {
72Error bigfloat_init_buf(BigFloat *dest, const uint8_t *buf_ptr) {
7373 char *str_begin = (char *)buf_ptr;
7474 char *str_end;
7575
......@@ -79,7 +79,6 @@ Error bigfloat_init_buf(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len)
7979 return ErrorOverflow;
8080 }
8181
82 assert(str_end <= ((char*)buf_ptr) + buf_len);
8382 return ErrorNone;
8483}
8584
src/stage1/bigfloat.hpp+1-1
......@@ -28,7 +28,7 @@ void bigfloat_init_64(BigFloat *dest, double x);
2828void bigfloat_init_128(BigFloat *dest, float128_t x);
2929void bigfloat_init_bigfloat(BigFloat *dest, const BigFloat *x);
3030void bigfloat_init_bigint(BigFloat *dest, const BigInt *op);
31Error bigfloat_init_buf(BigFloat *dest, const uint8_t *buf_ptr, size_t buf_len);
31Error bigfloat_init_buf(BigFloat *dest, const uint8_t *buf_ptr);
3232
3333float16_t bigfloat_to_f16(const BigFloat *bigfloat);
3434float bigfloat_to_f32(const BigFloat *bigfloat);
src/stage1/codegen.cpp+119-107
......@@ -6,7 +6,6 @@
66 */
77
88#include "analyze.hpp"
9#include "ast_render.hpp"
109#include "codegen.hpp"
1110#include "errmsg.hpp"
1211#include "error.hpp"
......@@ -642,6 +641,18 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn) {
642641 return fn->llvm_value;
643642}
644643
644static uint32_t node_line_onebased(AstNode *node) {
645 RootStruct *root_struct = node->owner->data.structure.root_struct;
646 assert(node->main_token < root_struct->token_count);
647 return root_struct->token_locs[node->main_token].line + 1;
648}
649
650static uint32_t node_column_onebased(AstNode *node) {
651 RootStruct *root_struct = node->owner->data.structure.root_struct;
652 assert(node->main_token < root_struct->token_count);
653 return root_struct->token_locs[node->main_token].column + 1;
654}
655
645656static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
646657 if (scope->di_scope)
647658 return scope->di_scope;
......@@ -657,8 +668,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
657668 ZigFn *fn_table_entry = fn_scope->fn_entry;
658669 if (!fn_table_entry->proto_node)
659670 return get_di_scope(g, scope->parent);
660 unsigned line_number = (unsigned)(fn_table_entry->proto_node->line == 0) ?
661 0 : (fn_table_entry->proto_node->line + 1);
671 unsigned line_number = node_line_onebased(fn_table_entry->proto_node);
662672 unsigned scope_line = line_number;
663673 bool is_definition = fn_table_entry->body_node != nullptr;
664674 bool is_optimized = g->build_mode != BuildModeDebug;
......@@ -696,8 +706,8 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
696706 ZigLLVMDILexicalBlock *di_block = ZigLLVMCreateLexicalBlock(g->dbuilder,
697707 get_di_scope(g, scope->parent),
698708 import->data.structure.root_struct->di_file,
699 (unsigned)scope->source_node->line + 1,
700 (unsigned)scope->source_node->column + 1);
709 node_line_onebased(scope->source_node),
710 node_column_onebased(scope->source_node));
701711 scope->di_scope = ZigLLVMLexicalBlockToScope(di_block);
702712 return scope->di_scope;
703713 }
......@@ -1798,8 +1808,8 @@ static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {
17981808 if (g->strip_debug_symbols) return;
17991809 assert(var->di_loc_var != nullptr);
18001810 AstNode *source_node = var->decl_node;
1801 ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc((unsigned)source_node->line + 1,
1802 (unsigned)source_node->column + 1, get_di_scope(g, var->parent_scope));
1811 ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc(node_line_onebased(source_node),
1812 node_column_onebased(source_node), get_di_scope(g, var->parent_scope));
18031813 ZigLLVMInsertDeclareAtEnd(g->dbuilder, var->value_ref, var->di_loc_var, debug_loc,
18041814 LLVMGetInsertBlock(g->builder));
18051815}
......@@ -2198,7 +2208,7 @@ var_ok:
21982208 // arg index + 1 because the 0 index is return value
21992209 var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
22002210 var->name, fn_walk->data.vars.import->data.structure.root_struct->di_file,
2201 (unsigned)(var->decl_node->line + 1),
2211 node_line_onebased(var->decl_node),
22022212 get_llvm_di_type(g, dest_ty), !g->strip_debug_symbols, 0, di_arg_index + 1);
22032213 }
22042214 return true;
......@@ -2433,7 +2443,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
24332443 return fn_val;
24342444
24352445}
2436static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutableGen *executable,
2446static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, Stage1Air *executable,
24372447 IrInstGenSaveErrRetAddr *save_err_ret_addr_instruction)
24382448{
24392449 assert(g->have_err_ret_tracing);
......@@ -2626,7 +2636,7 @@ static void gen_async_return(CodeGen *g, IrInstGenReturn *instruction) {
26262636 LLVMBuildRetVoid(g->builder);
26272637}
26282638
2629static LLVMValueRef ir_render_return(CodeGen *g, IrExecutableGen *executable, IrInstGenReturn *instruction) {
2639static LLVMValueRef ir_render_return(CodeGen *g, Stage1Air *executable, IrInstGenReturn *instruction) {
26302640 if (fn_is_async(g->cur_fn)) {
26312641 gen_async_return(g, instruction);
26322642 return nullptr;
......@@ -3051,7 +3061,7 @@ static void gen_shift_rhs_check(CodeGen *g, ZigType *lhs_type, ZigType *rhs_type
30513061 }
30523062}
30533063
3054static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutableGen *executable,
3064static LLVMValueRef ir_render_bin_op(CodeGen *g, Stage1Air *executable,
30553065 IrInstGenBinOp *bin_op_instruction)
30563066{
30573067 IrBinOp op_id = bin_op_instruction->op_id;
......@@ -3273,7 +3283,7 @@ static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *in
32733283 }
32743284}
32753285
3276static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,
3286static LLVMValueRef ir_render_cast(CodeGen *g, Stage1Air *executable,
32773287 IrInstGenCast *cast_instruction)
32783288{
32793289 Error err;
......@@ -3357,7 +3367,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,
33573367 zig_unreachable();
33583368}
33593369
3360static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutableGen *executable,
3370static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, Stage1Air *executable,
33613371 IrInstGenPtrOfArrayToSlice *instruction)
33623372{
33633373 ZigType *actual_type = instruction->operand->value->type;
......@@ -3394,7 +3404,7 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutableGen
33943404 return result_loc;
33953405}
33963406
3397static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutableGen *executable,
3407static LLVMValueRef ir_render_ptr_cast(CodeGen *g, Stage1Air *executable,
33983408 IrInstGenPtrCast *instruction)
33993409{
34003410 ZigType *wanted_type = instruction->base.value->type;
......@@ -3420,7 +3430,7 @@ static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutableGen *executable,
34203430 return result_ptr;
34213431}
34223432
3423static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutableGen *executable,
3433static LLVMValueRef ir_render_bit_cast(CodeGen *g, Stage1Air *executable,
34243434 IrInstGenBitCast *instruction)
34253435{
34263436 ZigType *wanted_type = instruction->base.value->type;
......@@ -3448,7 +3458,7 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutableGen *executable,
34483458 }
34493459}
34503460
3451static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutableGen *executable,
3461static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, Stage1Air *executable,
34523462 IrInstGenWidenOrShorten *instruction)
34533463{
34543464 ZigType *actual_type = instruction->target->value->type;
......@@ -3465,7 +3475,7 @@ static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutableGen *exec
34653475 instruction->base.value->type, target_val);
34663476}
34673477
3468static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenIntToPtr *instruction) {
3478static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, Stage1Air *executable, IrInstGenIntToPtr *instruction) {
34693479 ZigType *wanted_type = instruction->base.value->type;
34703480 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
34713481 const uint32_t align_bytes = get_ptr_align(g, wanted_type);
......@@ -3503,13 +3513,13 @@ static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutableGen *executable
35033513 return LLVMBuildIntToPtr(g->builder, target_val, get_llvm_type(g, wanted_type), "");
35043514}
35053515
3506static LLVMValueRef ir_render_ptr_to_int(CodeGen *g, IrExecutableGen *executable, IrInstGenPtrToInt *instruction) {
3516static LLVMValueRef ir_render_ptr_to_int(CodeGen *g, Stage1Air *executable, IrInstGenPtrToInt *instruction) {
35073517 ZigType *wanted_type = instruction->base.value->type;
35083518 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
35093519 return LLVMBuildPtrToInt(g->builder, target_val, get_llvm_type(g, wanted_type), "");
35103520}
35113521
3512static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutableGen *executable, IrInstGenIntToEnum *instruction) {
3522static LLVMValueRef ir_render_int_to_enum(CodeGen *g, Stage1Air *executable, IrInstGenIntToEnum *instruction) {
35133523 ZigType *wanted_type = instruction->base.value->type;
35143524 assert(wanted_type->id == ZigTypeIdEnum);
35153525 ZigType *tag_int_type = wanted_type->data.enumeration.tag_int_type;
......@@ -3549,7 +3559,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutableGen *executabl
35493559 return tag_int_value;
35503560}
35513561
3552static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutableGen *executable, IrInstGenIntToErr *instruction) {
3562static LLVMValueRef ir_render_int_to_err(CodeGen *g, Stage1Air *executable, IrInstGenIntToErr *instruction) {
35533563 ZigType *wanted_type = instruction->base.value->type;
35543564 assert(wanted_type->id == ZigTypeIdErrorSet);
35553565
......@@ -3566,7 +3576,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutableGen *executable
35663576 return gen_widen_or_shorten(g, false, actual_type, g->err_tag_type, target_val);
35673577}
35683578
3569static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutableGen *executable, IrInstGenErrToInt *instruction) {
3579static LLVMValueRef ir_render_err_to_int(CodeGen *g, Stage1Air *executable, IrInstGenErrToInt *instruction) {
35703580 ZigType *wanted_type = instruction->base.value->type;
35713581 assert(wanted_type->id == ZigTypeIdInt);
35723582 assert(!wanted_type->data.integral.is_signed);
......@@ -3592,7 +3602,7 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutableGen *executable
35923602 }
35933603}
35943604
3595static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutableGen *executable,
3605static LLVMValueRef ir_render_unreachable(CodeGen *g, Stage1Air *executable,
35963606 IrInstGenUnreachable *unreachable_instruction)
35973607{
35983608 if (ir_want_runtime_safety(g, &unreachable_instruction->base)) {
......@@ -3603,7 +3613,7 @@ static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutableGen *executabl
36033613 return nullptr;
36043614}
36053615
3606static LLVMValueRef ir_render_cond_br(CodeGen *g, IrExecutableGen *executable,
3616static LLVMValueRef ir_render_cond_br(CodeGen *g, Stage1Air *executable,
36073617 IrInstGenCondBr *cond_br_instruction)
36083618{
36093619 LLVMBuildCondBr(g->builder,
......@@ -3613,12 +3623,12 @@ static LLVMValueRef ir_render_cond_br(CodeGen *g, IrExecutableGen *executable,
36133623 return nullptr;
36143624}
36153625
3616static LLVMValueRef ir_render_br(CodeGen *g, IrExecutableGen *executable, IrInstGenBr *br_instruction) {
3626static LLVMValueRef ir_render_br(CodeGen *g, Stage1Air *executable, IrInstGenBr *br_instruction) {
36173627 LLVMBuildBr(g->builder, br_instruction->dest_block->llvm_block);
36183628 return nullptr;
36193629}
36203630
3621static LLVMValueRef ir_render_binary_not(CodeGen *g, IrExecutableGen *executable,
3631static LLVMValueRef ir_render_binary_not(CodeGen *g, Stage1Air *executable,
36223632 IrInstGenBinaryNot *inst)
36233633{
36243634 LLVMValueRef operand = ir_llvm_value(g, inst->operand);
......@@ -3650,13 +3660,13 @@ static LLVMValueRef ir_gen_negation(CodeGen *g, IrInstGen *inst, IrInstGen *oper
36503660 }
36513661}
36523662
3653static LLVMValueRef ir_render_negation(CodeGen *g, IrExecutableGen *executable,
3663static LLVMValueRef ir_render_negation(CodeGen *g, Stage1Air *executable,
36543664 IrInstGenNegation *inst)
36553665{
36563666 return ir_gen_negation(g, &inst->base, inst->operand, inst->wrapping);
36573667}
36583668
3659static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutableGen *executable, IrInstGenBoolNot *instruction) {
3669static LLVMValueRef ir_render_bool_not(CodeGen *g, Stage1Air *executable, IrInstGenBoolNot *instruction) {
36603670 LLVMValueRef value = ir_llvm_value(g, instruction->value);
36613671 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(value));
36623672 return LLVMBuildICmp(g->builder, LLVMIntEQ, value, zero, "");
......@@ -3670,14 +3680,14 @@ static void render_decl_var(CodeGen *g, ZigVar *var) {
36703680 gen_var_debug_decl(g, var);
36713681}
36723682
3673static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutableGen *executable, IrInstGenDeclVar *instruction) {
3683static LLVMValueRef ir_render_decl_var(CodeGen *g, Stage1Air *executable, IrInstGenDeclVar *instruction) {
36743684 instruction->var->ptr_instruction = instruction->var_ptr;
36753685 instruction->var->did_the_decl_codegen = true;
36763686 render_decl_var(g, instruction->var);
36773687 return nullptr;
36783688}
36793689
3680static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutableGen *executable,
3690static LLVMValueRef ir_render_load_ptr(CodeGen *g, Stage1Air *executable,
36813691 IrInstGenLoadPtr *instruction)
36823692{
36833693 ZigType *child_type = instruction->base.value->type;
......@@ -3879,7 +3889,7 @@ static void gen_undef_init(CodeGen *g, ZigType *ptr_type, ZigType *value_type, L
38793889 gen_assign_raw(g, ptr, ptr_type, zero);
38803890}
38813891
3882static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenStorePtr *instruction) {
3892static LLVMValueRef ir_render_store_ptr(CodeGen *g, Stage1Air *executable, IrInstGenStorePtr *instruction) {
38833893 Error err;
38843894
38853895 ZigType *ptr_type = instruction->ptr->value->type;
......@@ -3911,7 +3921,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutableGen *executable,
39113921 return nullptr;
39123922}
39133923
3914static LLVMValueRef ir_render_vector_store_elem(CodeGen *g, IrExecutableGen *executable,
3924static LLVMValueRef ir_render_vector_store_elem(CodeGen *g, Stage1Air *executable,
39153925 IrInstGenVectorStoreElem *instruction)
39163926{
39173927 LLVMValueRef vector_ptr = ir_llvm_value(g, instruction->vector_ptr);
......@@ -3924,7 +3934,7 @@ static LLVMValueRef ir_render_vector_store_elem(CodeGen *g, IrExecutableGen *exe
39243934 return nullptr;
39253935}
39263936
3927static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenVarPtr *instruction) {
3937static LLVMValueRef ir_render_var_ptr(CodeGen *g, Stage1Air *executable, IrInstGenVarPtr *instruction) {
39283938 Error err;
39293939
39303940 ZigType *ptr_type = instruction->base.value->type;
......@@ -3951,7 +3961,7 @@ static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutableGen *executable, I
39513961 get_llvm_type(g, ptr_type), "");
39523962}
39533963
3954static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutableGen *executable,
3964static LLVMValueRef ir_render_return_ptr(CodeGen *g, Stage1Air *executable,
39553965 IrInstGenReturnPtr *instruction)
39563966{
39573967 if (!type_has_bits(g, instruction->base.value->type))
......@@ -3960,7 +3970,7 @@ static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutableGen *executable
39603970 return g->cur_ret_ptr;
39613971}
39623972
3963static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutableGen *executable, IrInstGenElemPtr *instruction) {
3973static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, IrInstGenElemPtr *instruction) {
39643974 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr);
39653975 ZigType *array_ptr_type = instruction->array_ptr->value->type;
39663976 assert(array_ptr_type->id == ZigTypeIdPointer);
......@@ -4126,7 +4136,7 @@ static void render_async_spills(CodeGen *g) {
41264136 if (var->decl_node) {
41274137 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
41284138 var->name, import->data.structure.root_struct->di_file,
4129 (unsigned)(var->decl_node->line + 1),
4139 node_line_onebased(var->decl_node),
41304140 get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);
41314141 gen_var_debug_decl(g, var);
41324142 }
......@@ -4212,7 +4222,7 @@ static void gen_init_stack_trace(CodeGen *g, LLVMValueRef trace_field_ptr, LLVMV
42124222 LLVMBuildStore(g->builder, LLVMConstInt(usize_type_ref, stack_trace_ptr_count, false), addrs_len_ptr);
42134223}
42144224
4215static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrInstGenCall *instruction) {
4225static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, IrInstGenCall *instruction) {
42164226 Error err;
42174227
42184228 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
......@@ -4632,7 +4642,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
46324642 }
46334643}
46344644
4635static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutableGen *executable,
4645static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, Stage1Air *executable,
46364646 IrInstGenStructFieldPtr *instruction)
46374647{
46384648 Error err;
......@@ -4683,7 +4693,7 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutableGen *exec
46834693 return field_ptr_val;
46844694}
46854695
4686static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutableGen *executable,
4696static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable,
46874697 IrInstGenUnionFieldPtr *instruction)
46884698{
46894699 if (instruction->base.value->special != ConstValSpecialRuntime)
......@@ -4783,7 +4793,7 @@ static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_
47834793 return SIZE_MAX;
47844794}
47854795
4786static LLVMValueRef ir_render_asm_gen(CodeGen *g, IrExecutableGen *executable, IrInstGenAsm *instruction) {
4796static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, IrInstGenAsm *instruction) {
47874797 AstNode *asm_node = instruction->base.base.source_node;
47884798 assert(asm_node->type == NodeTypeAsmExpr);
47894799 AstNodeAsmExpr *asm_expr = &asm_node->data.asm_expr;
......@@ -4960,13 +4970,13 @@ static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueR
49604970 return gen_load_untyped(g, maybe_field_ptr, 0, false, "");
49614971}
49624972
4963static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutableGen *executable,
4973static LLVMValueRef ir_render_test_non_null(CodeGen *g, Stage1Air *executable,
49644974 IrInstGenTestNonNull *instruction)
49654975{
49664976 return gen_non_null_bit(g, instruction->value->value->type, ir_llvm_value(g, instruction->value));
49674977}
49684978
4969static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutableGen *executable,
4979static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, Stage1Air *executable,
49704980 IrInstGenOptionalUnwrapPtr *instruction)
49714981{
49724982 if (instruction->base.value->special != ConstValSpecialRuntime)
......@@ -5073,7 +5083,7 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *expr_type, BuiltinFn
50735083 return fn_val;
50745084}
50755085
5076static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutableGen *executable, IrInstGenClz *instruction) {
5086static LLVMValueRef ir_render_clz(CodeGen *g, Stage1Air *executable, IrInstGenClz *instruction) {
50775087 ZigType *int_type = instruction->op->value->type;
50785088 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdClz);
50795089 LLVMValueRef operand = ir_llvm_value(g, instruction->op);
......@@ -5085,7 +5095,7 @@ static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutableGen *executable, IrIns
50855095 return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
50865096}
50875097
5088static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutableGen *executable, IrInstGenCtz *instruction) {
5098static LLVMValueRef ir_render_ctz(CodeGen *g, Stage1Air *executable, IrInstGenCtz *instruction) {
50895099 ZigType *int_type = instruction->op->value->type;
50905100 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdCtz);
50915101 LLVMValueRef operand = ir_llvm_value(g, instruction->op);
......@@ -5097,7 +5107,7 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutableGen *executable, IrIns
50975107 return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
50985108}
50995109
5100static LLVMValueRef ir_render_shuffle_vector(CodeGen *g, IrExecutableGen *executable, IrInstGenShuffleVector *instruction) {
5110static LLVMValueRef ir_render_shuffle_vector(CodeGen *g, Stage1Air *executable, IrInstGenShuffleVector *instruction) {
51015111 uint64_t len_a = instruction->a->value->type->data.vector.len;
51025112 uint64_t len_mask = instruction->mask->value->type->data.vector.len;
51035113
......@@ -5127,7 +5137,7 @@ static LLVMValueRef ir_render_shuffle_vector(CodeGen *g, IrExecutableGen *execut
51275137 llvm_mask_value, "");
51285138}
51295139
5130static LLVMValueRef ir_render_splat(CodeGen *g, IrExecutableGen *executable, IrInstGenSplat *instruction) {
5140static LLVMValueRef ir_render_splat(CodeGen *g, Stage1Air *executable, IrInstGenSplat *instruction) {
51315141 ZigType *result_type = instruction->base.value->type;
51325142 ir_assert(result_type->id == ZigTypeIdVector, &instruction->base);
51335143 uint32_t len = result_type->data.vector.len;
......@@ -5139,7 +5149,7 @@ static LLVMValueRef ir_render_splat(CodeGen *g, IrExecutableGen *executable, IrI
51395149 return LLVMBuildShuffleVector(g->builder, op_vector, undef_vector, LLVMConstNull(mask_llvm_type), "");
51405150}
51415151
5142static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutableGen *executable, IrInstGenPopCount *instruction) {
5152static LLVMValueRef ir_render_pop_count(CodeGen *g, Stage1Air *executable, IrInstGenPopCount *instruction) {
51435153 ZigType *int_type = instruction->op->value->type;
51445154 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount);
51455155 LLVMValueRef operand = ir_llvm_value(g, instruction->op);
......@@ -5147,7 +5157,7 @@ static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutableGen *executable,
51475157 return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int);
51485158}
51495159
5150static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutableGen *executable, IrInstGenSwitchBr *instruction) {
5160static LLVMValueRef ir_render_switch_br(CodeGen *g, Stage1Air *executable, IrInstGenSwitchBr *instruction) {
51515161 ZigType *target_type = instruction->target_value->value->type;
51525162 LLVMBasicBlockRef else_block = instruction->else_block->llvm_block;
51535163
......@@ -5175,7 +5185,7 @@ static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutableGen *executable,
51755185 return nullptr;
51765186}
51775187
5178static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutableGen *executable, IrInstGenPhi *instruction) {
5188static LLVMValueRef ir_render_phi(CodeGen *g, Stage1Air *executable, IrInstGenPhi *instruction) {
51795189 if (!type_has_bits(g, instruction->base.value->type))
51805190 return nullptr;
51815191
......@@ -5199,7 +5209,7 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutableGen *executable, IrIns
51995209 return phi;
52005210}
52015211
5202static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrInstGenRef *instruction) {
5212static LLVMValueRef ir_render_ref(CodeGen *g, Stage1Air *executable, IrInstGenRef *instruction) {
52035213 if (!type_has_bits(g, instruction->base.value->type)) {
52045214 return nullptr;
52055215 }
......@@ -5219,7 +5229,7 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrIns
52195229 }
52205230}
52215231
5222static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutableGen *executable, IrInstGenErrName *instruction) {
5232static LLVMValueRef ir_render_err_name(CodeGen *g, Stage1Air *executable, IrInstGenErrName *instruction) {
52235233 assert(g->generate_error_name_table);
52245234 assert(g->errors_by_index.length > 0);
52255235
......@@ -5346,7 +5356,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) {
53465356 return fn_val;
53475357}
53485358
5349static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutableGen *executable,
5359static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, Stage1Air *executable,
53505360 IrInstGenTagName *instruction)
53515361{
53525362 ZigType *enum_type = instruction->target->value->type;
......@@ -5359,7 +5369,7 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutableGen *executa
53595369 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, "");
53605370}
53615371
5362static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, IrExecutableGen *executable,
5372static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, Stage1Air *executable,
53635373 IrInstGenFieldParentPtr *instruction)
53645374{
53655375 ZigType *container_ptr_type = instruction->base.value->type;
......@@ -5386,7 +5396,7 @@ static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, IrExecutableGen *exec
53865396 }
53875397}
53885398
5389static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutableGen *executable, IrInstGenAlignCast *instruction) {
5399static LLVMValueRef ir_render_align_cast(CodeGen *g, Stage1Air *executable, IrInstGenAlignCast *instruction) {
53905400 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
53915401 assert(target_val);
53925402
......@@ -5449,7 +5459,7 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutableGen *executable
54495459 return target_val;
54505460}
54515461
5452static LLVMValueRef ir_render_error_return_trace(CodeGen *g, IrExecutableGen *executable,
5462static LLVMValueRef ir_render_error_return_trace(CodeGen *g, Stage1Air *executable,
54535463 IrInstGenErrorReturnTrace *instruction)
54545464{
54555465 bool is_llvm_alloca;
......@@ -5522,7 +5532,7 @@ static LLVMTypeRef get_atomic_abi_type(CodeGen *g, IrInstGen *instruction, bool
55225532 }
55235533}
55245534
5525static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, IrInstGenCmpxchg *instruction) {
5535static LLVMValueRef ir_render_cmpxchg(CodeGen *g, Stage1Air *executable, IrInstGenCmpxchg *instruction) {
55265536 LLVMValueRef ptr_val = ir_llvm_value(g, instruction->ptr);
55275537 LLVMValueRef cmp_val = ir_llvm_value(g, instruction->cmp_value);
55285538 LLVMValueRef new_val = ir_llvm_value(g, instruction->new_value);
......@@ -5584,7 +5594,7 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I
55845594 return result_loc;
55855595}
55865596
5587static LLVMValueRef ir_render_reduce(CodeGen *g, IrExecutableGen *executable, IrInstGenReduce *instruction) {
5597static LLVMValueRef ir_render_reduce(CodeGen *g, Stage1Air *executable, IrInstGenReduce *instruction) {
55885598 LLVMValueRef value = ir_llvm_value(g, instruction->value);
55895599
55905600 ZigType *value_type = instruction->value->value->type;
......@@ -5648,13 +5658,13 @@ static LLVMValueRef ir_render_reduce(CodeGen *g, IrExecutableGen *executable, Ir
56485658 return result_val;
56495659}
56505660
5651static LLVMValueRef ir_render_fence(CodeGen *g, IrExecutableGen *executable, IrInstGenFence *instruction) {
5661static LLVMValueRef ir_render_fence(CodeGen *g, Stage1Air *executable, IrInstGenFence *instruction) {
56525662 LLVMAtomicOrdering atomic_order = to_LLVMAtomicOrdering(instruction->order);
56535663 LLVMBuildFence(g->builder, atomic_order, false, "");
56545664 return nullptr;
56555665}
56565666
5657static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutableGen *executable, IrInstGenTruncate *instruction) {
5667static LLVMValueRef ir_render_truncate(CodeGen *g, Stage1Air *executable, IrInstGenTruncate *instruction) {
56585668 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
56595669 ZigType *dest_type = instruction->base.value->type;
56605670 ZigType *src_type = instruction->target->value->type;
......@@ -5669,7 +5679,7 @@ static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutableGen *executable,
56695679 }
56705680}
56715681
5672static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutableGen *executable, IrInstGenMemset *instruction) {
5682static LLVMValueRef ir_render_memset(CodeGen *g, Stage1Air *executable, IrInstGenMemset *instruction) {
56735683 LLVMValueRef dest_ptr = ir_llvm_value(g, instruction->dest_ptr);
56745684 LLVMValueRef len_val = ir_llvm_value(g, instruction->count);
56755685
......@@ -5699,7 +5709,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutableGen *executable, Ir
56995709 return nullptr;
57005710}
57015711
5702static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutableGen *executable, IrInstGenMemcpy *instruction) {
5712static LLVMValueRef ir_render_memcpy(CodeGen *g, Stage1Air *executable, IrInstGenMemcpy *instruction) {
57035713 LLVMValueRef dest_ptr = ir_llvm_value(g, instruction->dest_ptr);
57045714 LLVMValueRef src_ptr = ir_llvm_value(g, instruction->src_ptr);
57055715 LLVMValueRef len_val = ir_llvm_value(g, instruction->count);
......@@ -5721,14 +5731,14 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutableGen *executable, Ir
57215731 return nullptr;
57225732}
57235733
5724static LLVMValueRef ir_render_wasm_memory_size(CodeGen *g, IrExecutableGen *executable, IrInstGenWasmMemorySize *instruction) {
5734static LLVMValueRef ir_render_wasm_memory_size(CodeGen *g, Stage1Air *executable, IrInstGenWasmMemorySize *instruction) {
57255735 // TODO adjust for wasm64
57265736 LLVMValueRef param = ir_llvm_value(g, instruction->index);
57275737 LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_size(g), &param, 1, "");
57285738 return val;
57295739}
57305740
5731static LLVMValueRef ir_render_wasm_memory_grow(CodeGen *g, IrExecutableGen *executable, IrInstGenWasmMemoryGrow *instruction) {
5741static LLVMValueRef ir_render_wasm_memory_grow(CodeGen *g, Stage1Air *executable, IrInstGenWasmMemoryGrow *instruction) {
57325742 // TODO adjust for wasm64
57335743 LLVMValueRef params[] = {
57345744 ir_llvm_value(g, instruction->index),
......@@ -5738,7 +5748,7 @@ static LLVMValueRef ir_render_wasm_memory_grow(CodeGen *g, IrExecutableGen *exec
57385748 return val;
57395749}
57405750
5741static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutableGen *executable, IrInstGenSlice *instruction) {
5751static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, IrInstGenSlice *instruction) {
57425752 Error err;
57435753
57445754 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr);
......@@ -5975,12 +5985,12 @@ static LLVMValueRef get_trap_fn_val(CodeGen *g) {
59755985}
59765986
59775987
5978static LLVMValueRef ir_render_breakpoint(CodeGen *g, IrExecutableGen *executable, IrInstGenBreakpoint *instruction) {
5988static LLVMValueRef ir_render_breakpoint(CodeGen *g, Stage1Air *executable, IrInstGenBreakpoint *instruction) {
59795989 LLVMBuildCall(g->builder, get_trap_fn_val(g), nullptr, 0, "");
59805990 return nullptr;
59815991}
59825992
5983static LLVMValueRef ir_render_return_address(CodeGen *g, IrExecutableGen *executable,
5993static LLVMValueRef ir_render_return_address(CodeGen *g, Stage1Air *executable,
59845994 IrInstGenReturnAddress *instruction)
59855995{
59865996 if (target_is_wasm(g->zig_target) && g->zig_target->os != OsEmscripten) {
......@@ -6008,7 +6018,7 @@ static LLVMValueRef get_frame_address_fn_val(CodeGen *g) {
60086018 return g->frame_address_fn_val;
60096019}
60106020
6011static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutableGen *executable,
6021static LLVMValueRef ir_render_frame_address(CodeGen *g, Stage1Air *executable,
60126022 IrInstGenFrameAddress *instruction)
60136023{
60146024 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type);
......@@ -6016,7 +6026,7 @@ static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutableGen *executa
60166026 return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, "");
60176027}
60186028
6019static LLVMValueRef ir_render_handle(CodeGen *g, IrExecutableGen *executable, IrInstGenFrameHandle *instruction) {
6029static LLVMValueRef ir_render_handle(CodeGen *g, Stage1Air *executable, IrInstGenFrameHandle *instruction) {
60206030 return g->cur_frame_ptr;
60216031}
60226032
......@@ -6045,7 +6055,7 @@ static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstGenOverflowOp *in
60456055 return overflow_bit;
60466056}
60476057
6048static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutableGen *executable, IrInstGenOverflowOp *instruction) {
6058static LLVMValueRef ir_render_overflow_op(CodeGen *g, Stage1Air *executable, IrInstGenOverflowOp *instruction) {
60496059 AddSubMul add_sub_mul;
60506060 switch (instruction->op) {
60516061 case IrOverflowOpAdd:
......@@ -6083,7 +6093,7 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutableGen *executabl
60836093 return overflow_bit;
60846094}
60856095
6086static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutableGen *executable, IrInstGenTestErr *instruction) {
6096static LLVMValueRef ir_render_test_err(CodeGen *g, Stage1Air *executable, IrInstGenTestErr *instruction) {
60876097 ZigType *err_union_type = instruction->err_union->value->type;
60886098 ZigType *payload_type = err_union_type->data.error_union.payload_type;
60896099 LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->err_union);
......@@ -6100,7 +6110,7 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutableGen *executable,
61006110 return LLVMBuildICmp(g->builder, LLVMIntNE, err_val, zero, "");
61016111}
61026112
6103static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutableGen *executable,
6113static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, Stage1Air *executable,
61046114 IrInstGenUnwrapErrCode *instruction)
61056115{
61066116 if (instruction->base.value->special != ConstValSpecialRuntime)
......@@ -6120,7 +6130,7 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutableGen *execu
61206130 }
61216131}
61226132
6123static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutableGen *executable,
6133static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, Stage1Air *executable,
61246134 IrInstGenUnwrapErrPayload *instruction)
61256135{
61266136 Error err;
......@@ -6189,7 +6199,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutableGen *ex
61896199 }
61906200}
61916201
6192static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutableGen *executable, IrInstGenOptionalWrap *instruction) {
6202static LLVMValueRef ir_render_optional_wrap(CodeGen *g, Stage1Air *executable, IrInstGenOptionalWrap *instruction) {
61936203 ZigType *wanted_type = instruction->base.value->type;
61946204
61956205 assert(wanted_type->id == ZigTypeIdOptional);
......@@ -6225,7 +6235,7 @@ static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutableGen *executa
62256235 return result_loc;
62266236}
62276237
6228static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutableGen *executable, IrInstGenErrWrapCode *instruction) {
6238static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, Stage1Air *executable, IrInstGenErrWrapCode *instruction) {
62296239 ZigType *wanted_type = instruction->base.value->type;
62306240
62316241 assert(wanted_type->id == ZigTypeIdErrorUnion);
......@@ -6245,7 +6255,7 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutableGen *executa
62456255 return result_loc;
62466256}
62476257
6248static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutableGen *executable, IrInstGenErrWrapPayload *instruction) {
6258static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, Stage1Air *executable, IrInstGenErrWrapPayload *instruction) {
62496259 ZigType *wanted_type = instruction->base.value->type;
62506260
62516261 assert(wanted_type->id == ZigTypeIdErrorUnion);
......@@ -6276,7 +6286,7 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutableGen *exec
62766286 return result_loc;
62776287}
62786288
6279static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutableGen *executable, IrInstGenUnionTag *instruction) {
6289static LLVMValueRef ir_render_union_tag(CodeGen *g, Stage1Air *executable, IrInstGenUnionTag *instruction) {
62806290 ZigType *union_type = instruction->value->value->type;
62816291
62826292 ZigType *tag_type = union_type->data.unionation.tag_type;
......@@ -6294,14 +6304,14 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutableGen *executable,
62946304 return get_handle_value(g, tag_field_ptr, tag_type, ptr_type);
62956305}
62966306
6297static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutableGen *executable, IrInstGenPanic *instruction) {
6307static LLVMValueRef ir_render_panic(CodeGen *g, Stage1Air *executable, IrInstGenPanic *instruction) {
62986308 bool is_llvm_alloca;
62996309 LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.base.scope, &is_llvm_alloca);
63006310 gen_panic(g, ir_llvm_value(g, instruction->msg), err_ret_trace_val, is_llvm_alloca);
63016311 return nullptr;
63026312}
63036313
6304static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable,
6314static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, Stage1Air *executable,
63056315 IrInstGenAtomicRmw *instruction)
63066316{
63076317 bool is_signed;
......@@ -6353,7 +6363,7 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable
63536363 return LLVMBuildIntToPtr(g->builder, uncasted_result, get_llvm_type(g, operand_type), "");
63546364}
63556365
6356static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutableGen *executable,
6366static LLVMValueRef ir_render_atomic_load(CodeGen *g, Stage1Air *executable,
63576367 IrInstGenAtomicLoad *instruction)
63586368{
63596369 LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->ordering);
......@@ -6374,7 +6384,7 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutableGen *executabl
63746384 return load_inst;
63756385}
63766386
6377static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executable,
6387static LLVMValueRef ir_render_atomic_store(CodeGen *g, Stage1Air *executable,
63786388 IrInstGenAtomicStore *instruction)
63796389{
63806390 LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->ordering);
......@@ -6397,13 +6407,13 @@ static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executab
63976407 return nullptr;
63986408}
63996409
6400static LLVMValueRef ir_render_float_op(CodeGen *g, IrExecutableGen *executable, IrInstGenFloatOp *instruction) {
6410static LLVMValueRef ir_render_float_op(CodeGen *g, Stage1Air *executable, IrInstGenFloatOp *instruction) {
64016411 LLVMValueRef operand = ir_llvm_value(g, instruction->operand);
64026412 LLVMValueRef fn_val = get_float_fn(g, instruction->base.value->type, ZigLLVMFnIdFloatOp, instruction->fn_id);
64036413 return LLVMBuildCall(g->builder, fn_val, &operand, 1, "");
64046414}
64056415
6406static LLVMValueRef ir_render_mul_add(CodeGen *g, IrExecutableGen *executable, IrInstGenMulAdd *instruction) {
6416static LLVMValueRef ir_render_mul_add(CodeGen *g, Stage1Air *executable, IrInstGenMulAdd *instruction) {
64076417 LLVMValueRef op1 = ir_llvm_value(g, instruction->op1);
64086418 LLVMValueRef op2 = ir_llvm_value(g, instruction->op2);
64096419 LLVMValueRef op3 = ir_llvm_value(g, instruction->op3);
......@@ -6418,7 +6428,7 @@ static LLVMValueRef ir_render_mul_add(CodeGen *g, IrExecutableGen *executable, I
64186428 return LLVMBuildCall(g->builder, fn_val, args, 3, "");
64196429}
64206430
6421static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutableGen *executable, IrInstGenBswap *instruction) {
6431static LLVMValueRef ir_render_bswap(CodeGen *g, Stage1Air *executable, IrInstGenBswap *instruction) {
64226432 LLVMValueRef op = ir_llvm_value(g, instruction->op);
64236433 ZigType *expr_type = instruction->base.value->type;
64246434 bool is_vector = expr_type->id == ZigTypeIdVector;
......@@ -6452,7 +6462,7 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutableGen *executable, IrI
64526462 return LLVMBuildTrunc(g->builder, shifted, get_llvm_type(g, expr_type), "");
64536463}
64546464
6455static LLVMValueRef ir_render_extern(CodeGen *g, IrExecutableGen *executable,
6465static LLVMValueRef ir_render_extern(CodeGen *g, Stage1Air *executable,
64566466 IrInstGenExtern *instruction)
64576467{
64586468 ZigType *expr_type = instruction->base.value->type;
......@@ -6476,7 +6486,7 @@ static LLVMValueRef ir_render_extern(CodeGen *g, IrExecutableGen *executable,
64766486 return LLVMBuildBitCast(g->builder, global_value, get_llvm_type(g, expr_type), "");
64776487}
64786488
6479static LLVMValueRef ir_render_bit_reverse(CodeGen *g, IrExecutableGen *executable, IrInstGenBitReverse *instruction) {
6489static LLVMValueRef ir_render_bit_reverse(CodeGen *g, Stage1Air *executable, IrInstGenBitReverse *instruction) {
64806490 LLVMValueRef op = ir_llvm_value(g, instruction->op);
64816491 ZigType *int_type = instruction->base.value->type;
64826492 assert(int_type->id == ZigTypeIdInt);
......@@ -6484,7 +6494,7 @@ static LLVMValueRef ir_render_bit_reverse(CodeGen *g, IrExecutableGen *executabl
64846494 return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
64856495}
64866496
6487static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutableGen *executable,
6497static LLVMValueRef ir_render_vector_to_array(CodeGen *g, Stage1Air *executable,
64886498 IrInstGenVectorToArray *instruction)
64896499{
64906500 ZigType *array_type = instruction->base.value->type;
......@@ -6518,7 +6528,7 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutableGen *execu
65186528 return result_loc;
65196529}
65206530
6521static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutableGen *executable,
6531static LLVMValueRef ir_render_array_to_vector(CodeGen *g, Stage1Air *executable,
65226532 IrInstGenArrayToVector *instruction)
65236533{
65246534 ZigType *vector_type = instruction->base.value->type;
......@@ -6555,7 +6565,7 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutableGen *execu
65556565 }
65566566}
65576567
6558static LLVMValueRef ir_render_assert_zero(CodeGen *g, IrExecutableGen *executable,
6568static LLVMValueRef ir_render_assert_zero(CodeGen *g, Stage1Air *executable,
65596569 IrInstGenAssertZero *instruction)
65606570{
65616571 LLVMValueRef target = ir_llvm_value(g, instruction->target);
......@@ -6566,7 +6576,7 @@ static LLVMValueRef ir_render_assert_zero(CodeGen *g, IrExecutableGen *executabl
65666576 return nullptr;
65676577}
65686578
6569static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutableGen *executable,
6579static LLVMValueRef ir_render_assert_non_null(CodeGen *g, Stage1Air *executable,
65706580 IrInstGenAssertNonNull *instruction)
65716581{
65726582 LLVMValueRef target = ir_llvm_value(g, instruction->target);
......@@ -6591,7 +6601,7 @@ static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutableGen *execu
65916601 return nullptr;
65926602}
65936603
6594static LLVMValueRef ir_render_suspend_begin(CodeGen *g, IrExecutableGen *executable,
6604static LLVMValueRef ir_render_suspend_begin(CodeGen *g, Stage1Air *executable,
65956605 IrInstGenSuspendBegin *instruction)
65966606{
65976607 if (fn_is_async(g->cur_fn)) {
......@@ -6600,7 +6610,7 @@ static LLVMValueRef ir_render_suspend_begin(CodeGen *g, IrExecutableGen *executa
66006610 return nullptr;
66016611}
66026612
6603static LLVMValueRef ir_render_suspend_finish(CodeGen *g, IrExecutableGen *executable,
6613static LLVMValueRef ir_render_suspend_finish(CodeGen *g, Stage1Air *executable,
66046614 IrInstGenSuspendFinish *instruction)
66056615{
66066616 LLVMBuildRetVoid(g->builder);
......@@ -6652,7 +6662,7 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstGen *source_instr,
66526662 }
66536663}
66546664
6655static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrInstGenAwait *instruction) {
6665static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, IrInstGenAwait *instruction) {
66566666 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
66576667 LLVMValueRef zero = LLVMConstNull(usize_type_ref);
66586668 LLVMValueRef target_frame_ptr = ir_llvm_value(g, instruction->frame);
......@@ -6739,7 +6749,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrI
67396749 return nullptr;
67406750}
67416751
6742static LLVMValueRef ir_render_resume(CodeGen *g, IrExecutableGen *executable, IrInstGenResume *instruction) {
6752static LLVMValueRef ir_render_resume(CodeGen *g, Stage1Air *executable, IrInstGenResume *instruction) {
67436753 LLVMValueRef frame = ir_llvm_value(g, instruction->frame);
67446754 ZigType *frame_type = instruction->frame->value->type;
67456755 assert(frame_type->id == ZigTypeIdAnyFrame);
......@@ -6748,14 +6758,14 @@ static LLVMValueRef ir_render_resume(CodeGen *g, IrExecutableGen *executable, Ir
67486758 return nullptr;
67496759}
67506760
6751static LLVMValueRef ir_render_frame_size(CodeGen *g, IrExecutableGen *executable,
6761static LLVMValueRef ir_render_frame_size(CodeGen *g, Stage1Air *executable,
67526762 IrInstGenFrameSize *instruction)
67536763{
67546764 LLVMValueRef fn_val = ir_llvm_value(g, instruction->fn);
67556765 return gen_frame_size(g, fn_val);
67566766}
67576767
6758static LLVMValueRef ir_render_spill_begin(CodeGen *g, IrExecutableGen *executable,
6768static LLVMValueRef ir_render_spill_begin(CodeGen *g, Stage1Air *executable,
67596769 IrInstGenSpillBegin *instruction)
67606770{
67616771 if (!fn_is_async(g->cur_fn))
......@@ -6775,7 +6785,7 @@ static LLVMValueRef ir_render_spill_begin(CodeGen *g, IrExecutableGen *executabl
67756785 zig_unreachable();
67766786}
67776787
6778static LLVMValueRef ir_render_spill_end(CodeGen *g, IrExecutableGen *executable, IrInstGenSpillEnd *instruction) {
6788static LLVMValueRef ir_render_spill_end(CodeGen *g, Stage1Air *executable, IrInstGenSpillEnd *instruction) {
67796789 if (!fn_is_async(g->cur_fn))
67806790 return ir_llvm_value(g, instruction->begin->operand);
67816791
......@@ -6791,7 +6801,7 @@ static LLVMValueRef ir_render_spill_end(CodeGen *g, IrExecutableGen *executable,
67916801 zig_unreachable();
67926802}
67936803
6794static LLVMValueRef ir_render_vector_extract_elem(CodeGen *g, IrExecutableGen *executable,
6804static LLVMValueRef ir_render_vector_extract_elem(CodeGen *g, Stage1Air *executable,
67956805 IrInstGenVectorExtractElem *instruction)
67966806{
67976807 LLVMValueRef vector = ir_llvm_value(g, instruction->vector);
......@@ -6806,11 +6816,11 @@ static void set_debug_location(CodeGen *g, IrInstGen *instruction) {
68066816 assert(source_node);
68076817 assert(scope);
68086818
6809 ZigLLVMSetCurrentDebugLocation(g->builder, (int)source_node->line + 1,
6810 (int)source_node->column + 1, get_di_scope(g, scope));
6819 ZigLLVMSetCurrentDebugLocation(g->builder, node_line_onebased(source_node),
6820 node_column_onebased(source_node), get_di_scope(g, scope));
68116821}
68126822
6813static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executable, IrInstGen *instruction) {
6823static LLVMValueRef ir_render_instruction(CodeGen *g, Stage1Air *executable, IrInstGen *instruction) {
68146824 switch (instruction->id) {
68156825 case IrInstGenIdInvalid:
68166826 case IrInstGenIdConst:
......@@ -6998,7 +7008,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl
69987008static void ir_render(CodeGen *g, ZigFn *fn_entry) {
69997009 assert(fn_entry);
70007010
7001 IrExecutableGen *executable = &fn_entry->analyzed_executable;
7011 Stage1Air *executable = &fn_entry->analyzed_executable;
70027012 assert(executable->basic_block_list.length > 0);
70037013
70047014 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) {
......@@ -7996,7 +8006,7 @@ static void generate_error_name_table(CodeGen *g) {
79968006}
79978007
79988008static void build_all_basic_blocks(CodeGen *g, ZigFn *fn) {
7999 IrExecutableGen *executable = &fn->analyzed_executable;
8009 Stage1Air *executable = &fn->analyzed_executable;
80008010 assert(executable->basic_block_list.length > 0);
80018011 LLVMValueRef fn_val = fn_llvm_value(g, fn);
80028012 LLVMBasicBlockRef first_bb = nullptr;
......@@ -8030,7 +8040,7 @@ static void gen_global_var(CodeGen *g, ZigVar *var, LLVMValueRef init_val,
80308040 bool is_local_to_unit = true;
80318041 ZigLLVMCreateGlobalVariable(g->dbuilder, get_di_scope(g, var->parent_scope), var->name,
80328042 var->name, import->data.structure.root_struct->di_file,
8033 (unsigned)(var->decl_node->line + 1),
8043 node_line_onebased(var->decl_node),
80348044 get_llvm_di_type(g, type_entry), is_local_to_unit);
80358045
80368046 // TODO ^^ make an actual global variable
......@@ -8305,7 +8315,8 @@ static void do_code_gen(CodeGen *g) {
83058315
83068316 if (var->src_arg_index == SIZE_MAX) {
83078317 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
8308 var->name, import->data.structure.root_struct->di_file, (unsigned)(var->decl_node->line + 1),
8318 var->name, import->data.structure.root_struct->di_file,
8319 node_line_onebased(var->decl_node),
83098320 get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0);
83108321
83118322 } else if (is_c_abi) {
......@@ -8330,7 +8341,7 @@ static void do_code_gen(CodeGen *g) {
83308341 if (var->decl_node) {
83318342 var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
83328343 var->name, import->data.structure.root_struct->di_file,
8333 (unsigned)(var->decl_node->line + 1),
8344 node_line_onebased(var->decl_node),
83348345 get_llvm_di_type(g, gen_type), !g->strip_debug_symbols, 0, (unsigned)(gen_info->gen_index+1));
83358346 }
83368347
......@@ -8374,10 +8385,11 @@ static void do_code_gen(CodeGen *g) {
83748385
83758386 if (!g->strip_debug_symbols) {
83768387 AstNode *source_node = fn_table_entry->proto_node;
8377 ZigLLVMSetCurrentDebugLocation(g->builder, (int)source_node->line + 1,
8378 (int)source_node->column + 1, get_di_scope(g, fn_table_entry->child_scope));
8388 ZigLLVMSetCurrentDebugLocation(g->builder,
8389 node_line_onebased(source_node), node_column_onebased(source_node),
8390 get_di_scope(g, fn_table_entry->child_scope));
83798391 }
8380 IrExecutableGen *executable = &fn_table_entry->analyzed_executable;
8392 Stage1Air *executable = &fn_table_entry->analyzed_executable;
83818393 LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadResume");
83828394 LLVMPositionBuilderAtEnd(g->builder, bad_resume_block);
83838395 gen_assertion_scope(g, PanicMsgIdBadResume, fn_table_entry->child_scope);
src/stage1/dump_analysis.cpp+33-9
......@@ -1084,19 +1084,43 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
10841084 jw_end_object(jw);
10851085}
10861086
1087static Buf *collect_doc_comments(RootStruct *root_struct, TokenIndex first_token) {
1088 if (first_token == 0)
1089 return nullptr;
1090
1091 TokenId *token_ids = root_struct->token_ids;
1092 TokenLoc *token_locs = root_struct->token_locs;
1093 Buf *str = buf_alloc();
1094 const char *source = buf_ptr(root_struct->source_code);
1095 TokenIndex doc_token = first_token;
1096 for (;token_ids[doc_token] == TokenIdDocComment; doc_token += 1) {
1097 // chops off '///' but leaves '\n'
1098 uint32_t start_pos = token_locs[doc_token].offset;
1099 uint32_t token_len = 0;
1100 while (source[start_pos + token_len] != '\n' &&
1101 source[start_pos + token_len] != 0)
1102 {
1103 token_len += 1;
1104 }
1105 buf_append_mem(str, source + start_pos + 3, token_len - 3);
1106 }
1107 return str;
1108}
1109
10871110static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {
10881111 JsonWriter *jw = &ctx->jw;
10891112
10901113 jw_begin_object(jw);
10911114
10921115 jw_object_field(jw, "file");
1093 anal_dump_file_ref(ctx, node->owner->data.structure.root_struct->path);
1116 RootStruct *root_struct = node->owner->data.structure.root_struct;
1117 anal_dump_file_ref(ctx, root_struct->path);
10941118
10951119 jw_object_field(jw, "line");
1096 jw_int(jw, node->line);
1120 jw_int(jw, root_struct->token_locs[node->main_token].line);
10971121
10981122 jw_object_field(jw, "col");
1099 jw_int(jw, node->column);
1123 jw_int(jw, root_struct->token_locs[node->main_token].column);
11001124
11011125 const Buf *doc_comments_buf = nullptr;
11021126 const Buf *name_buf = nullptr;
......@@ -1107,30 +1131,30 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {
11071131
11081132 switch (node->type) {
11091133 case NodeTypeParamDecl:
1110 doc_comments_buf = &node->data.param_decl.doc_comments;
1134 doc_comments_buf = collect_doc_comments(root_struct, node->data.param_decl.doc_comments);
11111135 name_buf = node->data.param_decl.name;
11121136 is_var_args = node->data.param_decl.is_var_args;
11131137 is_noalias = node->data.param_decl.is_noalias;
11141138 is_comptime = node->data.param_decl.is_comptime;
11151139 break;
11161140 case NodeTypeFnProto:
1117 doc_comments_buf = &node->data.fn_proto.doc_comments;
1141 doc_comments_buf = collect_doc_comments(root_struct, node->data.fn_proto.doc_comments);
11181142 field_nodes = &node->data.fn_proto.params;
11191143 is_var_args = node->data.fn_proto.is_var_args;
11201144 break;
11211145 case NodeTypeVariableDeclaration:
1122 doc_comments_buf = &node->data.variable_declaration.doc_comments;
1146 doc_comments_buf = collect_doc_comments(root_struct, node->data.variable_declaration.doc_comments);
11231147 break;
11241148 case NodeTypeErrorSetField:
1125 doc_comments_buf = &node->data.err_set_field.doc_comments;
1149 doc_comments_buf = collect_doc_comments(root_struct, node->data.err_set_field.doc_comments);
11261150 break;
11271151 case NodeTypeStructField:
1128 doc_comments_buf = &node->data.struct_field.doc_comments;
1152 doc_comments_buf = collect_doc_comments(root_struct, node->data.struct_field.doc_comments);
11291153 name_buf = node->data.struct_field.name;
11301154 break;
11311155 case NodeTypeContainerDecl:
11321156 field_nodes = &node->data.container_decl.fields;
1133 doc_comments_buf = &node->data.container_decl.doc_comments;
1157 doc_comments_buf = collect_doc_comments(root_struct, node->data.container_decl.doc_comments);
11341158 break;
11351159 default:
11361160 break;
src/stage1/errmsg.cpp+19-40
......@@ -96,14 +96,14 @@ void err_msg_add_note(ErrorMsg *parent, ErrorMsg *note) {
9696 parent->notes.append(note);
9797}
9898
99ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size_t offset,
100 const char *source, Buf *msg)
99ErrorMsg *err_msg_create_with_offset(Buf *path, uint32_t byte_offset, const char *source,
100 Buf *msg)
101101{
102102 ErrorMsg *err_msg = heap::c_allocator.create<ErrorMsg>();
103103 err_msg->path = path;
104 err_msg->line_start = line;
105 err_msg->column_start = column;
106104 err_msg->msg = msg;
105 err_msg->line_start = 0;
106 err_msg->column_start = 0;
107107
108108 if (source == nullptr) {
109109 // Must initialize the buffer anyway
......@@ -111,46 +111,25 @@ ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size
111111 return err_msg;
112112 }
113113
114 size_t line_start_offset = offset;
115 for (;;) {
116 if (line_start_offset == 0) {
117 break;
118 }
119
120 line_start_offset -= 1;
121
122 if (source[line_start_offset] == '\n') {
123 line_start_offset += 1;
124 break;
114 size_t line_start = 0;
115 size_t i = 0;
116 for (;i < byte_offset; i += 1) {
117 switch (source[i]) {
118 case '\n':
119 err_msg->line_start += 1;
120 err_msg->column_start = 0;
121 line_start = i + 1;
122 continue;
123 default:
124 err_msg->column_start += 1;
125 continue;
125126 }
126127 }
127
128 size_t line_end_offset = offset;
129 while (source[line_end_offset] && source[line_end_offset] != '\n') {
130 line_end_offset += 1;
128 while (source[i] != '\n' && source[i] != 0) {
129 i += 1;
131130 }
132131
133 buf_init_from_mem(&err_msg->line_buf, source + line_start_offset, line_end_offset - line_start_offset);
134
135 return err_msg;
136}
137
138ErrorMsg *err_msg_create_with_line(Buf *path, size_t line, size_t column,
139 Buf *source, ZigList<size_t> *line_offsets, Buf *msg)
140{
141 ErrorMsg *err_msg = heap::c_allocator.create<ErrorMsg>();
142 err_msg->path = path;
143 err_msg->line_start = line;
144 err_msg->column_start = column;
145 err_msg->msg = msg;
146
147 size_t line_start_offset = line_offsets->at(line);
148 size_t end_line = line + 1;
149 size_t line_end_offset = (end_line >= line_offsets->length) ? buf_len(source) : line_offsets->at(line + 1);
150 size_t len = (line_end_offset + 1 > line_start_offset) ? (line_end_offset - line_start_offset - 1) : 0;
151 if (len == SIZE_MAX) len = 0;
152
153 buf_init_from_mem(&err_msg->line_buf, buf_ptr(source) + line_start_offset, len);
132 buf_init_from_mem(&err_msg->line_buf, source + line_start, i - line_start);
154133
155134 return err_msg;
156135}
src/stage1/errmsg.hpp+1-5
......@@ -25,10 +25,6 @@ struct ErrorMsg {
2525void print_err_msg(ErrorMsg *msg, ErrColor color);
2626
2727void err_msg_add_note(ErrorMsg *parent, ErrorMsg *note);
28ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size_t offset,
29 const char *source, Buf *msg);
30
31ErrorMsg *err_msg_create_with_line(Buf *path, size_t line, size_t column,
32 Buf *source, ZigList<size_t> *line_offsets, Buf *msg);
28ErrorMsg *err_msg_create_with_offset(Buf *path, uint32_t byte_offset, const char *source, Buf *msg);
3329
3430#endif
src/stage1/error.cpp+2
......@@ -88,6 +88,8 @@ const char *err_str(Error err) {
8888 case ErrorZigIsTheCCompiler: return "Zig was not provided with libc installation information, and so it does not know where the libc paths are on the system. Zig attempted to use the system C compiler to find out where the libc paths are, but discovered that Zig is being used as the system C compiler.";
8989 case ErrorFileBusy: return "file is busy";
9090 case ErrorLocked: return "file is locked by another process";
91 case ErrorInvalidCharacter: return "invalid character";
92 case ErrorUnicodePointTooLarge: return "unicode codepoint too large";
9193 }
9294 return "(invalid error)";
9395}
src/stage1/ir.cpp+1336-9376
......@@ -5,8 +5,8 @@
55 * See http://opensource.org/licenses/MIT
66 */
77
8#include "astgen.hpp"
89#include "analyze.hpp"
9#include "ast_render.hpp"
1010#include "error.hpp"
1111#include "ir.hpp"
1212#include "ir_print.hpp"
......@@ -22,16 +22,9 @@
2222#include <errno.h>
2323#include <math.h>
2424
25struct IrBuilderSrc {
26 CodeGen *codegen;
27 IrExecutableSrc *exec;
28 IrBasicBlockSrc *current_basic_block;
29 AstNode *main_block_node;
30};
31
3225struct IrBuilderGen {
3326 CodeGen *codegen;
34 IrExecutableGen *exec;
27 Stage1Air *exec;
3528 IrBasicBlockGen *current_basic_block;
3629
3730 // track for immediate post-analysis destruction
......@@ -40,7 +33,8 @@ struct IrBuilderGen {
4033
4134struct IrAnalyze {
4235 CodeGen *codegen;
43 IrBuilderSrc old_irb;
36 Stage1Zir *zir;
37 Stage1ZirBasicBlock *zir_current_basic_block;
4438 IrBuilderGen new_irb;
4539 size_t old_bb_index;
4640 size_t instruction_index;
......@@ -48,10 +42,14 @@ struct IrAnalyze {
4842 AstNode *explicit_return_type_source_node;
4943 ZigList<IrInstGen *> src_implicit_return_type_list;
5044 ZigList<IrSuspendPosition> resume_stack;
51 IrBasicBlockSrc *const_predecessor_bb;
45 Stage1ZirBasicBlock *const_predecessor_bb;
5246 size_t ref_count;
5347 size_t break_debug_id; // for debugging purposes
5448 IrInstGen *return_ptr;
49 Stage1Air *parent_exec;
50 size_t *backward_branch_count;
51 size_t *backward_branch_quota;
52 ZigFn *fn;
5553
5654 // For the purpose of using in a debugger
5755 void dump();
......@@ -216,27 +214,18 @@ struct DbgIrBreakPoint {
216214 const char *src_file;
217215 uint32_t line;
218216};
219DbgIrBreakPoint dbg_ir_breakpoints_buf[20];
220size_t dbg_ir_breakpoints_count = 0;
221217
222static IrInstSrc *ir_gen_node(IrBuilderSrc *irb, AstNode *node, Scope *scope);
223static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *scope, LVal lval,
224 ResultLoc *result_loc);
225218static IrInstGen *ir_implicit_cast(IrAnalyze *ira, IrInstGen *value, ZigType *expected_type);
226219static IrInstGen *ir_implicit_cast2(IrAnalyze *ira, IrInst *value_source_instr,
227220 IrInstGen *value, ZigType *expected_type);
228221static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst *source_instr, IrInstGen *ptr,
229222 ResultLoc *result_loc);
230static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutableSrc *exec, AstNode *source_node, Buf *msg);
231223static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,
232224 IrInst* source_instr, IrInstGen *container_ptr, IrInst *container_ptr_src,
233225 ZigType *container_type, bool initializing);
234static void ir_assert_impl(bool ok, IrInst* source_instruction, const char *file, unsigned int line);
235226static void ir_assert_gen_impl(bool ok, IrInstGen *source_instruction, const char *file, unsigned int line);
236227static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *var);
237228static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op);
238static IrInstSrc *ir_lval_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *value, LVal lval, ResultLoc *result_loc);
239static IrInstSrc *ir_expr_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *inst, ResultLoc *result_loc);
240229static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align);
241230static ZigType *adjust_ptr_const(CodeGen *g, ZigType *ptr_type, bool is_const);
242231static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align);
......@@ -265,26 +254,14 @@ static IrInstGen *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInst* source_inst
265254 IrInstGen *base_ptr, bool initializing);
266255static IrInstGen *ir_analyze_store_ptr(IrAnalyze *ira, IrInst* source_instr,
267256 IrInstGen *ptr, IrInstGen *uncasted_value, bool allow_write_through_const);
268static IrInstSrc *ir_gen_union_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
269 IrInstSrc *union_type, IrInstSrc *field_name, AstNode *expr_node,
270 LVal lval, ResultLoc *parent_result_loc);
271257static void ir_reset_result(ResultLoc *result_loc);
272static Buf *get_anon_type_name(CodeGen *codegen, IrExecutableSrc *exec, const char *kind_name,
273 Scope *scope, AstNode *source_node, Buf *out_bare_name);
274static ResultLocCast *ir_build_cast_result_loc(IrBuilderSrc *irb, IrInstSrc *dest_type,
275 ResultLoc *parent_result_loc);
276258static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_instr,
277259 TypeStructField *field, IrInstGen *struct_ptr, ZigType *struct_type, bool initializing);
278260static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
279261 IrInst* source_instr, IrInstGen *container_ptr, ZigType *container_type);
280static ResultLoc *no_result_loc(void);
281262static IrInstGen *ir_analyze_test_non_null(IrAnalyze *ira, IrInst *source_inst, IrInstGen *value);
282263static IrInstGen *ir_error_dependency_loop(IrAnalyze *ira, IrInst *source_instr);
283264static IrInstGen *ir_const_undef(IrAnalyze *ira, IrInst *source_instruction, ZigType *ty);
284static ZigVar *ir_create_var(IrBuilderSrc *irb, AstNode *node, Scope *scope, Buf *name,
285 bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime);
286static void build_decl_var_and_init(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var,
287 IrInstSrc *init, const char *name_hint, IrInstSrc *is_comptime);
288265static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instruction,
289266 AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstGen *field_result_loc,
290267 IrInstGen *result_loc);
......@@ -295,292 +272,15 @@ static bool value_cmp_numeric_val_all(ZigValue *left, Cmp predicate, ZigValue *r
295272static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field);
296273static void value_to_bigfloat(BigFloat *out, ZigValue *val);
297274
275static void ir_assert_impl(bool ok, IrInst *source_instruction, char const *file, unsigned int line) {
276 if (ok) return;
277 src_assert_impl(ok, source_instruction->source_node, file, line);
278}
279
280
298281#define ir_assert(OK, SOURCE_INSTRUCTION) ir_assert_impl((OK), (SOURCE_INSTRUCTION), __FILE__, __LINE__)
299282#define ir_assert_gen(OK, SOURCE_INSTRUCTION) ir_assert_gen_impl((OK), (SOURCE_INSTRUCTION), __FILE__, __LINE__)
300283
301static void destroy_instruction_src(IrInstSrc *inst) {
302 switch (inst->id) {
303 case IrInstSrcIdInvalid:
304 zig_unreachable();
305 case IrInstSrcIdReturn:
306 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcReturn *>(inst));
307 case IrInstSrcIdConst:
308 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcConst *>(inst));
309 case IrInstSrcIdBinOp:
310 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBinOp *>(inst));
311 case IrInstSrcIdMergeErrSets:
312 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMergeErrSets *>(inst));
313 case IrInstSrcIdDeclVar:
314 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcDeclVar *>(inst));
315 case IrInstSrcIdCall:
316 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCall *>(inst));
317 case IrInstSrcIdCallExtra:
318 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallExtra *>(inst));
319 case IrInstSrcIdAsyncCallExtra:
320 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAsyncCallExtra *>(inst));
321 case IrInstSrcIdUnOp:
322 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnOp *>(inst));
323 case IrInstSrcIdCondBr:
324 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCondBr *>(inst));
325 case IrInstSrcIdBr:
326 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBr *>(inst));
327 case IrInstSrcIdPhi:
328 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPhi *>(inst));
329 case IrInstSrcIdContainerInitList:
330 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcContainerInitList *>(inst));
331 case IrInstSrcIdContainerInitFields:
332 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcContainerInitFields *>(inst));
333 case IrInstSrcIdUnreachable:
334 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnreachable *>(inst));
335 case IrInstSrcIdElemPtr:
336 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcElemPtr *>(inst));
337 case IrInstSrcIdVarPtr:
338 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVarPtr *>(inst));
339 case IrInstSrcIdLoadPtr:
340 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcLoadPtr *>(inst));
341 case IrInstSrcIdStorePtr:
342 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcStorePtr *>(inst));
343 case IrInstSrcIdTypeOf:
344 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeOf *>(inst));
345 case IrInstSrcIdFieldPtr:
346 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFieldPtr *>(inst));
347 case IrInstSrcIdSetCold:
348 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetCold *>(inst));
349 case IrInstSrcIdSetRuntimeSafety:
350 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetRuntimeSafety *>(inst));
351 case IrInstSrcIdSetFloatMode:
352 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetFloatMode *>(inst));
353 case IrInstSrcIdArrayType:
354 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcArrayType *>(inst));
355 case IrInstSrcIdSliceType:
356 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSliceType *>(inst));
357 case IrInstSrcIdAnyFrameType:
358 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAnyFrameType *>(inst));
359 case IrInstSrcIdAsm:
360 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAsm *>(inst));
361 case IrInstSrcIdSizeOf:
362 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSizeOf *>(inst));
363 case IrInstSrcIdTestNonNull:
364 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestNonNull *>(inst));
365 case IrInstSrcIdOptionalUnwrapPtr:
366 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOptionalUnwrapPtr *>(inst));
367 case IrInstSrcIdPopCount:
368 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPopCount *>(inst));
369 case IrInstSrcIdClz:
370 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcClz *>(inst));
371 case IrInstSrcIdCtz:
372 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCtz *>(inst));
373 case IrInstSrcIdBswap:
374 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBswap *>(inst));
375 case IrInstSrcIdBitReverse:
376 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitReverse *>(inst));
377 case IrInstSrcIdSwitchBr:
378 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchBr *>(inst));
379 case IrInstSrcIdSwitchVar:
380 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchVar *>(inst));
381 case IrInstSrcIdSwitchElseVar:
382 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchElseVar *>(inst));
383 case IrInstSrcIdSwitchTarget:
384 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchTarget *>(inst));
385 case IrInstSrcIdImport:
386 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcImport *>(inst));
387 case IrInstSrcIdRef:
388 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcRef *>(inst));
389 case IrInstSrcIdCompileErr:
390 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCompileErr *>(inst));
391 case IrInstSrcIdCompileLog:
392 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCompileLog *>(inst));
393 case IrInstSrcIdErrName:
394 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrName *>(inst));
395 case IrInstSrcIdCImport:
396 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCImport *>(inst));
397 case IrInstSrcIdCInclude:
398 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCInclude *>(inst));
399 case IrInstSrcIdCDefine:
400 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCDefine *>(inst));
401 case IrInstSrcIdCUndef:
402 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCUndef *>(inst));
403 case IrInstSrcIdEmbedFile:
404 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEmbedFile *>(inst));
405 case IrInstSrcIdCmpxchg:
406 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCmpxchg *>(inst));
407 case IrInstSrcIdFence:
408 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFence *>(inst));
409 case IrInstSrcIdReduce:
410 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcReduce *>(inst));
411 case IrInstSrcIdTruncate:
412 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTruncate *>(inst));
413 case IrInstSrcIdIntCast:
414 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntCast *>(inst));
415 case IrInstSrcIdFloatCast:
416 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst));
417 case IrInstSrcIdErrSetCast:
418 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst));
419 case IrInstSrcIdIntToFloat:
420 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst));
421 case IrInstSrcIdFloatToInt:
422 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatToInt *>(inst));
423 case IrInstSrcIdBoolToInt:
424 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolToInt *>(inst));
425 case IrInstSrcIdVectorType:
426 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVectorType *>(inst));
427 case IrInstSrcIdShuffleVector:
428 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcShuffleVector *>(inst));
429 case IrInstSrcIdSplat:
430 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSplat *>(inst));
431 case IrInstSrcIdBoolNot:
432 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolNot *>(inst));
433 case IrInstSrcIdMemset:
434 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemset *>(inst));
435 case IrInstSrcIdMemcpy:
436 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemcpy *>(inst));
437 case IrInstSrcIdSlice:
438 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSlice *>(inst));
439 case IrInstSrcIdBreakpoint:
440 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBreakpoint *>(inst));
441 case IrInstSrcIdReturnAddress:
442 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcReturnAddress *>(inst));
443 case IrInstSrcIdFrameAddress:
444 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameAddress *>(inst));
445 case IrInstSrcIdFrameHandle:
446 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameHandle *>(inst));
447 case IrInstSrcIdFrameType:
448 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameType *>(inst));
449 case IrInstSrcIdFrameSize:
450 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameSize *>(inst));
451 case IrInstSrcIdAlignOf:
452 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlignOf *>(inst));
453 case IrInstSrcIdOverflowOp:
454 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOverflowOp *>(inst));
455 case IrInstSrcIdTestErr:
456 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestErr *>(inst));
457 case IrInstSrcIdUnwrapErrCode:
458 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnwrapErrCode *>(inst));
459 case IrInstSrcIdUnwrapErrPayload:
460 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnwrapErrPayload *>(inst));
461 case IrInstSrcIdFnProto:
462 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFnProto *>(inst));
463 case IrInstSrcIdTestComptime:
464 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestComptime *>(inst));
465 case IrInstSrcIdPtrCast:
466 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrCast *>(inst));
467 case IrInstSrcIdBitCast:
468 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitCast *>(inst));
469 case IrInstSrcIdPtrToInt:
470 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrToInt *>(inst));
471 case IrInstSrcIdIntToPtr:
472 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToPtr *>(inst));
473 case IrInstSrcIdIntToEnum:
474 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToEnum *>(inst));
475 case IrInstSrcIdIntToErr:
476 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToErr *>(inst));
477 case IrInstSrcIdErrToInt:
478 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrToInt *>(inst));
479 case IrInstSrcIdCheckSwitchProngsUnderNo:
480 case IrInstSrcIdCheckSwitchProngsUnderYes:
481 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckSwitchProngs *>(inst));
482 case IrInstSrcIdCheckStatementIsVoid:
483 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckStatementIsVoid *>(inst));
484 case IrInstSrcIdTypeName:
485 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeName *>(inst));
486 case IrInstSrcIdTagName:
487 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTagName *>(inst));
488 case IrInstSrcIdPtrType:
489 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrType *>(inst));
490 case IrInstSrcIdPtrTypeSimple:
491 case IrInstSrcIdPtrTypeSimpleConst:
492 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrTypeSimple *>(inst));
493 case IrInstSrcIdDeclRef:
494 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcDeclRef *>(inst));
495 case IrInstSrcIdPanic:
496 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPanic *>(inst));
497 case IrInstSrcIdFieldParentPtr:
498 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFieldParentPtr *>(inst));
499 case IrInstSrcIdByteOffsetOf:
500 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcByteOffsetOf *>(inst));
501 case IrInstSrcIdBitOffsetOf:
502 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitOffsetOf *>(inst));
503 case IrInstSrcIdTypeInfo:
504 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeInfo *>(inst));
505 case IrInstSrcIdType:
506 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcType *>(inst));
507 case IrInstSrcIdHasField:
508 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasField *>(inst));
509 case IrInstSrcIdSetEvalBranchQuota:
510 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetEvalBranchQuota *>(inst));
511 case IrInstSrcIdAlignCast:
512 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlignCast *>(inst));
513 case IrInstSrcIdImplicitCast:
514 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcImplicitCast *>(inst));
515 case IrInstSrcIdResolveResult:
516 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResolveResult *>(inst));
517 case IrInstSrcIdResetResult:
518 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResetResult *>(inst));
519 case IrInstSrcIdSetAlignStack:
520 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetAlignStack *>(inst));
521 case IrInstSrcIdArgTypeAllowVarFalse:
522 case IrInstSrcIdArgTypeAllowVarTrue:
523 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcArgType *>(inst));
524 case IrInstSrcIdExport:
525 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcExport *>(inst));
526 case IrInstSrcIdExtern:
527 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcExtern *>(inst));
528 case IrInstSrcIdErrorReturnTrace:
529 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrorReturnTrace *>(inst));
530 case IrInstSrcIdErrorUnion:
531 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrorUnion *>(inst));
532 case IrInstSrcIdAtomicRmw:
533 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicRmw *>(inst));
534 case IrInstSrcIdSaveErrRetAddr:
535 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSaveErrRetAddr *>(inst));
536 case IrInstSrcIdAddImplicitReturnType:
537 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAddImplicitReturnType *>(inst));
538 case IrInstSrcIdFloatOp:
539 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatOp *>(inst));
540 case IrInstSrcIdMulAdd:
541 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMulAdd *>(inst));
542 case IrInstSrcIdAtomicLoad:
543 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicLoad *>(inst));
544 case IrInstSrcIdAtomicStore:
545 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicStore *>(inst));
546 case IrInstSrcIdEnumToInt:
547 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEnumToInt *>(inst));
548 case IrInstSrcIdCheckRuntimeScope:
549 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckRuntimeScope *>(inst));
550 case IrInstSrcIdHasDecl:
551 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasDecl *>(inst));
552 case IrInstSrcIdUndeclaredIdent:
553 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUndeclaredIdent *>(inst));
554 case IrInstSrcIdAlloca:
555 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlloca *>(inst));
556 case IrInstSrcIdEndExpr:
557 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEndExpr *>(inst));
558 case IrInstSrcIdUnionInitNamedField:
559 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnionInitNamedField *>(inst));
560 case IrInstSrcIdSuspendBegin:
561 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSuspendBegin *>(inst));
562 case IrInstSrcIdSuspendFinish:
563 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSuspendFinish *>(inst));
564 case IrInstSrcIdResume:
565 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResume *>(inst));
566 case IrInstSrcIdAwait:
567 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAwait *>(inst));
568 case IrInstSrcIdSpillBegin:
569 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSpillBegin *>(inst));
570 case IrInstSrcIdSpillEnd:
571 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSpillEnd *>(inst));
572 case IrInstSrcIdCallArgs:
573 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallArgs *>(inst));
574 case IrInstSrcIdWasmMemorySize:
575 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcWasmMemorySize *>(inst));
576 case IrInstSrcIdWasmMemoryGrow:
577 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcWasmMemoryGrow *>(inst));
578 case IrInstSrcIdSrc:
579 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSrc *>(inst));
580 }
581 zig_unreachable();
582}
583
584284void destroy_instruction_gen(IrInstGen *inst) {
585285 switch (inst->id) {
586286 case IrInstGenIdInvalid:
......@@ -781,17 +481,17 @@ static void ira_deref(IrAnalyze *ira) {
781481 }
782482 assert(ira->ref_count != 0);
783483
784 for (size_t bb_i = 0; bb_i < ira->old_irb.exec->basic_block_list.length; bb_i += 1) {
785 IrBasicBlockSrc *pass1_bb = ira->old_irb.exec->basic_block_list.items[bb_i];
484 for (size_t bb_i = 0; bb_i < ira->zir->basic_block_list.length; bb_i += 1) {
485 Stage1ZirBasicBlock *pass1_bb = ira->zir->basic_block_list.items[bb_i];
786486 for (size_t inst_i = 0; inst_i < pass1_bb->instruction_list.length; inst_i += 1) {
787487 IrInstSrc *pass1_inst = pass1_bb->instruction_list.items[inst_i];
788488 destroy_instruction_src(pass1_inst);
789489 }
790490 heap::c_allocator.destroy(pass1_bb);
791491 }
792 ira->old_irb.exec->basic_block_list.deinit();
793 ira->old_irb.exec->tld_list.deinit();
794 heap::c_allocator.destroy(ira->old_irb.exec);
492 ira->zir->basic_block_list.deinit();
493 ira->zir->tld_list.deinit();
494 heap::c_allocator.destroy(ira->zir);
795495 ira->src_implicit_return_type_list.deinit();
796496 ira->resume_stack.deinit();
797497
......@@ -970,54 +670,18 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte
970670 zig_unreachable();
971671}
972672
973static bool ir_should_inline(IrExecutableSrc *exec, Scope *scope) {
974 if (exec->is_inline)
975 return true;
976
977 while (scope != nullptr) {
978 if (scope->id == ScopeIdCompTime)
979 return true;
980 if (scope->id == ScopeIdTypeOf)
981 return false;
982 if (scope->id == ScopeIdFnDef)
983 break;
984 scope = scope->parent;
985 }
986 return false;
987}
988
989static void ir_instruction_append(IrBasicBlockSrc *basic_block, IrInstSrc *instruction) {
990 assert(basic_block);
991 assert(instruction);
992 basic_block->instruction_list.append(instruction);
993}
994
995673static void ir_inst_gen_append(IrBasicBlockGen *basic_block, IrInstGen *instruction) {
996674 assert(basic_block);
997675 assert(instruction);
998676 basic_block->instruction_list.append(instruction);
999677}
1000678
1001static size_t exec_next_debug_id(IrExecutableSrc *exec) {
1002 size_t result = exec->next_debug_id;
1003 exec->next_debug_id += 1;
1004 return result;
1005}
1006
1007static size_t exec_next_debug_id_gen(IrExecutableGen *exec) {
679static size_t exec_next_debug_id_gen(Stage1Air *exec) {
1008680 size_t result = exec->next_debug_id;
1009681 exec->next_debug_id += 1;
1010682 return result;
1011683}
1012684
1013static ZigFn *exec_fn_entry(IrExecutableSrc *exec) {
1014 return exec->fn_entry;
1015}
1016
1017static Buf *exec_c_import_buf(IrExecutableSrc *exec) {
1018 return exec->c_import_buf;
1019}
1020
1021685static bool value_is_comptime(ZigValue *const_val) {
1022686 return const_val->special != ConstValSpecialRuntime;
1023687}
......@@ -1026,33 +690,11 @@ static bool instr_is_comptime(IrInstGen *instruction) {
1026690 return value_is_comptime(instruction->value);
1027691}
1028692
1029static bool instr_is_unreachable(IrInstSrc *instruction) {
1030 return instruction->is_noreturn;
1031}
1032
1033static void ir_ref_bb(IrBasicBlockSrc *bb) {
1034 bb->ref_count += 1;
1035}
1036
1037static void ir_ref_instruction(IrInstSrc *instruction, IrBasicBlockSrc *cur_bb) {
1038 assert(instruction->id != IrInstSrcIdInvalid);
1039 instruction->base.ref_count += 1;
1040 if (instruction->owner_bb != cur_bb && !instr_is_unreachable(instruction)
1041 && instruction->id != IrInstSrcIdConst)
1042 {
1043 ir_ref_bb(instruction->owner_bb);
1044 }
1045}
1046
1047693static void ir_ref_inst_gen(IrInstGen *instruction) {
1048694 assert(instruction->id != IrInstGenIdInvalid);
1049695 instruction->base.ref_count += 1;
1050696}
1051697
1052static void ir_ref_var(ZigVar *var) {
1053 var->ref_count += 1;
1054}
1055
1056698static void create_result_ptr(CodeGen *codegen, ZigType *expected_type,
1057699 ZigValue **out_result, ZigValue **out_result_ptr)
1058700{
......@@ -1078,7 +720,7 @@ ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {
1078720 create_result_ptr(ira->codegen, ira->codegen->builtin_types.entry_type, &result, &result_ptr);
1079721
1080722 if ((err = ir_eval_const_value(ira->codegen, scope, node, result_ptr,
1081 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota,
723 ira->backward_branch_count, ira->backward_branch_quota,
1082724 nullptr, nullptr, node, nullptr, ira->new_irb.exec, nullptr, UndefBad)))
1083725 {
1084726 return ira->codegen->builtin_types.entry_invalid;
......@@ -1092,15 +734,6 @@ ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {
1092734 return res_type;
1093735}
1094736
1095static IrBasicBlockSrc *ir_create_basic_block(IrBuilderSrc *irb, Scope *scope, const char *name_hint) {
1096 IrBasicBlockSrc *result = heap::c_allocator.create<IrBasicBlockSrc>();
1097 result->scope = scope;
1098 result->name_hint = name_hint;
1099 result->debug_id = exec_next_debug_id(irb->exec);
1100 result->index = UINT32_MAX; // set later
1101 return result;
1102}
1103
1104737static IrBasicBlockGen *ir_create_basic_block_gen(IrAnalyze *ira, Scope *scope, const char *name_hint) {
1105738 IrBasicBlockGen *result = heap::c_allocator.create<IrBasicBlockGen>();
1106739 result->scope = scope;
......@@ -1109,8813 +742,1693 @@ static IrBasicBlockGen *ir_create_basic_block_gen(IrAnalyze *ira, Scope *scope,
1109742 return result;
1110743}
1111744
1112static IrBasicBlockGen *ir_build_bb_from(IrAnalyze *ira, IrBasicBlockSrc *other_bb) {
745static IrBasicBlockGen *ir_build_bb_from(IrAnalyze *ira, Stage1ZirBasicBlock *other_bb) {
1113746 IrBasicBlockGen *new_bb = ir_create_basic_block_gen(ira, other_bb->scope, other_bb->name_hint);
1114747 other_bb->child = new_bb;
1115748 return new_bb;
1116749}
1117750
1118static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclVar *) {
1119 return IrInstSrcIdDeclVar;
751static constexpr IrInstGenId ir_inst_id(IrInstGenDeclVar *) {
752 return IrInstGenIdDeclVar;
1120753}
1121754
1122static constexpr IrInstSrcId ir_inst_id(IrInstSrcBr *) {
1123 return IrInstSrcIdBr;
755static constexpr IrInstGenId ir_inst_id(IrInstGenBr *) {
756 return IrInstGenIdBr;
1124757}
1125758
1126static constexpr IrInstSrcId ir_inst_id(IrInstSrcCondBr *) {
1127 return IrInstSrcIdCondBr;
759static constexpr IrInstGenId ir_inst_id(IrInstGenCondBr *) {
760 return IrInstGenIdCondBr;
1128761}
1129762
1130static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchBr *) {
1131 return IrInstSrcIdSwitchBr;
763static constexpr IrInstGenId ir_inst_id(IrInstGenSwitchBr *) {
764 return IrInstGenIdSwitchBr;
1132765}
1133766
1134static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchVar *) {
1135 return IrInstSrcIdSwitchVar;
767static constexpr IrInstGenId ir_inst_id(IrInstGenPhi *) {
768 return IrInstGenIdPhi;
1136769}
1137770
1138static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchElseVar *) {
1139 return IrInstSrcIdSwitchElseVar;
771static constexpr IrInstGenId ir_inst_id(IrInstGenBinaryNot *) {
772 return IrInstGenIdBinaryNot;
1140773}
1141774
1142static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchTarget *) {
1143 return IrInstSrcIdSwitchTarget;
775static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) {
776 return IrInstGenIdNegation;
1144777}
1145778
1146static constexpr IrInstSrcId ir_inst_id(IrInstSrcPhi *) {
1147 return IrInstSrcIdPhi;
779static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) {
780 return IrInstGenIdBinOp;
1148781}
1149782
1150static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnOp *) {
1151 return IrInstSrcIdUnOp;
783static constexpr IrInstGenId ir_inst_id(IrInstGenLoadPtr *) {
784 return IrInstGenIdLoadPtr;
1152785}
1153786
1154static constexpr IrInstSrcId ir_inst_id(IrInstSrcBinOp *) {
1155 return IrInstSrcIdBinOp;
787static constexpr IrInstGenId ir_inst_id(IrInstGenStorePtr *) {
788 return IrInstGenIdStorePtr;
1156789}
1157790
1158static constexpr IrInstSrcId ir_inst_id(IrInstSrcMergeErrSets *) {
1159 return IrInstSrcIdMergeErrSets;
791static constexpr IrInstGenId ir_inst_id(IrInstGenVectorStoreElem *) {
792 return IrInstGenIdVectorStoreElem;
1160793}
1161794
1162static constexpr IrInstSrcId ir_inst_id(IrInstSrcLoadPtr *) {
1163 return IrInstSrcIdLoadPtr;
795static constexpr IrInstGenId ir_inst_id(IrInstGenStructFieldPtr *) {
796 return IrInstGenIdStructFieldPtr;
1164797}
1165798
1166static constexpr IrInstSrcId ir_inst_id(IrInstSrcStorePtr *) {
1167 return IrInstSrcIdStorePtr;
799static constexpr IrInstGenId ir_inst_id(IrInstGenUnionFieldPtr *) {
800 return IrInstGenIdUnionFieldPtr;
1168801}
1169802
1170static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldPtr *) {
1171 return IrInstSrcIdFieldPtr;
803static constexpr IrInstGenId ir_inst_id(IrInstGenElemPtr *) {
804 return IrInstGenIdElemPtr;
1172805}
1173806
1174static constexpr IrInstSrcId ir_inst_id(IrInstSrcElemPtr *) {
1175 return IrInstSrcIdElemPtr;
807static constexpr IrInstGenId ir_inst_id(IrInstGenVarPtr *) {
808 return IrInstGenIdVarPtr;
1176809}
1177810
1178static constexpr IrInstSrcId ir_inst_id(IrInstSrcVarPtr *) {
1179 return IrInstSrcIdVarPtr;
811static constexpr IrInstGenId ir_inst_id(IrInstGenReturnPtr *) {
812 return IrInstGenIdReturnPtr;
1180813}
1181814
1182static constexpr IrInstSrcId ir_inst_id(IrInstSrcCall *) {
1183 return IrInstSrcIdCall;
815static constexpr IrInstGenId ir_inst_id(IrInstGenCall *) {
816 return IrInstGenIdCall;
1184817}
1185818
1186static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallArgs *) {
1187 return IrInstSrcIdCallArgs;
819static constexpr IrInstGenId ir_inst_id(IrInstGenReturn *) {
820 return IrInstGenIdReturn;
1188821}
1189822
1190static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallExtra *) {
1191 return IrInstSrcIdCallExtra;
823static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) {
824 return IrInstGenIdCast;
1192825}
1193826
1194static constexpr IrInstSrcId ir_inst_id(IrInstSrcAsyncCallExtra *) {
1195 return IrInstSrcIdAsyncCallExtra;
827static constexpr IrInstGenId ir_inst_id(IrInstGenUnreachable *) {
828 return IrInstGenIdUnreachable;
1196829}
1197830
1198static constexpr IrInstSrcId ir_inst_id(IrInstSrcConst *) {
1199 return IrInstSrcIdConst;
831static constexpr IrInstGenId ir_inst_id(IrInstGenAsm *) {
832 return IrInstGenIdAsm;
1200833}
1201834
1202static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturn *) {
1203 return IrInstSrcIdReturn;
835static constexpr IrInstGenId ir_inst_id(IrInstGenTestNonNull *) {
836 return IrInstGenIdTestNonNull;
1204837}
1205838
1206static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitList *) {
1207 return IrInstSrcIdContainerInitList;
839static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalUnwrapPtr *) {
840 return IrInstGenIdOptionalUnwrapPtr;
1208841}
1209842
1210static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitFields *) {
1211 return IrInstSrcIdContainerInitFields;
843static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalWrap *) {
844 return IrInstGenIdOptionalWrap;
1212845}
1213846
1214static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnreachable *) {
1215 return IrInstSrcIdUnreachable;
847static constexpr IrInstGenId ir_inst_id(IrInstGenUnionTag *) {
848 return IrInstGenIdUnionTag;
1216849}
1217850
1218static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeOf *) {
1219 return IrInstSrcIdTypeOf;
851static constexpr IrInstGenId ir_inst_id(IrInstGenClz *) {
852 return IrInstGenIdClz;
1220853}
1221854
1222static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetCold *) {
1223 return IrInstSrcIdSetCold;
855static constexpr IrInstGenId ir_inst_id(IrInstGenCtz *) {
856 return IrInstGenIdCtz;
1224857}
1225858
1226static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetRuntimeSafety *) {
1227 return IrInstSrcIdSetRuntimeSafety;
859static constexpr IrInstGenId ir_inst_id(IrInstGenPopCount *) {
860 return IrInstGenIdPopCount;
1228861}
1229862
1230static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetFloatMode *) {
1231 return IrInstSrcIdSetFloatMode;
863static constexpr IrInstGenId ir_inst_id(IrInstGenBswap *) {
864 return IrInstGenIdBswap;
1232865}
1233866
1234static constexpr IrInstSrcId ir_inst_id(IrInstSrcArrayType *) {
1235 return IrInstSrcIdArrayType;
1236}
1237
1238static constexpr IrInstSrcId ir_inst_id(IrInstSrcAnyFrameType *) {
1239 return IrInstSrcIdAnyFrameType;
1240}
1241
1242static constexpr IrInstSrcId ir_inst_id(IrInstSrcSliceType *) {
1243 return IrInstSrcIdSliceType;
1244}
1245
1246static constexpr IrInstSrcId ir_inst_id(IrInstSrcAsm *) {
1247 return IrInstSrcIdAsm;
867static constexpr IrInstGenId ir_inst_id(IrInstGenBitReverse *) {
868 return IrInstGenIdBitReverse;
1248869}
1249870
1250static constexpr IrInstSrcId ir_inst_id(IrInstSrcSizeOf *) {
1251 return IrInstSrcIdSizeOf;
871static constexpr IrInstGenId ir_inst_id(IrInstGenRef *) {
872 return IrInstGenIdRef;
1252873}
1253874
1254static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestNonNull *) {
1255 return IrInstSrcIdTestNonNull;
875static constexpr IrInstGenId ir_inst_id(IrInstGenErrName *) {
876 return IrInstGenIdErrName;
1256877}
1257878
1258static constexpr IrInstSrcId ir_inst_id(IrInstSrcOptionalUnwrapPtr *) {
1259 return IrInstSrcIdOptionalUnwrapPtr;
879static constexpr IrInstGenId ir_inst_id(IrInstGenCmpxchg *) {
880 return IrInstGenIdCmpxchg;
1260881}
1261882
1262static constexpr IrInstSrcId ir_inst_id(IrInstSrcClz *) {
1263 return IrInstSrcIdClz;
883static constexpr IrInstGenId ir_inst_id(IrInstGenFence *) {
884 return IrInstGenIdFence;
1264885}
1265886
1266static constexpr IrInstSrcId ir_inst_id(IrInstSrcCtz *) {
1267 return IrInstSrcIdCtz;
887static constexpr IrInstGenId ir_inst_id(IrInstGenReduce *) {
888 return IrInstGenIdReduce;
1268889}
1269890
1270static constexpr IrInstSrcId ir_inst_id(IrInstSrcPopCount *) {
1271 return IrInstSrcIdPopCount;
891static constexpr IrInstGenId ir_inst_id(IrInstGenTruncate *) {
892 return IrInstGenIdTruncate;
1272893}
1273894
1274static constexpr IrInstSrcId ir_inst_id(IrInstSrcBswap *) {
1275 return IrInstSrcIdBswap;
895static constexpr IrInstGenId ir_inst_id(IrInstGenShuffleVector *) {
896 return IrInstGenIdShuffleVector;
1276897}
1277898
1278static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitReverse *) {
1279 return IrInstSrcIdBitReverse;
899static constexpr IrInstGenId ir_inst_id(IrInstGenSplat *) {
900 return IrInstGenIdSplat;
1280901}
1281902
1282static constexpr IrInstSrcId ir_inst_id(IrInstSrcImport *) {
1283 return IrInstSrcIdImport;
903static constexpr IrInstGenId ir_inst_id(IrInstGenBoolNot *) {
904 return IrInstGenIdBoolNot;
1284905}
1285906
1286static constexpr IrInstSrcId ir_inst_id(IrInstSrcCImport *) {
1287 return IrInstSrcIdCImport;
907static constexpr IrInstGenId ir_inst_id(IrInstGenMemset *) {
908 return IrInstGenIdMemset;
1288909}
1289910
1290static constexpr IrInstSrcId ir_inst_id(IrInstSrcCInclude *) {
1291 return IrInstSrcIdCInclude;
911static constexpr IrInstGenId ir_inst_id(IrInstGenMemcpy *) {
912 return IrInstGenIdMemcpy;
1292913}
1293914
1294static constexpr IrInstSrcId ir_inst_id(IrInstSrcCDefine *) {
1295 return IrInstSrcIdCDefine;
915static constexpr IrInstGenId ir_inst_id(IrInstGenSlice *) {
916 return IrInstGenIdSlice;
1296917}
1297918
1298static constexpr IrInstSrcId ir_inst_id(IrInstSrcCUndef *) {
1299 return IrInstSrcIdCUndef;
919static constexpr IrInstGenId ir_inst_id(IrInstGenBreakpoint *) {
920 return IrInstGenIdBreakpoint;
1300921}
1301922
1302static constexpr IrInstSrcId ir_inst_id(IrInstSrcRef *) {
1303 return IrInstSrcIdRef;
923static constexpr IrInstGenId ir_inst_id(IrInstGenReturnAddress *) {
924 return IrInstGenIdReturnAddress;
1304925}
1305926
1306static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileErr *) {
1307 return IrInstSrcIdCompileErr;
927static constexpr IrInstGenId ir_inst_id(IrInstGenFrameAddress *) {
928 return IrInstGenIdFrameAddress;
1308929}
1309930
1310static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileLog *) {
1311 return IrInstSrcIdCompileLog;
931static constexpr IrInstGenId ir_inst_id(IrInstGenFrameHandle *) {
932 return IrInstGenIdFrameHandle;
1312933}
1313934
1314static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrName *) {
1315 return IrInstSrcIdErrName;
935static constexpr IrInstGenId ir_inst_id(IrInstGenFrameSize *) {
936 return IrInstGenIdFrameSize;
1316937}
1317938
1318static constexpr IrInstSrcId ir_inst_id(IrInstSrcEmbedFile *) {
1319 return IrInstSrcIdEmbedFile;
939static constexpr IrInstGenId ir_inst_id(IrInstGenOverflowOp *) {
940 return IrInstGenIdOverflowOp;
1320941}
1321942
1322static constexpr IrInstSrcId ir_inst_id(IrInstSrcCmpxchg *) {
1323 return IrInstSrcIdCmpxchg;
943static constexpr IrInstGenId ir_inst_id(IrInstGenTestErr *) {
944 return IrInstGenIdTestErr;
1324945}
1325946
1326static constexpr IrInstSrcId ir_inst_id(IrInstSrcFence *) {
1327 return IrInstSrcIdFence;
947static constexpr IrInstGenId ir_inst_id(IrInstGenMulAdd *) {
948 return IrInstGenIdMulAdd;
1328949}
1329950
1330static constexpr IrInstSrcId ir_inst_id(IrInstSrcReduce *) {
1331 return IrInstSrcIdReduce;
951static constexpr IrInstGenId ir_inst_id(IrInstGenFloatOp *) {
952 return IrInstGenIdFloatOp;
1332953}
1333954
1334static constexpr IrInstSrcId ir_inst_id(IrInstSrcTruncate *) {
1335 return IrInstSrcIdTruncate;
955static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrCode *) {
956 return IrInstGenIdUnwrapErrCode;
1336957}
1337958
1338static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntCast *) {
1339 return IrInstSrcIdIntCast;
959static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrPayload *) {
960 return IrInstGenIdUnwrapErrPayload;
1340961}
1341962
1342static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatCast *) {
1343 return IrInstSrcIdFloatCast;
963static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapCode *) {
964 return IrInstGenIdErrWrapCode;
1344965}
1345966
1346static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToFloat *) {
1347 return IrInstSrcIdIntToFloat;
967static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapPayload *) {
968 return IrInstGenIdErrWrapPayload;
1348969}
1349970
1350static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatToInt *) {
1351 return IrInstSrcIdFloatToInt;
971static constexpr IrInstGenId ir_inst_id(IrInstGenPtrCast *) {
972 return IrInstGenIdPtrCast;
1352973}
1353974
1354static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolToInt *) {
1355 return IrInstSrcIdBoolToInt;
975static constexpr IrInstGenId ir_inst_id(IrInstGenBitCast *) {
976 return IrInstGenIdBitCast;
1356977}
1357978
1358static constexpr IrInstSrcId ir_inst_id(IrInstSrcVectorType *) {
1359 return IrInstSrcIdVectorType;
979static constexpr IrInstGenId ir_inst_id(IrInstGenWidenOrShorten *) {
980 return IrInstGenIdWidenOrShorten;
1360981}
1361982
1362static constexpr IrInstSrcId ir_inst_id(IrInstSrcShuffleVector *) {
1363 return IrInstSrcIdShuffleVector;
983static constexpr IrInstGenId ir_inst_id(IrInstGenIntToPtr *) {
984 return IrInstGenIdIntToPtr;
1364985}
1365986
1366static constexpr IrInstSrcId ir_inst_id(IrInstSrcSplat *) {
1367 return IrInstSrcIdSplat;
987static constexpr IrInstGenId ir_inst_id(IrInstGenPtrToInt *) {
988 return IrInstGenIdPtrToInt;
1368989}
1369990
1370static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolNot *) {
1371 return IrInstSrcIdBoolNot;
991static constexpr IrInstGenId ir_inst_id(IrInstGenIntToEnum *) {
992 return IrInstGenIdIntToEnum;
1372993}
1373994
1374static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemset *) {
1375 return IrInstSrcIdMemset;
995static constexpr IrInstGenId ir_inst_id(IrInstGenIntToErr *) {
996 return IrInstGenIdIntToErr;
1376997}
1377998
1378static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemcpy *) {
1379 return IrInstSrcIdMemcpy;
999static constexpr IrInstGenId ir_inst_id(IrInstGenErrToInt *) {
1000 return IrInstGenIdErrToInt;
13801001}
13811002
1382static constexpr IrInstSrcId ir_inst_id(IrInstSrcSlice *) {
1383 return IrInstSrcIdSlice;
1003static constexpr IrInstGenId ir_inst_id(IrInstGenPanic *) {
1004 return IrInstGenIdPanic;
13841005}
13851006
1386static constexpr IrInstSrcId ir_inst_id(IrInstSrcBreakpoint *) {
1387 return IrInstSrcIdBreakpoint;
1007static constexpr IrInstGenId ir_inst_id(IrInstGenTagName *) {
1008 return IrInstGenIdTagName;
13881009}
13891010
1390static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturnAddress *) {
1391 return IrInstSrcIdReturnAddress;
1011static constexpr IrInstGenId ir_inst_id(IrInstGenFieldParentPtr *) {
1012 return IrInstGenIdFieldParentPtr;
13921013}
13931014
1394static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameAddress *) {
1395 return IrInstSrcIdFrameAddress;
1015static constexpr IrInstGenId ir_inst_id(IrInstGenAlignCast *) {
1016 return IrInstGenIdAlignCast;
13961017}
13971018
1398static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameHandle *) {
1399 return IrInstSrcIdFrameHandle;
1019static constexpr IrInstGenId ir_inst_id(IrInstGenErrorReturnTrace *) {
1020 return IrInstGenIdErrorReturnTrace;
14001021}
14011022
1402static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameType *) {
1403 return IrInstSrcIdFrameType;
1023static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicRmw *) {
1024 return IrInstGenIdAtomicRmw;
14041025}
14051026
1406static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameSize *) {
1407 return IrInstSrcIdFrameSize;
1027static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicLoad *) {
1028 return IrInstGenIdAtomicLoad;
14081029}
14091030
1410static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignOf *) {
1411 return IrInstSrcIdAlignOf;
1031static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicStore *) {
1032 return IrInstGenIdAtomicStore;
14121033}
14131034
1414static constexpr IrInstSrcId ir_inst_id(IrInstSrcOverflowOp *) {
1415 return IrInstSrcIdOverflowOp;
1035static constexpr IrInstGenId ir_inst_id(IrInstGenSaveErrRetAddr *) {
1036 return IrInstGenIdSaveErrRetAddr;
14161037}
14171038
1418static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestErr *) {
1419 return IrInstSrcIdTestErr;
1039static constexpr IrInstGenId ir_inst_id(IrInstGenVectorToArray *) {
1040 return IrInstGenIdVectorToArray;
14201041}
14211042
1422static constexpr IrInstSrcId ir_inst_id(IrInstSrcMulAdd *) {
1423 return IrInstSrcIdMulAdd;
1043static constexpr IrInstGenId ir_inst_id(IrInstGenArrayToVector *) {
1044 return IrInstGenIdArrayToVector;
14241045}
14251046
1426static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatOp *) {
1427 return IrInstSrcIdFloatOp;
1047static constexpr IrInstGenId ir_inst_id(IrInstGenAssertZero *) {
1048 return IrInstGenIdAssertZero;
14281049}
14291050
1430static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrCode *) {
1431 return IrInstSrcIdUnwrapErrCode;
1051static constexpr IrInstGenId ir_inst_id(IrInstGenAssertNonNull *) {
1052 return IrInstGenIdAssertNonNull;
14321053}
14331054
1434static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrPayload *) {
1435 return IrInstSrcIdUnwrapErrPayload;
1055static constexpr IrInstGenId ir_inst_id(IrInstGenPtrOfArrayToSlice *) {
1056 return IrInstGenIdPtrOfArrayToSlice;
14361057}
14371058
1438static constexpr IrInstSrcId ir_inst_id(IrInstSrcFnProto *) {
1439 return IrInstSrcIdFnProto;
1059static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendBegin *) {
1060 return IrInstGenIdSuspendBegin;
14401061}
14411062
1442static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestComptime *) {
1443 return IrInstSrcIdTestComptime;
1063static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendFinish *) {
1064 return IrInstGenIdSuspendFinish;
14441065}
14451066
1446static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrCast *) {
1447 return IrInstSrcIdPtrCast;
1067static constexpr IrInstGenId ir_inst_id(IrInstGenAwait *) {
1068 return IrInstGenIdAwait;
14481069}
14491070
1450static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitCast *) {
1451 return IrInstSrcIdBitCast;
1071static constexpr IrInstGenId ir_inst_id(IrInstGenResume *) {
1072 return IrInstGenIdResume;
14521073}
14531074
1454static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToPtr *) {
1455 return IrInstSrcIdIntToPtr;
1075static constexpr IrInstGenId ir_inst_id(IrInstGenSpillBegin *) {
1076 return IrInstGenIdSpillBegin;
14561077}
14571078
1458static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrToInt *) {
1459 return IrInstSrcIdPtrToInt;
1079static constexpr IrInstGenId ir_inst_id(IrInstGenSpillEnd *) {
1080 return IrInstGenIdSpillEnd;
14601081}
14611082
1462static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToEnum *) {
1463 return IrInstSrcIdIntToEnum;
1083static constexpr IrInstGenId ir_inst_id(IrInstGenVectorExtractElem *) {
1084 return IrInstGenIdVectorExtractElem;
14641085}
14651086
1466static constexpr IrInstSrcId ir_inst_id(IrInstSrcEnumToInt *) {
1467 return IrInstSrcIdEnumToInt;
1087static constexpr IrInstGenId ir_inst_id(IrInstGenAlloca *) {
1088 return IrInstGenIdAlloca;
14681089}
14691090
1470static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToErr *) {
1471 return IrInstSrcIdIntToErr;
1091static constexpr IrInstGenId ir_inst_id(IrInstGenConst *) {
1092 return IrInstGenIdConst;
14721093}
14731094
1474static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrToInt *) {
1475 return IrInstSrcIdErrToInt;
1095static constexpr IrInstGenId ir_inst_id(IrInstGenWasmMemorySize *) {
1096 return IrInstGenIdWasmMemorySize;
14761097}
14771098
1478static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckStatementIsVoid *) {
1479 return IrInstSrcIdCheckStatementIsVoid;
1099static constexpr IrInstGenId ir_inst_id(IrInstGenWasmMemoryGrow *) {
1100 return IrInstGenIdWasmMemoryGrow;
14801101}
14811102
1482static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeName *) {
1483 return IrInstSrcIdTypeName;
1103static constexpr IrInstGenId ir_inst_id(IrInstGenExtern *) {
1104 return IrInstGenIdExtern;
14841105}
14851106
1486static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclRef *) {
1487 return IrInstSrcIdDeclRef;
1107template<typename T>
1108static T *ir_create_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {
1109 T *special_instruction = heap::c_allocator.create<T>();
1110 special_instruction->base.id = ir_inst_id(special_instruction);
1111 special_instruction->base.base.scope = scope;
1112 special_instruction->base.base.source_node = source_node;
1113 special_instruction->base.base.debug_id = exec_next_debug_id_gen(irb->exec);
1114 special_instruction->base.owner_bb = irb->current_basic_block;
1115 special_instruction->base.value = irb->codegen->pass1_arena->create<ZigValue>();
1116 return special_instruction;
14881117}
14891118
1490static constexpr IrInstSrcId ir_inst_id(IrInstSrcPanic *) {
1491 return IrInstSrcIdPanic;
1119template<typename T>
1120static T *ir_create_inst_noval(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {
1121 T *special_instruction = heap::c_allocator.create<T>();
1122 special_instruction->base.id = ir_inst_id(special_instruction);
1123 special_instruction->base.base.scope = scope;
1124 special_instruction->base.base.source_node = source_node;
1125 special_instruction->base.base.debug_id = exec_next_debug_id_gen(irb->exec);
1126 special_instruction->base.owner_bb = irb->current_basic_block;
1127 return special_instruction;
14921128}
14931129
1494static constexpr IrInstSrcId ir_inst_id(IrInstSrcTagName *) {
1495 return IrInstSrcIdTagName;
1130template<typename T>
1131static T *ir_build_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {
1132 T *special_instruction = ir_create_inst_gen<T>(irb, scope, source_node);
1133 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base);
1134 return special_instruction;
14961135}
14971136
1498static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldParentPtr *) {
1499 return IrInstSrcIdFieldParentPtr;
1137template<typename T>
1138static T *ir_build_inst_noreturn(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {
1139 T *special_instruction = ir_create_inst_noval<T>(irb, scope, source_node);
1140 special_instruction->base.value = irb->codegen->intern.for_unreachable();
1141 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base);
1142 return special_instruction;
15001143}
15011144
1502static constexpr IrInstSrcId ir_inst_id(IrInstSrcByteOffsetOf *) {
1503 return IrInstSrcIdByteOffsetOf;
1145template<typename T>
1146static T *ir_build_inst_void(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {
1147 T *special_instruction = ir_create_inst_noval<T>(irb, scope, source_node);
1148 special_instruction->base.value = irb->codegen->intern.for_void();
1149 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base);
1150 return special_instruction;
15041151}
15051152
1506static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitOffsetOf *) {
1507 return IrInstSrcIdBitOffsetOf;
1153IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,
1154 ZigType *var_type, const char *name_hint)
1155{
1156 IrInstGenAlloca *alloca_gen = heap::c_allocator.create<IrInstGenAlloca>();
1157 alloca_gen->base.id = IrInstGenIdAlloca;
1158 alloca_gen->base.base.source_node = source_node;
1159 alloca_gen->base.base.scope = scope;
1160 alloca_gen->base.value = g->pass1_arena->create<ZigValue>();
1161 alloca_gen->base.value->type = get_pointer_to_type(g, var_type, false);
1162 alloca_gen->base.base.ref_count = 1;
1163 alloca_gen->name_hint = name_hint;
1164 fn->alloca_gen_list.append(alloca_gen);
1165 return &alloca_gen->base;
15081166}
15091167
1510static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeInfo *) {
1511 return IrInstSrcIdTypeInfo;
1512}
1168static IrInstGen *ir_build_cast(IrAnalyze *ira, IrInst *source_instr,ZigType *dest_type,
1169 IrInstGen *value, CastOp cast_op)
1170{
1171 IrInstGenCast *inst = ir_build_inst_gen<IrInstGenCast>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1172 inst->base.value->type = dest_type;
1173 inst->value = value;
1174 inst->cast_op = cast_op;
15131175
1514static constexpr IrInstSrcId ir_inst_id(IrInstSrcType *) {
1515 return IrInstSrcIdType;
1516}
1176 ir_ref_inst_gen(value);
15171177
1518static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasField *) {
1519 return IrInstSrcIdHasField;
1178 return &inst->base;
15201179}
15211180
1522static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetEvalBranchQuota *) {
1523 return IrInstSrcIdSetEvalBranchQuota;
1524}
1181static IrInstGen *ir_build_cond_br_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *condition,
1182 IrBasicBlockGen *then_block, IrBasicBlockGen *else_block)
1183{
1184 IrInstGenCondBr *inst = ir_build_inst_noreturn<IrInstGenCondBr>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1185 inst->condition = condition;
1186 inst->then_block = then_block;
1187 inst->else_block = else_block;
15251188
1526static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrType *) {
1527 return IrInstSrcIdPtrType;
1528}
1189 ir_ref_inst_gen(condition);
15291190
1530static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignCast *) {
1531 return IrInstSrcIdAlignCast;
1191 return &inst->base;
15321192}
15331193
1534static constexpr IrInstSrcId ir_inst_id(IrInstSrcImplicitCast *) {
1535 return IrInstSrcIdImplicitCast;
1536}
1194static IrInstGen *ir_build_return_gen(IrAnalyze *ira, IrInst *source_inst, IrInstGen *operand) {
1195 IrInstGenReturn *inst = ir_build_inst_noreturn<IrInstGenReturn>(&ira->new_irb,
1196 source_inst->scope, source_inst->source_node);
1197 inst->operand = operand;
15371198
1538static constexpr IrInstSrcId ir_inst_id(IrInstSrcResolveResult *) {
1539 return IrInstSrcIdResolveResult;
1540}
1199 if (operand != nullptr) ir_ref_inst_gen(operand);
15411200
1542static constexpr IrInstSrcId ir_inst_id(IrInstSrcResetResult *) {
1543 return IrInstSrcIdResetResult;
1201 return &inst->base;
15441202}
15451203
1546static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetAlignStack *) {
1547 return IrInstSrcIdSetAlignStack;
1548}
1204static IrInstGen *ir_build_bin_op_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *res_type,
1205 IrBinOp op_id, IrInstGen *op1, IrInstGen *op2, bool safety_check_on)
1206{
1207 IrInstGenBinOp *inst = ir_build_inst_gen<IrInstGenBinOp>(&ira->new_irb,
1208 source_instr->scope, source_instr->source_node);
1209 inst->base.value->type = res_type;
1210 inst->op_id = op_id;
1211 inst->op1 = op1;
1212 inst->op2 = op2;
1213 inst->safety_check_on = safety_check_on;
15491214
1550static constexpr IrInstSrcId ir_inst_id(IrInstSrcExport *) {
1551 return IrInstSrcIdExport;
1552}
1215 ir_ref_inst_gen(op1);
1216 ir_ref_inst_gen(op2);
15531217
1554static constexpr IrInstSrcId ir_inst_id(IrInstSrcExtern *) {
1555 return IrInstSrcIdExtern;
1218 return &inst->base;
15561219}
15571220
1558static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorReturnTrace *) {
1559 return IrInstSrcIdErrorReturnTrace;
1560}
15611221
1562static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorUnion *) {
1563 return IrInstSrcIdErrorUnion;
1564}
1222static IrInstGen *ir_build_var_ptr_gen(IrAnalyze *ira, IrInst *source_instr, ZigVar *var) {
1223 IrInstGenVarPtr *instruction = ir_build_inst_gen<IrInstGenVarPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1224 instruction->var = var;
15651225
1566static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicRmw *) {
1567 return IrInstSrcIdAtomicRmw;
1568}
1226 var->ref_count += 1;
15691227
1570static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicLoad *) {
1571 return IrInstSrcIdAtomicLoad;
1228 return &instruction->base;
15721229}
15731230
1574static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicStore *) {
1575 return IrInstSrcIdAtomicStore;
1231static IrInstGen *ir_build_return_ptr(IrAnalyze *ira, Scope *scope, AstNode *source_node, ZigType *ty) {
1232 IrInstGenReturnPtr *instruction = ir_build_inst_gen<IrInstGenReturnPtr>(&ira->new_irb, scope, source_node);
1233 instruction->base.value->type = ty;
1234 return &instruction->base;
15761235}
15771236
1578static constexpr IrInstSrcId ir_inst_id(IrInstSrcSaveErrRetAddr *) {
1579 return IrInstSrcIdSaveErrRetAddr;
1580}
1237static IrInstGen *ir_build_elem_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
1238 IrInstGen *array_ptr, IrInstGen *elem_index, bool safety_check_on, ZigType *return_type)
1239{
1240 IrInstGenElemPtr *instruction = ir_build_inst_gen<IrInstGenElemPtr>(&ira->new_irb, scope, source_node);
1241 instruction->base.value->type = return_type;
1242 instruction->array_ptr = array_ptr;
1243 instruction->elem_index = elem_index;
1244 instruction->safety_check_on = safety_check_on;
15811245
1582static constexpr IrInstSrcId ir_inst_id(IrInstSrcAddImplicitReturnType *) {
1583 return IrInstSrcIdAddImplicitReturnType;
1584}
1246 ir_ref_inst_gen(array_ptr);
1247 ir_ref_inst_gen(elem_index);
15851248
1586static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrSetCast *) {
1587 return IrInstSrcIdErrSetCast;
1249 return &instruction->base;
15881250}
15891251
1590static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckRuntimeScope *) {
1591 return IrInstSrcIdCheckRuntimeScope;
1592}
1252static IrInstGen *ir_build_struct_field_ptr(IrAnalyze *ira, IrInst *source_instr,
1253 IrInstGen *struct_ptr, TypeStructField *field, ZigType *ptr_type)
1254{
1255 IrInstGenStructFieldPtr *inst = ir_build_inst_gen<IrInstGenStructFieldPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1256 inst->base.value->type = ptr_type;
1257 inst->struct_ptr = struct_ptr;
1258 inst->field = field;
15931259
1594static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasDecl *) {
1595 return IrInstSrcIdHasDecl;
1596}
1260 ir_ref_inst_gen(struct_ptr);
15971261
1598static constexpr IrInstSrcId ir_inst_id(IrInstSrcUndeclaredIdent *) {
1599 return IrInstSrcIdUndeclaredIdent;
1262 return &inst->base;
16001263}
16011264
1602static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlloca *) {
1603 return IrInstSrcIdAlloca;
1604}
1265static IrInstGen *ir_build_union_field_ptr(IrAnalyze *ira, IrInst *source_instr,
1266 IrInstGen *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing, ZigType *ptr_type)
1267{
1268 IrInstGenUnionFieldPtr *inst = ir_build_inst_gen<IrInstGenUnionFieldPtr>(&ira->new_irb,
1269 source_instr->scope, source_instr->source_node);
1270 inst->base.value->type = ptr_type;
1271 inst->initializing = initializing;
1272 inst->safety_check_on = safety_check_on;
1273 inst->union_ptr = union_ptr;
1274 inst->field = field;
16051275
1606static constexpr IrInstSrcId ir_inst_id(IrInstSrcEndExpr *) {
1607 return IrInstSrcIdEndExpr;
1608}
1276 ir_ref_inst_gen(union_ptr);
16091277
1610static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnionInitNamedField *) {
1611 return IrInstSrcIdUnionInitNamedField;
1278 return &inst->base;
16121279}
16131280
1614static constexpr IrInstSrcId ir_inst_id(IrInstSrcSuspendBegin *) {
1615 return IrInstSrcIdSuspendBegin;
1616}
1281static IrInstGenCall *ir_build_call_gen(IrAnalyze *ira, IrInst *source_instruction,
1282 ZigFn *fn_entry, IrInstGen *fn_ref, size_t arg_count, IrInstGen **args,
1283 CallModifier modifier, IrInstGen *new_stack, bool is_async_call_builtin,
1284 IrInstGen *result_loc, ZigType *return_type)
1285{
1286 IrInstGenCall *call_instruction = ir_build_inst_gen<IrInstGenCall>(&ira->new_irb,
1287 source_instruction->scope, source_instruction->source_node);
1288 call_instruction->base.value->type = return_type;
1289 call_instruction->fn_entry = fn_entry;
1290 call_instruction->fn_ref = fn_ref;
1291 call_instruction->args = args;
1292 call_instruction->arg_count = arg_count;
1293 call_instruction->modifier = modifier;
1294 call_instruction->is_async_call_builtin = is_async_call_builtin;
1295 call_instruction->new_stack = new_stack;
1296 call_instruction->result_loc = result_loc;
16171297
1618static constexpr IrInstSrcId ir_inst_id(IrInstSrcSuspendFinish *) {
1619 return IrInstSrcIdSuspendFinish;
1620}
1298 if (fn_ref != nullptr) ir_ref_inst_gen(fn_ref);
1299 for (size_t i = 0; i < arg_count; i += 1)
1300 ir_ref_inst_gen(args[i]);
1301 if (new_stack != nullptr) ir_ref_inst_gen(new_stack);
1302 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
16211303
1622static constexpr IrInstSrcId ir_inst_id(IrInstSrcAwait *) {
1623 return IrInstSrcIdAwait;
1304 return call_instruction;
16241305}
16251306
1626static constexpr IrInstSrcId ir_inst_id(IrInstSrcResume *) {
1627 return IrInstSrcIdResume;
1628}
1307static IrInstGen *ir_build_phi_gen(IrAnalyze *ira, IrInst *source_instr, size_t incoming_count,
1308 IrBasicBlockGen **incoming_blocks, IrInstGen **incoming_values, ZigType *result_type)
1309{
1310 assert(incoming_count != 0);
1311 assert(incoming_count != SIZE_MAX);
16291312
1630static constexpr IrInstSrcId ir_inst_id(IrInstSrcSpillBegin *) {
1631 return IrInstSrcIdSpillBegin;
1632}
1313 IrInstGenPhi *phi_instruction = ir_build_inst_gen<IrInstGenPhi>(&ira->new_irb,
1314 source_instr->scope, source_instr->source_node);
1315 phi_instruction->base.value->type = result_type;
1316 phi_instruction->incoming_count = incoming_count;
1317 phi_instruction->incoming_blocks = incoming_blocks;
1318 phi_instruction->incoming_values = incoming_values;
16331319
1634static constexpr IrInstSrcId ir_inst_id(IrInstSrcSpillEnd *) {
1635 return IrInstSrcIdSpillEnd;
1636}
1320 for (size_t i = 0; i < incoming_count; i += 1) {
1321 ir_ref_inst_gen(incoming_values[i]);
1322 }
16371323
1638static constexpr IrInstSrcId ir_inst_id(IrInstSrcWasmMemorySize *) {
1639 return IrInstSrcIdWasmMemorySize;
1324 return &phi_instruction->base;
16401325}
16411326
1642static constexpr IrInstSrcId ir_inst_id(IrInstSrcWasmMemoryGrow *) {
1643 return IrInstSrcIdWasmMemoryGrow;
1644}
1327static IrInstGen *ir_build_br_gen(IrAnalyze *ira, IrInst *source_instr, IrBasicBlockGen *dest_block) {
1328 IrInstGenBr *inst = ir_build_inst_noreturn<IrInstGenBr>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1329 inst->dest_block = dest_block;
16451330
1646static constexpr IrInstSrcId ir_inst_id(IrInstSrcSrc *) {
1647 return IrInstSrcIdSrc;
1331 return &inst->base;
16481332}
16491333
1650static constexpr IrInstGenId ir_inst_id(IrInstGenDeclVar *) {
1651 return IrInstGenIdDeclVar;
1652}
1334static IrInstGen *ir_build_negation(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, ZigType *expr_type, bool wrapping) {
1335 IrInstGenNegation *instruction = ir_build_inst_gen<IrInstGenNegation>(&ira->new_irb,
1336 source_instr->scope, source_instr->source_node);
1337 instruction->base.value->type = expr_type;
1338 instruction->operand = operand;
1339 instruction->wrapping = wrapping;
16531340
1654static constexpr IrInstGenId ir_inst_id(IrInstGenBr *) {
1655 return IrInstGenIdBr;
1656}
1341 ir_ref_inst_gen(operand);
16571342
1658static constexpr IrInstGenId ir_inst_id(IrInstGenCondBr *) {
1659 return IrInstGenIdCondBr;
1343 return &instruction->base;
16601344}
16611345
1662static constexpr IrInstGenId ir_inst_id(IrInstGenSwitchBr *) {
1663 return IrInstGenIdSwitchBr;
1664}
1346static IrInstGen *ir_build_binary_not(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand,
1347 ZigType *expr_type)
1348{
1349 IrInstGenBinaryNot *instruction = ir_build_inst_gen<IrInstGenBinaryNot>(&ira->new_irb,
1350 source_instr->scope, source_instr->source_node);
1351 instruction->base.value->type = expr_type;
1352 instruction->operand = operand;
16651353
1666static constexpr IrInstGenId ir_inst_id(IrInstGenPhi *) {
1667 return IrInstGenIdPhi;
1668}
1354 ir_ref_inst_gen(operand);
16691355
1670static constexpr IrInstGenId ir_inst_id(IrInstGenBinaryNot *) {
1671 return IrInstGenIdBinaryNot;
1356 return &instruction->base;
16721357}
16731358
1674static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) {
1675 return IrInstGenIdNegation;
1359static IrInstGen *ir_build_unreachable_gen(IrAnalyze *ira, IrInst *source_instr) {
1360 IrInstGenUnreachable *inst = ir_build_inst_noreturn<IrInstGenUnreachable>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1361 return &inst->base;
16761362}
16771363
1678static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) {
1679 return IrInstGenIdBinOp;
1680}
1364static IrInstGen *ir_build_store_ptr_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *ptr, IrInstGen *value) {
1365 IrInstGenStorePtr *instruction = ir_build_inst_void<IrInstGenStorePtr>(&ira->new_irb,
1366 source_instr->scope, source_instr->source_node);
1367 instruction->ptr = ptr;
1368 instruction->value = value;
16811369
1682static constexpr IrInstGenId ir_inst_id(IrInstGenLoadPtr *) {
1683 return IrInstGenIdLoadPtr;
1684}
1370 ir_ref_inst_gen(ptr);
1371 ir_ref_inst_gen(value);
16851372
1686static constexpr IrInstGenId ir_inst_id(IrInstGenStorePtr *) {
1687 return IrInstGenIdStorePtr;
1373 return &instruction->base;
16881374}
16891375
1690static constexpr IrInstGenId ir_inst_id(IrInstGenVectorStoreElem *) {
1691 return IrInstGenIdVectorStoreElem;
1692}
1376static IrInstGen *ir_build_vector_store_elem(IrAnalyze *ira, IrInst *src_inst,
1377 IrInstGen *vector_ptr, IrInstGen *index, IrInstGen *value)
1378{
1379 IrInstGenVectorStoreElem *inst = ir_build_inst_void<IrInstGenVectorStoreElem>(
1380 &ira->new_irb, src_inst->scope, src_inst->source_node);
1381 inst->vector_ptr = vector_ptr;
1382 inst->index = index;
1383 inst->value = value;
16931384
1694static constexpr IrInstGenId ir_inst_id(IrInstGenStructFieldPtr *) {
1695 return IrInstGenIdStructFieldPtr;
1696}
1385 ir_ref_inst_gen(vector_ptr);
1386 ir_ref_inst_gen(index);
1387 ir_ref_inst_gen(value);
16971388
1698static constexpr IrInstGenId ir_inst_id(IrInstGenUnionFieldPtr *) {
1699 return IrInstGenIdUnionFieldPtr;
1389 return &inst->base;
17001390}
17011391
1702static constexpr IrInstGenId ir_inst_id(IrInstGenElemPtr *) {
1703 return IrInstGenIdElemPtr;
1704}
1392static IrInstGen *ir_build_var_decl_gen(IrAnalyze *ira, IrInst *source_instruction,
1393 ZigVar *var, IrInstGen *var_ptr)
1394{
1395 IrInstGenDeclVar *inst = ir_build_inst_gen<IrInstGenDeclVar>(&ira->new_irb,
1396 source_instruction->scope, source_instruction->source_node);
1397 inst->base.value->special = ConstValSpecialStatic;
1398 inst->base.value->type = ira->codegen->builtin_types.entry_void;
1399 inst->var = var;
1400 inst->var_ptr = var_ptr;
17051401
1706static constexpr IrInstGenId ir_inst_id(IrInstGenVarPtr *) {
1707 return IrInstGenIdVarPtr;
1708}
1402 ir_ref_inst_gen(var_ptr);
17091403
1710static constexpr IrInstGenId ir_inst_id(IrInstGenReturnPtr *) {
1711 return IrInstGenIdReturnPtr;
1404 return &inst->base;
17121405}
17131406
1714static constexpr IrInstGenId ir_inst_id(IrInstGenCall *) {
1715 return IrInstGenIdCall;
1716}
1407static IrInstGen *ir_build_extern_gen(IrAnalyze *ira, IrInst *source_instr, Buf *name,
1408 GlobalLinkageId linkage, bool is_thread_local, ZigType *expr_type)
1409{
1410 IrInstGenExtern *instruction = ir_build_inst_gen<IrInstGenExtern>(&ira->new_irb,
1411 source_instr->scope, source_instr->source_node);
1412 instruction->base.value->type = expr_type;
1413 instruction->name = name;
1414 instruction->linkage = linkage;
1415 instruction->is_thread_local = is_thread_local;
17171416
1718static constexpr IrInstGenId ir_inst_id(IrInstGenReturn *) {
1719 return IrInstGenIdReturn;
1417 return &instruction->base;
17201418}
17211419
1722static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) {
1723 return IrInstGenIdCast;
1724}
1420static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instruction,
1421 IrInstGen *ptr, ZigType *ty, IrInstGen *result_loc)
1422{
1423 IrInstGenLoadPtr *instruction = ir_build_inst_gen<IrInstGenLoadPtr>(
1424 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1425 instruction->base.value->type = ty;
1426 instruction->ptr = ptr;
1427 instruction->result_loc = result_loc;
17251428
1726static constexpr IrInstGenId ir_inst_id(IrInstGenUnreachable *) {
1727 return IrInstGenIdUnreachable;
1728}
1429 ir_ref_inst_gen(ptr);
1430 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
17291431
1730static constexpr IrInstGenId ir_inst_id(IrInstGenAsm *) {
1731 return IrInstGenIdAsm;
1432 return &instruction->base;
17321433}
17331434
1734static constexpr IrInstGenId ir_inst_id(IrInstGenTestNonNull *) {
1735 return IrInstGenIdTestNonNull;
1736}
1435static IrInstGen *ir_build_asm_gen(IrAnalyze *ira, IrInst *source_instr,
1436 Buf *asm_template, AsmToken *token_list, size_t token_list_len,
1437 IrInstGen **input_list, IrInstGen **output_types, ZigVar **output_vars, size_t return_count,
1438 bool has_side_effects, ZigType *return_type)
1439{
1440 IrInstGenAsm *instruction = ir_build_inst_gen<IrInstGenAsm>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1441 instruction->base.value->type = return_type;
1442 instruction->asm_template = asm_template;
1443 instruction->token_list = token_list;
1444 instruction->token_list_len = token_list_len;
1445 instruction->input_list = input_list;
1446 instruction->output_types = output_types;
1447 instruction->output_vars = output_vars;
1448 instruction->return_count = return_count;
1449 instruction->has_side_effects = has_side_effects;
17371450
1738static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalUnwrapPtr *) {
1739 return IrInstGenIdOptionalUnwrapPtr;
1740}
1451 assert(source_instr->source_node->type == NodeTypeAsmExpr);
1452 for (size_t i = 0; i < source_instr->source_node->data.asm_expr.output_list.length; i += 1) {
1453 IrInstGen *output_type = output_types[i];
1454 if (output_type) ir_ref_inst_gen(output_type);
1455 }
17411456
1742static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalWrap *) {
1743 return IrInstGenIdOptionalWrap;
1744}
1457 for (size_t i = 0; i < source_instr->source_node->data.asm_expr.input_list.length; i += 1) {
1458 IrInstGen *input_value = input_list[i];
1459 ir_ref_inst_gen(input_value);
1460 }
17451461
1746static constexpr IrInstGenId ir_inst_id(IrInstGenUnionTag *) {
1747 return IrInstGenIdUnionTag;
1462 return &instruction->base;
17481463}
17491464
1750static constexpr IrInstGenId ir_inst_id(IrInstGenClz *) {
1751 return IrInstGenIdClz;
1752}
1465static IrInstGen *ir_build_test_non_null_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) {
1466 IrInstGenTestNonNull *inst = ir_build_inst_gen<IrInstGenTestNonNull>(&ira->new_irb,
1467 source_instr->scope, source_instr->source_node);
1468 inst->base.value->type = ira->codegen->builtin_types.entry_bool;
1469 inst->value = value;
17531470
1754static constexpr IrInstGenId ir_inst_id(IrInstGenCtz *) {
1755 return IrInstGenIdCtz;
1756}
1471 ir_ref_inst_gen(value);
17571472
1758static constexpr IrInstGenId ir_inst_id(IrInstGenPopCount *) {
1759 return IrInstGenIdPopCount;
1473 return &inst->base;
17601474}
17611475
1762static constexpr IrInstGenId ir_inst_id(IrInstGenBswap *) {
1763 return IrInstGenIdBswap;
1764}
1476static IrInstGen *ir_build_optional_unwrap_ptr_gen(IrAnalyze *ira, IrInst *source_instr,
1477 IrInstGen *base_ptr, bool safety_check_on, bool initializing, ZigType *result_type)
1478{
1479 IrInstGenOptionalUnwrapPtr *inst = ir_build_inst_gen<IrInstGenOptionalUnwrapPtr>(&ira->new_irb,
1480 source_instr->scope, source_instr->source_node);
1481 inst->base.value->type = result_type;
1482 inst->base_ptr = base_ptr;
1483 inst->safety_check_on = safety_check_on;
1484 inst->initializing = initializing;
17651485
1766static constexpr IrInstGenId ir_inst_id(IrInstGenBitReverse *) {
1767 return IrInstGenIdBitReverse;
1486 ir_ref_inst_gen(base_ptr);
1487
1488 return &inst->base;
17681489}
17691490
1770static constexpr IrInstGenId ir_inst_id(IrInstGenRef *) {
1771 return IrInstGenIdRef;
1772}
1491static IrInstGen *ir_build_optional_wrap(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_ty,
1492 IrInstGen *operand, IrInstGen *result_loc)
1493{
1494 IrInstGenOptionalWrap *instruction = ir_build_inst_gen<IrInstGenOptionalWrap>(
1495 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1496 instruction->base.value->type = result_ty;
1497 instruction->operand = operand;
1498 instruction->result_loc = result_loc;
17731499
1774static constexpr IrInstGenId ir_inst_id(IrInstGenErrName *) {
1775 return IrInstGenIdErrName;
1776}
1500 ir_ref_inst_gen(operand);
1501 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
17771502
1778static constexpr IrInstGenId ir_inst_id(IrInstGenCmpxchg *) {
1779 return IrInstGenIdCmpxchg;
1503 return &instruction->base;
17801504}
17811505
1782static constexpr IrInstGenId ir_inst_id(IrInstGenFence *) {
1783 return IrInstGenIdFence;
1784}
1506static IrInstGen *ir_build_err_wrap_payload(IrAnalyze *ira, IrInst *source_instruction,
1507 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc)
1508{
1509 IrInstGenErrWrapPayload *instruction = ir_build_inst_gen<IrInstGenErrWrapPayload>(
1510 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1511 instruction->base.value->type = result_type;
1512 instruction->operand = operand;
1513 instruction->result_loc = result_loc;
17851514
1786static constexpr IrInstGenId ir_inst_id(IrInstGenReduce *) {
1787 return IrInstGenIdReduce;
1788}
1515 ir_ref_inst_gen(operand);
1516 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
17891517
1790static constexpr IrInstGenId ir_inst_id(IrInstGenTruncate *) {
1791 return IrInstGenIdTruncate;
1518 return &instruction->base;
17921519}
17931520
1794static constexpr IrInstGenId ir_inst_id(IrInstGenShuffleVector *) {
1795 return IrInstGenIdShuffleVector;
1796}
1521static IrInstGen *ir_build_err_wrap_code(IrAnalyze *ira, IrInst *source_instruction,
1522 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc)
1523{
1524 IrInstGenErrWrapCode *instruction = ir_build_inst_gen<IrInstGenErrWrapCode>(
1525 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1526 instruction->base.value->type = result_type;
1527 instruction->operand = operand;
1528 instruction->result_loc = result_loc;
17971529
1798static constexpr IrInstGenId ir_inst_id(IrInstGenSplat *) {
1799 return IrInstGenIdSplat;
1800}
1530 ir_ref_inst_gen(operand);
1531 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
18011532
1802static constexpr IrInstGenId ir_inst_id(IrInstGenBoolNot *) {
1803 return IrInstGenIdBoolNot;
1533 return &instruction->base;
18041534}
18051535
1806static constexpr IrInstGenId ir_inst_id(IrInstGenMemset *) {
1807 return IrInstGenIdMemset;
1808}
1536static IrInstGen *ir_build_clz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) {
1537 IrInstGenClz *instruction = ir_build_inst_gen<IrInstGenClz>(&ira->new_irb,
1538 source_instr->scope, source_instr->source_node);
1539 instruction->base.value->type = result_type;
1540 instruction->op = op;
18091541
1810static constexpr IrInstGenId ir_inst_id(IrInstGenMemcpy *) {
1811 return IrInstGenIdMemcpy;
1812}
1542 ir_ref_inst_gen(op);
18131543
1814static constexpr IrInstGenId ir_inst_id(IrInstGenSlice *) {
1815 return IrInstGenIdSlice;
1544 return &instruction->base;
18161545}
18171546
1818static constexpr IrInstGenId ir_inst_id(IrInstGenBreakpoint *) {
1819 return IrInstGenIdBreakpoint;
1820}
1547static IrInstGen *ir_build_ctz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) {
1548 IrInstGenCtz *instruction = ir_build_inst_gen<IrInstGenCtz>(&ira->new_irb,
1549 source_instr->scope, source_instr->source_node);
1550 instruction->base.value->type = result_type;
1551 instruction->op = op;
18211552
1822static constexpr IrInstGenId ir_inst_id(IrInstGenReturnAddress *) {
1823 return IrInstGenIdReturnAddress;
1824}
1553 ir_ref_inst_gen(op);
18251554
1826static constexpr IrInstGenId ir_inst_id(IrInstGenFrameAddress *) {
1827 return IrInstGenIdFrameAddress;
1555 return &instruction->base;
18281556}
18291557
1830static constexpr IrInstGenId ir_inst_id(IrInstGenFrameHandle *) {
1831 return IrInstGenIdFrameHandle;
1832}
1558static IrInstGen *ir_build_pop_count_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type,
1559 IrInstGen *op)
1560{
1561 IrInstGenPopCount *instruction = ir_build_inst_gen<IrInstGenPopCount>(&ira->new_irb,
1562 source_instr->scope, source_instr->source_node);
1563 instruction->base.value->type = result_type;
1564 instruction->op = op;
18331565
1834static constexpr IrInstGenId ir_inst_id(IrInstGenFrameSize *) {
1835 return IrInstGenIdFrameSize;
1836}
1566 ir_ref_inst_gen(op);
18371567
1838static constexpr IrInstGenId ir_inst_id(IrInstGenOverflowOp *) {
1839 return IrInstGenIdOverflowOp;
1568 return &instruction->base;
18401569}
18411570
1842static constexpr IrInstGenId ir_inst_id(IrInstGenTestErr *) {
1843 return IrInstGenIdTestErr;
1844}
1571static IrInstGen *ir_build_bswap_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *op_type,
1572 IrInstGen *op)
1573{
1574 IrInstGenBswap *instruction = ir_build_inst_gen<IrInstGenBswap>(&ira->new_irb,
1575 source_instr->scope, source_instr->source_node);
1576 instruction->base.value->type = op_type;
1577 instruction->op = op;
18451578
1846static constexpr IrInstGenId ir_inst_id(IrInstGenMulAdd *) {
1847 return IrInstGenIdMulAdd;
1848}
1579 ir_ref_inst_gen(op);
18491580
1850static constexpr IrInstGenId ir_inst_id(IrInstGenFloatOp *) {
1851 return IrInstGenIdFloatOp;
1581 return &instruction->base;
18521582}
18531583
1854static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrCode *) {
1855 return IrInstGenIdUnwrapErrCode;
1856}
1584static IrInstGen *ir_build_bit_reverse_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *int_type,
1585 IrInstGen *op)
1586{
1587 IrInstGenBitReverse *instruction = ir_build_inst_gen<IrInstGenBitReverse>(&ira->new_irb,
1588 source_instr->scope, source_instr->source_node);
1589 instruction->base.value->type = int_type;
1590 instruction->op = op;
18571591
1858static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrPayload *) {
1859 return IrInstGenIdUnwrapErrPayload;
1860}
1592 ir_ref_inst_gen(op);
18611593
1862static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapCode *) {
1863 return IrInstGenIdErrWrapCode;
1594 return &instruction->base;
18641595}
18651596
1866static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapPayload *) {
1867 return IrInstGenIdErrWrapPayload;
1868}
1597static IrInstGenSwitchBr *ir_build_switch_br_gen(IrAnalyze *ira, IrInst *source_instr,
1598 IrInstGen *target_value, IrBasicBlockGen *else_block, size_t case_count, IrInstGenSwitchBrCase *cases)
1599{
1600 IrInstGenSwitchBr *instruction = ir_build_inst_noreturn<IrInstGenSwitchBr>(&ira->new_irb,
1601 source_instr->scope, source_instr->source_node);
1602 instruction->target_value = target_value;
1603 instruction->else_block = else_block;
1604 instruction->case_count = case_count;
1605 instruction->cases = cases;
18691606
1870static constexpr IrInstGenId ir_inst_id(IrInstGenPtrCast *) {
1871 return IrInstGenIdPtrCast;
1872}
1607 ir_ref_inst_gen(target_value);
18731608
1874static constexpr IrInstGenId ir_inst_id(IrInstGenBitCast *) {
1875 return IrInstGenIdBitCast;
1876}
1609 for (size_t i = 0; i < case_count; i += 1) {
1610 ir_ref_inst_gen(cases[i].value);
1611 }
18771612
1878static constexpr IrInstGenId ir_inst_id(IrInstGenWidenOrShorten *) {
1879 return IrInstGenIdWidenOrShorten;
1613 return instruction;
18801614}
18811615
1882static constexpr IrInstGenId ir_inst_id(IrInstGenIntToPtr *) {
1883 return IrInstGenIdIntToPtr;
1884}
1616static IrInstGen *ir_build_union_tag(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value,
1617 ZigType *tag_type)
1618{
1619 IrInstGenUnionTag *instruction = ir_build_inst_gen<IrInstGenUnionTag>(&ira->new_irb,
1620 source_instr->scope, source_instr->source_node);
1621 instruction->value = value;
1622 instruction->base.value->type = tag_type;
18851623
1886static constexpr IrInstGenId ir_inst_id(IrInstGenPtrToInt *) {
1887 return IrInstGenIdPtrToInt;
1888}
1624 ir_ref_inst_gen(value);
18891625
1890static constexpr IrInstGenId ir_inst_id(IrInstGenIntToEnum *) {
1891 return IrInstGenIdIntToEnum;
1626 return &instruction->base;
18921627}
18931628
1894static constexpr IrInstGenId ir_inst_id(IrInstGenIntToErr *) {
1895 return IrInstGenIdIntToErr;
1896}
1629static IrInstGen *ir_build_ref_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type,
1630 IrInstGen *operand, IrInstGen *result_loc)
1631{
1632 IrInstGenRef *instruction = ir_build_inst_gen<IrInstGenRef>(&ira->new_irb,
1633 source_instruction->scope, source_instruction->source_node);
1634 instruction->base.value->type = result_type;
1635 instruction->operand = operand;
1636 instruction->result_loc = result_loc;
18971637
1898static constexpr IrInstGenId ir_inst_id(IrInstGenErrToInt *) {
1899 return IrInstGenIdErrToInt;
1900}
1638 ir_ref_inst_gen(operand);
1639 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
19011640
1902static constexpr IrInstGenId ir_inst_id(IrInstGenPanic *) {
1903 return IrInstGenIdPanic;
1641 return &instruction->base;
19041642}
19051643
1906static constexpr IrInstGenId ir_inst_id(IrInstGenTagName *) {
1907 return IrInstGenIdTagName;
1908}
1644static IrInstGen *ir_build_err_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value,
1645 ZigType *str_type)
1646{
1647 IrInstGenErrName *instruction = ir_build_inst_gen<IrInstGenErrName>(&ira->new_irb,
1648 source_instr->scope, source_instr->source_node);
1649 instruction->base.value->type = str_type;
1650 instruction->value = value;
19091651
1910static constexpr IrInstGenId ir_inst_id(IrInstGenFieldParentPtr *) {
1911 return IrInstGenIdFieldParentPtr;
1912}
1652 ir_ref_inst_gen(value);
19131653
1914static constexpr IrInstGenId ir_inst_id(IrInstGenAlignCast *) {
1915 return IrInstGenIdAlignCast;
1654 return &instruction->base;
19161655}
19171656
1918static constexpr IrInstGenId ir_inst_id(IrInstGenErrorReturnTrace *) {
1919 return IrInstGenIdErrorReturnTrace;
1920}
1657static IrInstGen *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type,
1658 IrInstGen *ptr, IrInstGen *cmp_value, IrInstGen *new_value,
1659 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstGen *result_loc)
1660{
1661 IrInstGenCmpxchg *instruction = ir_build_inst_gen<IrInstGenCmpxchg>(&ira->new_irb,
1662 source_instruction->scope, source_instruction->source_node);
1663 instruction->base.value->type = result_type;
1664 instruction->ptr = ptr;
1665 instruction->cmp_value = cmp_value;
1666 instruction->new_value = new_value;
1667 instruction->success_order = success_order;
1668 instruction->failure_order = failure_order;
1669 instruction->is_weak = is_weak;
1670 instruction->result_loc = result_loc;
19211671
1922static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicRmw *) {
1923 return IrInstGenIdAtomicRmw;
1924}
1672 ir_ref_inst_gen(ptr);
1673 ir_ref_inst_gen(cmp_value);
1674 ir_ref_inst_gen(new_value);
1675 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
19251676
1926static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicLoad *) {
1927 return IrInstGenIdAtomicLoad;
1677 return &instruction->base;
19281678}
19291679
1930static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicStore *) {
1931 return IrInstGenIdAtomicStore;
1932}
1680static IrInstGen *ir_build_fence_gen(IrAnalyze *ira, IrInst *source_instr, AtomicOrder order) {
1681 IrInstGenFence *instruction = ir_build_inst_void<IrInstGenFence>(&ira->new_irb,
1682 source_instr->scope, source_instr->source_node);
1683 instruction->order = order;
19331684
1934static constexpr IrInstGenId ir_inst_id(IrInstGenSaveErrRetAddr *) {
1935 return IrInstGenIdSaveErrRetAddr;
1685 return &instruction->base;
19361686}
19371687
1938static constexpr IrInstGenId ir_inst_id(IrInstGenVectorToArray *) {
1939 return IrInstGenIdVectorToArray;
1940}
1941
1942static constexpr IrInstGenId ir_inst_id(IrInstGenArrayToVector *) {
1943 return IrInstGenIdArrayToVector;
1944}
1688static IrInstGen *ir_build_reduce_gen(IrAnalyze *ira, IrInst *source_instruction, ReduceOp op, IrInstGen *value, ZigType *result_type) {
1689 IrInstGenReduce *instruction = ir_build_inst_gen<IrInstGenReduce>(&ira->new_irb,
1690 source_instruction->scope, source_instruction->source_node);
1691 instruction->base.value->type = result_type;
1692 instruction->op = op;
1693 instruction->value = value;
19451694
1946static constexpr IrInstGenId ir_inst_id(IrInstGenAssertZero *) {
1947 return IrInstGenIdAssertZero;
1948}
1695 ir_ref_inst_gen(value);
19491696
1950static constexpr IrInstGenId ir_inst_id(IrInstGenAssertNonNull *) {
1951 return IrInstGenIdAssertNonNull;
1697 return &instruction->base;
19521698}
19531699
1954static constexpr IrInstGenId ir_inst_id(IrInstGenPtrOfArrayToSlice *) {
1955 return IrInstGenIdPtrOfArrayToSlice;
1700static void ir_set_cursor_at_end_gen(IrBuilderGen *irb, IrBasicBlockGen *basic_block) {
1701 assert(basic_block);
1702 irb->current_basic_block = basic_block;
19561703}
19571704
1958static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendBegin *) {
1959 return IrInstGenIdSuspendBegin;
1705static void ir_append_basic_block_gen(IrBuilderGen *irb, IrBasicBlockGen *bb) {
1706 assert(!bb->already_appended);
1707 bb->already_appended = true;
1708 irb->exec->basic_block_list.append(bb);
19601709}
19611710
1962static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendFinish *) {
1963 return IrInstGenIdSuspendFinish;
1711static void ir_set_cursor_at_end_and_append_block_gen(IrBuilderGen *irb, IrBasicBlockGen *basic_block) {
1712 ir_append_basic_block_gen(irb, basic_block);
1713 ir_set_cursor_at_end_gen(irb, basic_block);
19641714}
19651715
1966static constexpr IrInstGenId ir_inst_id(IrInstGenAwait *) {
1967 return IrInstGenIdAwait;
1716static IrInstGen *ir_build_suspend_begin_gen(IrAnalyze *ira, IrInst *source_instr) {
1717 IrInstGenSuspendBegin *inst = ir_build_inst_void<IrInstGenSuspendBegin>(&ira->new_irb,
1718 source_instr->scope, source_instr->source_node);
1719 return &inst->base;
19681720}
19691721
1970static constexpr IrInstGenId ir_inst_id(IrInstGenResume *) {
1971 return IrInstGenIdResume;
1722static IrInstGen *ir_build_save_err_ret_addr_gen(IrAnalyze *ira, IrInst *source_instr) {
1723 IrInstGenSaveErrRetAddr *inst = ir_build_inst_void<IrInstGenSaveErrRetAddr>(&ira->new_irb,
1724 source_instr->scope, source_instr->source_node);
1725 return &inst->base;
19721726}
19731727
1974static constexpr IrInstGenId ir_inst_id(IrInstGenSpillBegin *) {
1975 return IrInstGenIdSpillBegin;
1976}
1728static IrInstGen *ir_build_truncate_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *dest_type,
1729 IrInstGen *target)
1730{
1731 IrInstGenTruncate *instruction = ir_build_inst_gen<IrInstGenTruncate>(&ira->new_irb,
1732 source_instr->scope, source_instr->source_node);
1733 instruction->base.value->type = dest_type;
1734 instruction->target = target;
19771735
1978static constexpr IrInstGenId ir_inst_id(IrInstGenSpillEnd *) {
1979 return IrInstGenIdSpillEnd;
1980}
1736 ir_ref_inst_gen(target);
19811737
1982static constexpr IrInstGenId ir_inst_id(IrInstGenVectorExtractElem *) {
1983 return IrInstGenIdVectorExtractElem;
1738 return &instruction->base;
19841739}
19851740
1986static constexpr IrInstGenId ir_inst_id(IrInstGenAlloca *) {
1987 return IrInstGenIdAlloca;
1988}
1741static IrInstGen *ir_build_shuffle_vector_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
1742 ZigType *result_type, IrInstGen *a, IrInstGen *b, IrInstGen *mask)
1743{
1744 IrInstGenShuffleVector *inst = ir_build_inst_gen<IrInstGenShuffleVector>(&ira->new_irb, scope, source_node);
1745 inst->base.value->type = result_type;
1746 inst->a = a;
1747 inst->b = b;
1748 inst->mask = mask;
19891749
1990static constexpr IrInstGenId ir_inst_id(IrInstGenConst *) {
1991 return IrInstGenIdConst;
1992}
1750 ir_ref_inst_gen(a);
1751 ir_ref_inst_gen(b);
1752 ir_ref_inst_gen(mask);
19931753
1994static constexpr IrInstGenId ir_inst_id(IrInstGenWasmMemorySize *) {
1995 return IrInstGenIdWasmMemorySize;
1754 return &inst->base;
19961755}
19971756
1998static constexpr IrInstGenId ir_inst_id(IrInstGenWasmMemoryGrow *) {
1999 return IrInstGenIdWasmMemoryGrow;
2000}
1757static IrInstGen *ir_build_splat_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type,
1758 IrInstGen *scalar)
1759{
1760 IrInstGenSplat *instruction = ir_build_inst_gen<IrInstGenSplat>(
1761 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1762 instruction->base.value->type = result_type;
1763 instruction->scalar = scalar;
20011764
2002static constexpr IrInstGenId ir_inst_id(IrInstGenExtern *) {
2003 return IrInstGenIdExtern;
2004}
1765 ir_ref_inst_gen(scalar);
20051766
2006template<typename T>
2007static T *ir_create_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
2008 T *special_instruction = heap::c_allocator.create<T>();
2009 special_instruction->base.id = ir_inst_id(special_instruction);
2010 special_instruction->base.base.scope = scope;
2011 special_instruction->base.base.source_node = source_node;
2012 special_instruction->base.base.debug_id = exec_next_debug_id(irb->exec);
2013 special_instruction->base.owner_bb = irb->current_basic_block;
2014 return special_instruction;
1767 return &instruction->base;
20151768}
20161769
2017template<typename T>
2018static T *ir_create_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {
2019 T *special_instruction = heap::c_allocator.create<T>();
2020 special_instruction->base.id = ir_inst_id(special_instruction);
2021 special_instruction->base.base.scope = scope;
2022 special_instruction->base.base.source_node = source_node;
2023 special_instruction->base.base.debug_id = exec_next_debug_id_gen(irb->exec);
2024 special_instruction->base.owner_bb = irb->current_basic_block;
2025 special_instruction->base.value = irb->codegen->pass1_arena->create<ZigValue>();
2026 return special_instruction;
2027}
1770static IrInstGen *ir_build_bool_not_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) {
1771 IrInstGenBoolNot *instruction = ir_build_inst_gen<IrInstGenBoolNot>(&ira->new_irb,
1772 source_instr->scope, source_instr->source_node);
1773 instruction->base.value->type = ira->codegen->builtin_types.entry_bool;
1774 instruction->value = value;
20281775
2029template<typename T>
2030static T *ir_create_inst_noval(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {
2031 T *special_instruction = heap::c_allocator.create<T>();
2032 special_instruction->base.id = ir_inst_id(special_instruction);
2033 special_instruction->base.base.scope = scope;
2034 special_instruction->base.base.source_node = source_node;
2035 special_instruction->base.base.debug_id = exec_next_debug_id_gen(irb->exec);
2036 special_instruction->base.owner_bb = irb->current_basic_block;
2037 return special_instruction;
2038}
1776 ir_ref_inst_gen(value);
20391777
2040template<typename T>
2041static T *ir_build_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
2042 T *special_instruction = ir_create_instruction<T>(irb, scope, source_node);
2043 ir_instruction_append(irb->current_basic_block, &special_instruction->base);
2044 return special_instruction;
1778 return &instruction->base;
20451779}
20461780
2047template<typename T>
2048static T *ir_build_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {
2049 T *special_instruction = ir_create_inst_gen<T>(irb, scope, source_node);
2050 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base);
2051 return special_instruction;
2052}
1781static IrInstGen *ir_build_memset_gen(IrAnalyze *ira, IrInst *source_instr,
1782 IrInstGen *dest_ptr, IrInstGen *byte, IrInstGen *count)
1783{
1784 IrInstGenMemset *instruction = ir_build_inst_void<IrInstGenMemset>(&ira->new_irb,
1785 source_instr->scope, source_instr->source_node);
1786 instruction->dest_ptr = dest_ptr;
1787 instruction->byte = byte;
1788 instruction->count = count;
20531789
2054template<typename T>
2055static T *ir_build_inst_noreturn(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {
2056 T *special_instruction = ir_create_inst_noval<T>(irb, scope, source_node);
2057 special_instruction->base.value = irb->codegen->intern.for_unreachable();
2058 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base);
2059 return special_instruction;
2060}
1790 ir_ref_inst_gen(dest_ptr);
1791 ir_ref_inst_gen(byte);
1792 ir_ref_inst_gen(count);
20611793
2062template<typename T>
2063static T *ir_build_inst_void(IrBuilderGen *irb, Scope *scope, AstNode *source_node) {
2064 T *special_instruction = ir_create_inst_noval<T>(irb, scope, source_node);
2065 special_instruction->base.value = irb->codegen->intern.for_void();
2066 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base);
2067 return special_instruction;
1794 return &instruction->base;
20681795}
20691796
2070IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,
2071 ZigType *var_type, const char *name_hint)
1797static IrInstGen *ir_build_memcpy_gen(IrAnalyze *ira, IrInst *source_instr,
1798 IrInstGen *dest_ptr, IrInstGen *src_ptr, IrInstGen *count)
20721799{
2073 IrInstGenAlloca *alloca_gen = heap::c_allocator.create<IrInstGenAlloca>();
2074 alloca_gen->base.id = IrInstGenIdAlloca;
2075 alloca_gen->base.base.source_node = source_node;
2076 alloca_gen->base.base.scope = scope;
2077 alloca_gen->base.value = g->pass1_arena->create<ZigValue>();
2078 alloca_gen->base.value->type = get_pointer_to_type(g, var_type, false);
2079 alloca_gen->base.base.ref_count = 1;
2080 alloca_gen->name_hint = name_hint;
2081 fn->alloca_gen_list.append(alloca_gen);
2082 return &alloca_gen->base;
1800 IrInstGenMemcpy *instruction = ir_build_inst_void<IrInstGenMemcpy>(&ira->new_irb,
1801 source_instr->scope, source_instr->source_node);
1802 instruction->dest_ptr = dest_ptr;
1803 instruction->src_ptr = src_ptr;
1804 instruction->count = count;
1805
1806 ir_ref_inst_gen(dest_ptr);
1807 ir_ref_inst_gen(src_ptr);
1808 ir_ref_inst_gen(count);
1809
1810 return &instruction->base;
20831811}
20841812
2085static IrInstGen *ir_build_cast(IrAnalyze *ira, IrInst *source_instr,ZigType *dest_type,
2086 IrInstGen *value, CastOp cast_op)
1813static IrInstGen *ir_build_slice_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *slice_type,
1814 IrInstGen *ptr, IrInstGen *start, IrInstGen *end, bool safety_check_on, IrInstGen *result_loc,
1815 ZigValue *sentinel)
20871816{
2088 IrInstGenCast *inst = ir_build_inst_gen<IrInstGenCast>(&ira->new_irb, source_instr->scope, source_instr->source_node);
2089 inst->base.value->type = dest_type;
2090 inst->value = value;
2091 inst->cast_op = cast_op;
1817 IrInstGenSlice *instruction = ir_build_inst_gen<IrInstGenSlice>(
1818 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1819 instruction->base.value->type = slice_type;
1820 instruction->ptr = ptr;
1821 instruction->start = start;
1822 instruction->end = end;
1823 instruction->safety_check_on = safety_check_on;
1824 instruction->result_loc = result_loc;
1825 instruction->sentinel = sentinel;
20921826
2093 ir_ref_inst_gen(value);
1827 ir_ref_inst_gen(ptr);
1828 ir_ref_inst_gen(start);
1829 if (end != nullptr) ir_ref_inst_gen(end);
1830 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
20941831
2095 return &inst->base;
1832 return &instruction->base;
20961833}
20971834
2098static IrInstSrc *ir_build_cond_br(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *condition,
2099 IrBasicBlockSrc *then_block, IrBasicBlockSrc *else_block, IrInstSrc *is_comptime)
2100{
2101 IrInstSrcCondBr *inst = ir_build_instruction<IrInstSrcCondBr>(irb, scope, source_node);
2102 inst->base.is_noreturn = true;
2103 inst->condition = condition;
2104 inst->then_block = then_block;
2105 inst->else_block = else_block;
2106 inst->is_comptime = is_comptime;
2107
2108 ir_ref_instruction(condition, irb->current_basic_block);
2109 ir_ref_bb(then_block);
2110 ir_ref_bb(else_block);
2111 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block);
1835static IrInstGen *ir_build_breakpoint_gen(IrAnalyze *ira, IrInst *source_instr) {
1836 IrInstGenBreakpoint *instruction = ir_build_inst_void<IrInstGenBreakpoint>(&ira->new_irb,
1837 source_instr->scope, source_instr->source_node);
1838 return &instruction->base;
1839}
21121840
1841static IrInstGen *ir_build_return_address_gen(IrAnalyze *ira, IrInst *source_instr) {
1842 IrInstGenReturnAddress *inst = ir_build_inst_gen<IrInstGenReturnAddress>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1843 inst->base.value->type = ira->codegen->builtin_types.entry_usize;
21131844 return &inst->base;
21141845}
21151846
2116static IrInstGen *ir_build_cond_br_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *condition,
2117 IrBasicBlockGen *then_block, IrBasicBlockGen *else_block)
2118{
2119 IrInstGenCondBr *inst = ir_build_inst_noreturn<IrInstGenCondBr>(&ira->new_irb, source_instr->scope, source_instr->source_node);
2120 inst->condition = condition;
2121 inst->then_block = then_block;
2122 inst->else_block = else_block;
2123
2124 ir_ref_inst_gen(condition);
1847static IrInstGen *ir_build_frame_address_gen(IrAnalyze *ira, IrInst *source_instr) {
1848 IrInstGenFrameAddress *inst = ir_build_inst_gen<IrInstGenFrameAddress>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1849 inst->base.value->type = ira->codegen->builtin_types.entry_usize;
1850 return &inst->base;
1851}
21251852
1853static IrInstGen *ir_build_handle_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *ty) {
1854 IrInstGenFrameHandle *inst = ir_build_inst_gen<IrInstGenFrameHandle>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1855 inst->base.value->type = ty;
21261856 return &inst->base;
21271857}
21281858
2129static IrInstSrc *ir_build_return_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *operand) {
2130 IrInstSrcReturn *inst = ir_build_instruction<IrInstSrcReturn>(irb, scope, source_node);
2131 inst->base.is_noreturn = true;
2132 inst->operand = operand;
1859static IrInstGen *ir_build_frame_size_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *fn)
1860{
1861 IrInstGenFrameSize *inst = ir_build_inst_gen<IrInstGenFrameSize>(&ira->new_irb, source_instr->scope, source_instr->source_node);
1862 inst->base.value->type = ira->codegen->builtin_types.entry_usize;
1863 inst->fn = fn;
21331864
2134 if (operand != nullptr) ir_ref_instruction(operand, irb->current_basic_block);
1865 ir_ref_inst_gen(fn);
21351866
21361867 return &inst->base;
21371868}
21381869
2139static IrInstGen *ir_build_return_gen(IrAnalyze *ira, IrInst *source_inst, IrInstGen *operand) {
2140 IrInstGenReturn *inst = ir_build_inst_noreturn<IrInstGenReturn>(&ira->new_irb,
2141 source_inst->scope, source_inst->source_node);
2142 inst->operand = operand;
2143
2144 if (operand != nullptr) ir_ref_inst_gen(operand);
2145
2146 return &inst->base;
2147}
2148
2149static IrInstSrc *ir_build_const_void(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
2150 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node);
2151 ir_instruction_append(irb->current_basic_block, &const_instruction->base);
2152 const_instruction->value = irb->codegen->intern.for_void();
2153 return &const_instruction->base;
2154}
2155
2156static IrInstSrc *ir_build_const_undefined(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
2157 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node);
2158 ir_instruction_append(irb->current_basic_block, &const_instruction->base);
2159 const_instruction->value = irb->codegen->intern.for_undefined();
2160 const_instruction->value->special = ConstValSpecialUndef;
2161 return &const_instruction->base;
2162}
2163
2164static IrInstSrc *ir_build_const_uint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, uint64_t value) {
2165 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
2166 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
2167 const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_int;
2168 const_instruction->value->special = ConstValSpecialStatic;
2169 bigint_init_unsigned(&const_instruction->value->data.x_bigint, value);
2170 return &const_instruction->base;
2171}
1870static IrInstGen *ir_build_overflow_op_gen(IrAnalyze *ira, IrInst *source_instr,
1871 IrOverflowOp op, IrInstGen *op1, IrInstGen *op2, IrInstGen *result_ptr,
1872 ZigType *result_ptr_type)
1873{
1874 IrInstGenOverflowOp *instruction = ir_build_inst_gen<IrInstGenOverflowOp>(&ira->new_irb,
1875 source_instr->scope, source_instr->source_node);
1876 instruction->base.value->type = ira->codegen->builtin_types.entry_bool;
1877 instruction->op = op;
1878 instruction->op1 = op1;
1879 instruction->op2 = op2;
1880 instruction->result_ptr = result_ptr;
1881 instruction->result_ptr_type = result_ptr_type;
21721882
2173static IrInstSrc *ir_build_const_bigint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigInt *bigint) {
2174 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
2175 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
2176 const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_int;
2177 const_instruction->value->special = ConstValSpecialStatic;
2178 bigint_init_bigint(&const_instruction->value->data.x_bigint, bigint);
2179 return &const_instruction->base;
2180}
1883 ir_ref_inst_gen(op1);
1884 ir_ref_inst_gen(op2);
1885 ir_ref_inst_gen(result_ptr);
21811886
2182static IrInstSrc *ir_build_const_bigfloat(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigFloat *bigfloat) {
2183 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
2184 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
2185 const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_float;
2186 const_instruction->value->special = ConstValSpecialStatic;
2187 bigfloat_init_bigfloat(&const_instruction->value->data.x_bigfloat, bigfloat);
2188 return &const_instruction->base;
1887 return &instruction->base;
21891888}
21901889
2191static IrInstSrc *ir_build_const_null(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
2192 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node);
2193 ir_instruction_append(irb->current_basic_block, &const_instruction->base);
2194 const_instruction->value = irb->codegen->intern.for_null();
2195 return &const_instruction->base;
2196}
1890static IrInstGen *ir_build_float_op_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand,
1891 BuiltinFnId fn_id, ZigType *operand_type)
1892{
1893 IrInstGenFloatOp *instruction = ir_build_inst_gen<IrInstGenFloatOp>(&ira->new_irb,
1894 source_instr->scope, source_instr->source_node);
1895 instruction->base.value->type = operand_type;
1896 instruction->operand = operand;
1897 instruction->fn_id = fn_id;
21971898
2198static IrInstSrc *ir_build_const_usize(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, uint64_t value) {
2199 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
2200 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
2201 const_instruction->value->type = irb->codegen->builtin_types.entry_usize;
2202 const_instruction->value->special = ConstValSpecialStatic;
2203 bigint_init_unsigned(&const_instruction->value->data.x_bigint, value);
2204 return &const_instruction->base;
2205}
1899 ir_ref_inst_gen(operand);
22061900
2207static IrInstSrc *ir_create_const_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2208 ZigType *type_entry)
2209{
2210 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node);
2211 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
2212 const_instruction->value->type = irb->codegen->builtin_types.entry_type;
2213 const_instruction->value->special = ConstValSpecialStatic;
2214 const_instruction->value->data.x_type = type_entry;
2215 return &const_instruction->base;
1901 return &instruction->base;
22161902}
22171903
2218static IrInstSrc *ir_build_const_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2219 ZigType *type_entry)
1904static IrInstGen *ir_build_mul_add_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *op1, IrInstGen *op2,
1905 IrInstGen *op3, ZigType *expr_type)
22201906{
2221 IrInstSrc *instruction = ir_create_const_type(irb, scope, source_node, type_entry);
2222 ir_instruction_append(irb->current_basic_block, instruction);
2223 return instruction;
2224}
2225
2226static IrInstSrc *ir_build_const_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigType *import) {
2227 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
2228 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
2229 const_instruction->value->type = irb->codegen->builtin_types.entry_type;
2230 const_instruction->value->special = ConstValSpecialStatic;
2231 const_instruction->value->data.x_type = import;
2232 return &const_instruction->base;
2233}
1907 IrInstGenMulAdd *instruction = ir_build_inst_gen<IrInstGenMulAdd>(&ira->new_irb,
1908 source_instr->scope, source_instr->source_node);
1909 instruction->base.value->type = expr_type;
1910 instruction->op1 = op1;
1911 instruction->op2 = op2;
1912 instruction->op3 = op3;
22341913
2235static IrInstSrc *ir_build_const_bool(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, bool value) {
2236 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
2237 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
2238 const_instruction->value->type = irb->codegen->builtin_types.entry_bool;
2239 const_instruction->value->special = ConstValSpecialStatic;
2240 const_instruction->value->data.x_bool = value;
2241 return &const_instruction->base;
2242}
1914 ir_ref_inst_gen(op1);
1915 ir_ref_inst_gen(op2);
1916 ir_ref_inst_gen(op3);
22431917
2244static IrInstSrc *ir_build_const_enum_literal(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *name) {
2245 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node);
2246 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
2247 const_instruction->value->type = irb->codegen->builtin_types.entry_enum_literal;
2248 const_instruction->value->special = ConstValSpecialStatic;
2249 const_instruction->value->data.x_enum_literal = name;
2250 return &const_instruction->base;
1918 return &instruction->base;
22511919}
22521920
2253static IrInstSrc *ir_create_const_str_lit(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *str) {
2254 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node);
2255 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
2256 init_const_str_lit(irb->codegen, const_instruction->value, str);
1921static IrInstGen *ir_build_test_err_gen(IrAnalyze *ira, IrInst *source_instruction, IrInstGen *err_union) {
1922 IrInstGenTestErr *instruction = ir_build_inst_gen<IrInstGenTestErr>(
1923 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1924 instruction->base.value->type = ira->codegen->builtin_types.entry_bool;
1925 instruction->err_union = err_union;
22571926
2258 return &const_instruction->base;
2259}
1927 ir_ref_inst_gen(err_union);
22601928
2261static IrInstSrc *ir_build_const_str_lit(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *str) {
2262 IrInstSrc *instruction = ir_create_const_str_lit(irb, scope, source_node, str);
2263 ir_instruction_append(irb->current_basic_block, instruction);
2264 return instruction;
1929 return &instruction->base;
22651930}
22661931
2267static IrInstSrc *ir_build_bin_op(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrBinOp op_id,
2268 IrInstSrc *op1, IrInstSrc *op2, bool safety_check_on)
1932static IrInstGen *ir_build_unwrap_err_code_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
1933 IrInstGen *err_union_ptr, ZigType *result_type)
22691934{
2270 IrInstSrcBinOp *inst = ir_build_instruction<IrInstSrcBinOp>(irb, scope, source_node);
2271 inst->op_id = op_id;
2272 inst->op1 = op1;
2273 inst->op2 = op2;
2274 inst->safety_check_on = safety_check_on;
1935 IrInstGenUnwrapErrCode *inst = ir_build_inst_gen<IrInstGenUnwrapErrCode>(&ira->new_irb, scope, source_node);
1936 inst->base.value->type = result_type;
1937 inst->err_union_ptr = err_union_ptr;
22751938
2276 ir_ref_instruction(op1, irb->current_basic_block);
2277 ir_ref_instruction(op2, irb->current_basic_block);
1939 ir_ref_inst_gen(err_union_ptr);
22781940
22791941 return &inst->base;
22801942}
22811943
2282static IrInstGen *ir_build_bin_op_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *res_type,
2283 IrBinOp op_id, IrInstGen *op1, IrInstGen *op2, bool safety_check_on)
1944static IrInstGen *ir_build_unwrap_err_payload_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
1945 IrInstGen *value, bool safety_check_on, bool initializing, ZigType *result_type)
22841946{
2285 IrInstGenBinOp *inst = ir_build_inst_gen<IrInstGenBinOp>(&ira->new_irb,
2286 source_instr->scope, source_instr->source_node);
2287 inst->base.value->type = res_type;
2288 inst->op_id = op_id;
2289 inst->op1 = op1;
2290 inst->op2 = op2;
1947 IrInstGenUnwrapErrPayload *inst = ir_build_inst_gen<IrInstGenUnwrapErrPayload>(&ira->new_irb, scope, source_node);
1948 inst->base.value->type = result_type;
1949 inst->value = value;
22911950 inst->safety_check_on = safety_check_on;
1951 inst->initializing = initializing;
22921952
2293 ir_ref_inst_gen(op1);
2294 ir_ref_inst_gen(op2);
1953 ir_ref_inst_gen(value);
22951954
22961955 return &inst->base;
22971956}
22981957
2299
2300static IrInstSrc *ir_build_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2301 IrInstSrc *op1, IrInstSrc *op2, Buf *type_name)
1958static IrInstGen *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInst *source_instruction,
1959 ZigType *ptr_type, IrInstGen *ptr, bool safety_check_on)
23021960{
2303 IrInstSrcMergeErrSets *inst = ir_build_instruction<IrInstSrcMergeErrSets>(irb, scope, source_node);
2304 inst->op1 = op1;
2305 inst->op2 = op2;
2306 inst->type_name = type_name;
1961 IrInstGenPtrCast *instruction = ir_build_inst_gen<IrInstGenPtrCast>(
1962 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1963 instruction->base.value->type = ptr_type;
1964 instruction->ptr = ptr;
1965 instruction->safety_check_on = safety_check_on;
23071966
2308 ir_ref_instruction(op1, irb->current_basic_block);
2309 ir_ref_instruction(op2, irb->current_basic_block);
1967 ir_ref_inst_gen(ptr);
23101968
2311 return &inst->base;
1969 return &instruction->base;
23121970}
23131971
2314static IrInstSrc *ir_build_var_ptr_x(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var,
2315 ScopeFnDef *crossed_fndef_scope)
1972static IrInstGen *ir_build_bit_cast_gen(IrAnalyze *ira, IrInst *source_instruction,
1973 IrInstGen *operand, ZigType *ty)
23161974{
2317 IrInstSrcVarPtr *instruction = ir_build_instruction<IrInstSrcVarPtr>(irb, scope, source_node);
2318 instruction->var = var;
2319 instruction->crossed_fndef_scope = crossed_fndef_scope;
1975 IrInstGenBitCast *instruction = ir_build_inst_gen<IrInstGenBitCast>(
1976 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
1977 instruction->base.value->type = ty;
1978 instruction->operand = operand;
23201979
2321 ir_ref_var(var);
1980 ir_ref_inst_gen(operand);
23221981
23231982 return &instruction->base;
23241983}
23251984
2326static IrInstSrc *ir_build_var_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var) {
2327 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr);
2328}
2329
2330static IrInstGen *ir_build_var_ptr_gen(IrAnalyze *ira, IrInst *source_instr, ZigVar *var) {
2331 IrInstGenVarPtr *instruction = ir_build_inst_gen<IrInstGenVarPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node);
2332 instruction->var = var;
1985static IrInstGen *ir_build_widen_or_shorten(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target,
1986 ZigType *result_type)
1987{
1988 IrInstGenWidenOrShorten *inst = ir_build_inst_gen<IrInstGenWidenOrShorten>(&ira->new_irb, scope, source_node);
1989 inst->base.value->type = result_type;
1990 inst->target = target;
23331991
2334 ir_ref_var(var);
1992 ir_ref_inst_gen(target);
23351993
2336 return &instruction->base;
1994 return &inst->base;
23371995}
23381996
2339static IrInstGen *ir_build_return_ptr(IrAnalyze *ira, Scope *scope, AstNode *source_node, ZigType *ty) {
2340 IrInstGenReturnPtr *instruction = ir_build_inst_gen<IrInstGenReturnPtr>(&ira->new_irb, scope, source_node);
2341 instruction->base.value->type = ty;
1997static IrInstGen *ir_build_int_to_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
1998 IrInstGen *target, ZigType *ptr_type)
1999{
2000 IrInstGenIntToPtr *instruction = ir_build_inst_gen<IrInstGenIntToPtr>(&ira->new_irb, scope, source_node);
2001 instruction->base.value->type = ptr_type;
2002 instruction->target = target;
2003
2004 ir_ref_inst_gen(target);
2005
23422006 return &instruction->base;
23432007}
23442008
2345static IrInstSrc *ir_build_elem_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2346 IrInstSrc *array_ptr, IrInstSrc *elem_index, bool safety_check_on, PtrLen ptr_len,
2347 AstNode *init_array_type_source_node)
2348{
2349 IrInstSrcElemPtr *instruction = ir_build_instruction<IrInstSrcElemPtr>(irb, scope, source_node);
2350 instruction->array_ptr = array_ptr;
2351 instruction->elem_index = elem_index;
2352 instruction->safety_check_on = safety_check_on;
2353 instruction->ptr_len = ptr_len;
2354 instruction->init_array_type_source_node = init_array_type_source_node;
2009static IrInstGen *ir_build_ptr_to_int_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target) {
2010 IrInstGenPtrToInt *inst = ir_build_inst_gen<IrInstGenPtrToInt>(&ira->new_irb, source_instr->scope, source_instr->source_node);
2011 inst->base.value->type = ira->codegen->builtin_types.entry_usize;
2012 inst->target = target;
23552013
2356 ir_ref_instruction(array_ptr, irb->current_basic_block);
2357 ir_ref_instruction(elem_index, irb->current_basic_block);
2014 ir_ref_inst_gen(target);
23582015
2359 return &instruction->base;
2016 return &inst->base;
23602017}
23612018
2362static IrInstGen *ir_build_elem_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
2363 IrInstGen *array_ptr, IrInstGen *elem_index, bool safety_check_on, ZigType *return_type)
2019static IrInstGen *ir_build_int_to_enum_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
2020 ZigType *dest_type, IrInstGen *target)
23642021{
2365 IrInstGenElemPtr *instruction = ir_build_inst_gen<IrInstGenElemPtr>(&ira->new_irb, scope, source_node);
2366 instruction->base.value->type = return_type;
2367 instruction->array_ptr = array_ptr;
2368 instruction->elem_index = elem_index;
2369 instruction->safety_check_on = safety_check_on;
2022 IrInstGenIntToEnum *instruction = ir_build_inst_gen<IrInstGenIntToEnum>(&ira->new_irb, scope, source_node);
2023 instruction->base.value->type = dest_type;
2024 instruction->target = target;
23702025
2371 ir_ref_inst_gen(array_ptr);
2372 ir_ref_inst_gen(elem_index);
2026 ir_ref_inst_gen(target);
23732027
23742028 return &instruction->base;
23752029}
23762030
2377static IrInstSrc *ir_build_field_ptr_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2378 IrInstSrc *container_ptr, IrInstSrc *field_name_expr, bool initializing)
2031static IrInstGen *ir_build_int_to_err_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target,
2032 ZigType *wanted_type)
23792033{
2380 IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(irb, scope, source_node);
2381 instruction->container_ptr = container_ptr;
2382 instruction->field_name_buffer = nullptr;
2383 instruction->field_name_expr = field_name_expr;
2384 instruction->initializing = initializing;
2034 IrInstGenIntToErr *instruction = ir_build_inst_gen<IrInstGenIntToErr>(&ira->new_irb, scope, source_node);
2035 instruction->base.value->type = wanted_type;
2036 instruction->target = target;
23852037
2386 ir_ref_instruction(container_ptr, irb->current_basic_block);
2387 ir_ref_instruction(field_name_expr, irb->current_basic_block);
2038 ir_ref_inst_gen(target);
23882039
23892040 return &instruction->base;
23902041}
23912042
2392static IrInstSrc *ir_build_field_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2393 IrInstSrc *container_ptr, Buf *field_name, bool initializing)
2043static IrInstGen *ir_build_err_to_int_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target,
2044 ZigType *wanted_type)
23942045{
2395 IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(irb, scope, source_node);
2396 instruction->container_ptr = container_ptr;
2397 instruction->field_name_buffer = field_name;
2398 instruction->field_name_expr = nullptr;
2399 instruction->initializing = initializing;
2046 IrInstGenErrToInt *instruction = ir_build_inst_gen<IrInstGenErrToInt>(&ira->new_irb, scope, source_node);
2047 instruction->base.value->type = wanted_type;
2048 instruction->target = target;
24002049
2401 ir_ref_instruction(container_ptr, irb->current_basic_block);
2050 ir_ref_inst_gen(target);
24022051
24032052 return &instruction->base;
24042053}
24052054
2406static IrInstSrc *ir_build_has_field(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2407 IrInstSrc *container_type, IrInstSrc *field_name)
2408{
2409 IrInstSrcHasField *instruction = ir_build_instruction<IrInstSrcHasField>(irb, scope, source_node);
2410 instruction->container_type = container_type;
2411 instruction->field_name = field_name;
2055static IrInstGen *ir_build_panic_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *msg) {
2056 IrInstGenPanic *instruction = ir_build_inst_noreturn<IrInstGenPanic>(&ira->new_irb,
2057 source_instr->scope, source_instr->source_node);
2058 instruction->msg = msg;
24122059
2413 ir_ref_instruction(container_type, irb->current_basic_block);
2414 ir_ref_instruction(field_name, irb->current_basic_block);
2060 ir_ref_inst_gen(msg);
24152061
24162062 return &instruction->base;
24172063}
24182064
2419static IrInstGen *ir_build_struct_field_ptr(IrAnalyze *ira, IrInst *source_instr,
2420 IrInstGen *struct_ptr, TypeStructField *field, ZigType *ptr_type)
2065static IrInstGen *ir_build_tag_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target,
2066 ZigType *result_type)
24212067{
2422 IrInstGenStructFieldPtr *inst = ir_build_inst_gen<IrInstGenStructFieldPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node);
2423 inst->base.value->type = ptr_type;
2424 inst->struct_ptr = struct_ptr;
2425 inst->field = field;
2068 IrInstGenTagName *instruction = ir_build_inst_gen<IrInstGenTagName>(&ira->new_irb,
2069 source_instr->scope, source_instr->source_node);
2070 instruction->base.value->type = result_type;
2071 instruction->target = target;
24262072
2427 ir_ref_inst_gen(struct_ptr);
2073 ir_ref_inst_gen(target);
24282074
2429 return &inst->base;
2075 return &instruction->base;
24302076}
24312077
2432static IrInstGen *ir_build_union_field_ptr(IrAnalyze *ira, IrInst *source_instr,
2433 IrInstGen *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing, ZigType *ptr_type)
2078static IrInstGen *ir_build_field_parent_ptr_gen(IrAnalyze *ira, IrInst *source_instr,
2079 IrInstGen *field_ptr, TypeStructField *field, ZigType *result_type)
24342080{
2435 IrInstGenUnionFieldPtr *inst = ir_build_inst_gen<IrInstGenUnionFieldPtr>(&ira->new_irb,
2081 IrInstGenFieldParentPtr *inst = ir_build_inst_gen<IrInstGenFieldParentPtr>(&ira->new_irb,
24362082 source_instr->scope, source_instr->source_node);
2437 inst->base.value->type = ptr_type;
2438 inst->initializing = initializing;
2439 inst->safety_check_on = safety_check_on;
2440 inst->union_ptr = union_ptr;
2083 inst->base.value->type = result_type;
2084 inst->field_ptr = field_ptr;
24412085 inst->field = field;
24422086
2443 ir_ref_inst_gen(union_ptr);
2087 ir_ref_inst_gen(field_ptr);
24442088
24452089 return &inst->base;
24462090}
24472091
2448static IrInstSrc *ir_build_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2449 IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc *args, ResultLoc *result_loc)
2092static IrInstGen *ir_build_align_cast_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target,
2093 ZigType *result_type)
24502094{
2451 IrInstSrcCallExtra *call_instruction = ir_build_instruction<IrInstSrcCallExtra>(irb, scope, source_node);
2452 call_instruction->options = options;
2453 call_instruction->fn_ref = fn_ref;
2454 call_instruction->args = args;
2455 call_instruction->result_loc = result_loc;
2095 IrInstGenAlignCast *instruction = ir_build_inst_gen<IrInstGenAlignCast>(&ira->new_irb, scope, source_node);
2096 instruction->base.value->type = result_type;
2097 instruction->target = target;
24562098
2457 ir_ref_instruction(options, irb->current_basic_block);
2458 ir_ref_instruction(fn_ref, irb->current_basic_block);
2459 ir_ref_instruction(args, irb->current_basic_block);
2099 ir_ref_inst_gen(target);
24602100
2461 return &call_instruction->base;
2101 return &instruction->base;
24622102}
24632103
2464static IrInstSrc *ir_build_async_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2465 CallModifier modifier, IrInstSrc *fn_ref, IrInstSrc *ret_ptr, IrInstSrc *new_stack, IrInstSrc *args, ResultLoc *result_loc)
2104static IrInstGen *ir_build_error_return_trace_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
2105 IrInstErrorReturnTraceOptional optional, ZigType *result_type)
24662106{
2467 IrInstSrcAsyncCallExtra *call_instruction = ir_build_instruction<IrInstSrcAsyncCallExtra>(irb, scope, source_node);
2468 call_instruction->modifier = modifier;
2469 call_instruction->fn_ref = fn_ref;
2470 call_instruction->ret_ptr = ret_ptr;
2471 call_instruction->new_stack = new_stack;
2472 call_instruction->args = args;
2473 call_instruction->result_loc = result_loc;
2474
2475 ir_ref_instruction(fn_ref, irb->current_basic_block);
2476 if (ret_ptr != nullptr) ir_ref_instruction(ret_ptr, irb->current_basic_block);
2477 ir_ref_instruction(new_stack, irb->current_basic_block);
2478 ir_ref_instruction(args, irb->current_basic_block);
2107 IrInstGenErrorReturnTrace *inst = ir_build_inst_gen<IrInstGenErrorReturnTrace>(&ira->new_irb, scope, source_node);
2108 inst->base.value->type = result_type;
2109 inst->optional = optional;
24792110
2480 return &call_instruction->base;
2111 return &inst->base;
24812112}
24822113
2483static IrInstSrc *ir_build_call_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2484 IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc **args_ptr, size_t args_len,
2485 ResultLoc *result_loc)
2114static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr,
2115 IrInstGen *ptr, IrInstGen *operand, AtomicRmwOp op, AtomicOrder ordering, ZigType *operand_type)
24862116{
2487 IrInstSrcCallArgs *call_instruction = ir_build_instruction<IrInstSrcCallArgs>(irb, scope, source_node);
2488 call_instruction->options = options;
2489 call_instruction->fn_ref = fn_ref;
2490 call_instruction->args_ptr = args_ptr;
2491 call_instruction->args_len = args_len;
2492 call_instruction->result_loc = result_loc;
2493
2494 ir_ref_instruction(options, irb->current_basic_block);
2495 ir_ref_instruction(fn_ref, irb->current_basic_block);
2496 for (size_t i = 0; i < args_len; i += 1)
2497 ir_ref_instruction(args_ptr[i], irb->current_basic_block);
2498
2499 return &call_instruction->base;
2500}
2501
2502static IrInstSrc *ir_build_call_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2503 ZigFn *fn_entry, IrInstSrc *fn_ref, size_t arg_count, IrInstSrc **args,
2504 IrInstSrc *ret_ptr, CallModifier modifier, bool is_async_call_builtin,
2505 IrInstSrc *new_stack, ResultLoc *result_loc)
2506{
2507 IrInstSrcCall *call_instruction = ir_build_instruction<IrInstSrcCall>(irb, scope, source_node);
2508 call_instruction->fn_entry = fn_entry;
2509 call_instruction->fn_ref = fn_ref;
2510 call_instruction->args = args;
2511 call_instruction->arg_count = arg_count;
2512 call_instruction->modifier = modifier;
2513 call_instruction->is_async_call_builtin = is_async_call_builtin;
2514 call_instruction->new_stack = new_stack;
2515 call_instruction->result_loc = result_loc;
2516 call_instruction->ret_ptr = ret_ptr;
2517
2518 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block);
2519 for (size_t i = 0; i < arg_count; i += 1)
2520 ir_ref_instruction(args[i], irb->current_basic_block);
2521 if (ret_ptr != nullptr) ir_ref_instruction(ret_ptr, irb->current_basic_block);
2522 if (new_stack != nullptr) ir_ref_instruction(new_stack, irb->current_basic_block);
2523
2524 return &call_instruction->base;
2525}
2526
2527static IrInstGenCall *ir_build_call_gen(IrAnalyze *ira, IrInst *source_instruction,
2528 ZigFn *fn_entry, IrInstGen *fn_ref, size_t arg_count, IrInstGen **args,
2529 CallModifier modifier, IrInstGen *new_stack, bool is_async_call_builtin,
2530 IrInstGen *result_loc, ZigType *return_type)
2531{
2532 IrInstGenCall *call_instruction = ir_build_inst_gen<IrInstGenCall>(&ira->new_irb,
2533 source_instruction->scope, source_instruction->source_node);
2534 call_instruction->base.value->type = return_type;
2535 call_instruction->fn_entry = fn_entry;
2536 call_instruction->fn_ref = fn_ref;
2537 call_instruction->args = args;
2538 call_instruction->arg_count = arg_count;
2539 call_instruction->modifier = modifier;
2540 call_instruction->is_async_call_builtin = is_async_call_builtin;
2541 call_instruction->new_stack = new_stack;
2542 call_instruction->result_loc = result_loc;
2543
2544 if (fn_ref != nullptr) ir_ref_inst_gen(fn_ref);
2545 for (size_t i = 0; i < arg_count; i += 1)
2546 ir_ref_inst_gen(args[i]);
2547 if (new_stack != nullptr) ir_ref_inst_gen(new_stack);
2548 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
2549
2550 return call_instruction;
2551}
2552
2553static IrInstSrc *ir_build_phi(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2554 size_t incoming_count, IrBasicBlockSrc **incoming_blocks, IrInstSrc **incoming_values,
2555 ResultLocPeerParent *peer_parent)
2556{
2557 assert(incoming_count != 0);
2558 assert(incoming_count != SIZE_MAX);
2559
2560 IrInstSrcPhi *phi_instruction = ir_build_instruction<IrInstSrcPhi>(irb, scope, source_node);
2561 phi_instruction->incoming_count = incoming_count;
2562 phi_instruction->incoming_blocks = incoming_blocks;
2563 phi_instruction->incoming_values = incoming_values;
2564 phi_instruction->peer_parent = peer_parent;
2565
2566 for (size_t i = 0; i < incoming_count; i += 1) {
2567 ir_ref_bb(incoming_blocks[i]);
2568 ir_ref_instruction(incoming_values[i], irb->current_basic_block);
2569 }
2570
2571 return &phi_instruction->base;
2572}
2573
2574static IrInstGen *ir_build_phi_gen(IrAnalyze *ira, IrInst *source_instr, size_t incoming_count,
2575 IrBasicBlockGen **incoming_blocks, IrInstGen **incoming_values, ZigType *result_type)
2576{
2577 assert(incoming_count != 0);
2578 assert(incoming_count != SIZE_MAX);
2579
2580 IrInstGenPhi *phi_instruction = ir_build_inst_gen<IrInstGenPhi>(&ira->new_irb,
2581 source_instr->scope, source_instr->source_node);
2582 phi_instruction->base.value->type = result_type;
2583 phi_instruction->incoming_count = incoming_count;
2584 phi_instruction->incoming_blocks = incoming_blocks;
2585 phi_instruction->incoming_values = incoming_values;
2586
2587 for (size_t i = 0; i < incoming_count; i += 1) {
2588 ir_ref_inst_gen(incoming_values[i]);
2589 }
2590
2591 return &phi_instruction->base;
2592}
2593
2594static IrInstSrc *ir_build_br(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2595 IrBasicBlockSrc *dest_block, IrInstSrc *is_comptime)
2596{
2597 IrInstSrcBr *inst = ir_build_instruction<IrInstSrcBr>(irb, scope, source_node);
2598 inst->base.is_noreturn = true;
2599 inst->dest_block = dest_block;
2600 inst->is_comptime = is_comptime;
2601
2602 ir_ref_bb(dest_block);
2603 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block);
2604
2605 return &inst->base;
2606}
2607
2608static IrInstGen *ir_build_br_gen(IrAnalyze *ira, IrInst *source_instr, IrBasicBlockGen *dest_block) {
2609 IrInstGenBr *inst = ir_build_inst_noreturn<IrInstGenBr>(&ira->new_irb, source_instr->scope, source_instr->source_node);
2610 inst->dest_block = dest_block;
2611
2612 return &inst->base;
2613}
2614
2615static IrInstSrc *ir_build_ptr_type_simple(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2616 IrInstSrc *child_type, bool is_const)
2617{
2618 IrInstSrcPtrTypeSimple *inst = heap::c_allocator.create<IrInstSrcPtrTypeSimple>();
2619 inst->base.id = is_const ? IrInstSrcIdPtrTypeSimpleConst : IrInstSrcIdPtrTypeSimple;
2620 inst->base.base.scope = scope;
2621 inst->base.base.source_node = source_node;
2622 inst->base.base.debug_id = exec_next_debug_id(irb->exec);
2623 inst->base.owner_bb = irb->current_basic_block;
2624 ir_instruction_append(irb->current_basic_block, &inst->base);
2625
2626 inst->child_type = child_type;
2627
2628 ir_ref_instruction(child_type, irb->current_basic_block);
2629
2630 return &inst->base;
2631}
2632
2633static IrInstSrc *ir_build_ptr_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2634 IrInstSrc *child_type, bool is_const, bool is_volatile, PtrLen ptr_len,
2635 IrInstSrc *sentinel, IrInstSrc *align_value,
2636 uint32_t bit_offset_start, uint32_t host_int_bytes, bool is_allow_zero)
2637{
2638 if (!is_volatile && ptr_len == PtrLenSingle && sentinel == nullptr && align_value == nullptr &&
2639 bit_offset_start == 0 && host_int_bytes == 0 && is_allow_zero == 0)
2640 {
2641 return ir_build_ptr_type_simple(irb, scope, source_node, child_type, is_const);
2642 }
2643
2644 IrInstSrcPtrType *inst = ir_build_instruction<IrInstSrcPtrType>(irb, scope, source_node);
2645 inst->sentinel = sentinel;
2646 inst->align_value = align_value;
2647 inst->child_type = child_type;
2648 inst->is_const = is_const;
2649 inst->is_volatile = is_volatile;
2650 inst->ptr_len = ptr_len;
2651 inst->bit_offset_start = bit_offset_start;
2652 inst->host_int_bytes = host_int_bytes;
2653 inst->is_allow_zero = is_allow_zero;
2654
2655 if (sentinel) ir_ref_instruction(sentinel, irb->current_basic_block);
2656 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block);
2657 ir_ref_instruction(child_type, irb->current_basic_block);
2658
2659 return &inst->base;
2660}
2661
2662static IrInstSrc *ir_build_un_op_lval(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrUnOp op_id,
2663 IrInstSrc *value, LVal lval, ResultLoc *result_loc)
2664{
2665 IrInstSrcUnOp *instruction = ir_build_instruction<IrInstSrcUnOp>(irb, scope, source_node);
2666 instruction->op_id = op_id;
2667 instruction->value = value;
2668 instruction->lval = lval;
2669 instruction->result_loc = result_loc;
2670
2671 ir_ref_instruction(value, irb->current_basic_block);
2672
2673 return &instruction->base;
2674}
2675
2676static IrInstSrc *ir_build_un_op(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrUnOp op_id,
2677 IrInstSrc *value)
2678{
2679 return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr);
2680}
2681
2682static IrInstGen *ir_build_negation(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, ZigType *expr_type, bool wrapping) {
2683 IrInstGenNegation *instruction = ir_build_inst_gen<IrInstGenNegation>(&ira->new_irb,
2684 source_instr->scope, source_instr->source_node);
2685 instruction->base.value->type = expr_type;
2686 instruction->operand = operand;
2687 instruction->wrapping = wrapping;
2688
2689 ir_ref_inst_gen(operand);
2690
2691 return &instruction->base;
2692}
2693
2694static IrInstGen *ir_build_binary_not(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand,
2695 ZigType *expr_type)
2696{
2697 IrInstGenBinaryNot *instruction = ir_build_inst_gen<IrInstGenBinaryNot>(&ira->new_irb,
2698 source_instr->scope, source_instr->source_node);
2699 instruction->base.value->type = expr_type;
2700 instruction->operand = operand;
2701
2702 ir_ref_inst_gen(operand);
2703
2704 return &instruction->base;
2705}
2706
2707static IrInstSrc *ir_build_container_init_list(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2708 size_t item_count, IrInstSrc **elem_result_loc_list, IrInstSrc *result_loc,
2709 AstNode *init_array_type_source_node)
2710{
2711 IrInstSrcContainerInitList *container_init_list_instruction =
2712 ir_build_instruction<IrInstSrcContainerInitList>(irb, scope, source_node);
2713 container_init_list_instruction->item_count = item_count;
2714 container_init_list_instruction->elem_result_loc_list = elem_result_loc_list;
2715 container_init_list_instruction->result_loc = result_loc;
2716 container_init_list_instruction->init_array_type_source_node = init_array_type_source_node;
2717
2718 for (size_t i = 0; i < item_count; i += 1) {
2719 ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block);
2720 }
2721 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block);
2722
2723 return &container_init_list_instruction->base;
2724}
2725
2726static IrInstSrc *ir_build_container_init_fields(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2727 size_t field_count, IrInstSrcContainerInitFieldsField *fields, IrInstSrc *result_loc)
2728{
2729 IrInstSrcContainerInitFields *container_init_fields_instruction =
2730 ir_build_instruction<IrInstSrcContainerInitFields>(irb, scope, source_node);
2731 container_init_fields_instruction->field_count = field_count;
2732 container_init_fields_instruction->fields = fields;
2733 container_init_fields_instruction->result_loc = result_loc;
2734
2735 for (size_t i = 0; i < field_count; i += 1) {
2736 ir_ref_instruction(fields[i].result_loc, irb->current_basic_block);
2737 }
2738 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block);
2739
2740 return &container_init_fields_instruction->base;
2741}
2742
2743static IrInstSrc *ir_build_unreachable(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
2744 IrInstSrcUnreachable *inst = ir_build_instruction<IrInstSrcUnreachable>(irb, scope, source_node);
2745 inst->base.is_noreturn = true;
2746 return &inst->base;
2747}
2748
2749static IrInstGen *ir_build_unreachable_gen(IrAnalyze *ira, IrInst *source_instr) {
2750 IrInstGenUnreachable *inst = ir_build_inst_noreturn<IrInstGenUnreachable>(&ira->new_irb, source_instr->scope, source_instr->source_node);
2751 return &inst->base;
2752}
2753
2754static IrInstSrcStorePtr *ir_build_store_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2755 IrInstSrc *ptr, IrInstSrc *value)
2756{
2757 IrInstSrcStorePtr *instruction = ir_build_instruction<IrInstSrcStorePtr>(irb, scope, source_node);
2758 instruction->ptr = ptr;
2759 instruction->value = value;
2760
2761 ir_ref_instruction(ptr, irb->current_basic_block);
2762 ir_ref_instruction(value, irb->current_basic_block);
2763
2764 return instruction;
2765}
2766
2767static IrInstGen *ir_build_store_ptr_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *ptr, IrInstGen *value) {
2768 IrInstGenStorePtr *instruction = ir_build_inst_void<IrInstGenStorePtr>(&ira->new_irb,
2769 source_instr->scope, source_instr->source_node);
2117 IrInstGenAtomicRmw *instruction = ir_build_inst_gen<IrInstGenAtomicRmw>(&ira->new_irb, source_instr->scope, source_instr->source_node);
2118 instruction->base.value->type = operand_type;
27702119 instruction->ptr = ptr;
2771 instruction->value = value;
2120 instruction->op = op;
2121 instruction->operand = operand;
2122 instruction->ordering = ordering;
27722123
27732124 ir_ref_inst_gen(ptr);
2774 ir_ref_inst_gen(value);
2125 ir_ref_inst_gen(operand);
27752126
27762127 return &instruction->base;
27772128}
27782129
2779static IrInstGen *ir_build_vector_store_elem(IrAnalyze *ira, IrInst *src_inst,
2780 IrInstGen *vector_ptr, IrInstGen *index, IrInstGen *value)
2781{
2782 IrInstGenVectorStoreElem *inst = ir_build_inst_void<IrInstGenVectorStoreElem>(
2783 &ira->new_irb, src_inst->scope, src_inst->source_node);
2784 inst->vector_ptr = vector_ptr;
2785 inst->index = index;
2786 inst->value = value;
2787
2788 ir_ref_inst_gen(vector_ptr);
2789 ir_ref_inst_gen(index);
2790 ir_ref_inst_gen(value);
2791
2792 return &inst->base;
2793}
2794
2795static IrInstSrc *ir_build_var_decl_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2796 ZigVar *var, IrInstSrc *align_value, IrInstSrc *ptr)
2797{
2798 IrInstSrcDeclVar *inst = ir_build_instruction<IrInstSrcDeclVar>(irb, scope, source_node);
2799 inst->var = var;
2800 inst->align_value = align_value;
2801 inst->ptr = ptr;
2802
2803 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);
2804 ir_ref_instruction(ptr, irb->current_basic_block);
2805
2806 return &inst->base;
2807}
2808
2809static IrInstGen *ir_build_var_decl_gen(IrAnalyze *ira, IrInst *source_instruction,
2810 ZigVar *var, IrInstGen *var_ptr)
2811{
2812 IrInstGenDeclVar *inst = ir_build_inst_gen<IrInstGenDeclVar>(&ira->new_irb,
2813 source_instruction->scope, source_instruction->source_node);
2814 inst->base.value->special = ConstValSpecialStatic;
2815 inst->base.value->type = ira->codegen->builtin_types.entry_void;
2816 inst->var = var;
2817 inst->var_ptr = var_ptr;
2818
2819 ir_ref_inst_gen(var_ptr);
2820
2821 return &inst->base;
2822}
2823
2824static IrInstSrc *ir_build_export(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2825 IrInstSrc *target, IrInstSrc *options)
2826{
2827 IrInstSrcExport *export_instruction = ir_build_instruction<IrInstSrcExport>(
2828 irb, scope, source_node);
2829 export_instruction->target = target;
2830 export_instruction->options = options;
2831
2832 ir_ref_instruction(target, irb->current_basic_block);
2833 ir_ref_instruction(options, irb->current_basic_block);
2834
2835 return &export_instruction->base;
2836}
2837
2838static IrInstSrc *ir_build_extern(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2839 IrInstSrc *type, IrInstSrc *options)
2840{
2841 IrInstSrcExtern *extern_instruction = ir_build_instruction<IrInstSrcExtern>(
2842 irb, scope, source_node);
2843 extern_instruction->type = type;
2844 extern_instruction->options = options;
2845
2846 ir_ref_instruction(type, irb->current_basic_block);
2847 ir_ref_instruction(options, irb->current_basic_block);
2848
2849 return &extern_instruction->base;
2850}
2851
2852static IrInstGen *ir_build_extern_gen(IrAnalyze *ira, IrInst *source_instr, Buf *name,
2853 GlobalLinkageId linkage, bool is_thread_local, ZigType *expr_type)
2130static IrInstGen *ir_build_atomic_load_gen(IrAnalyze *ira, IrInst *source_instr,
2131 IrInstGen *ptr, AtomicOrder ordering, ZigType *operand_type)
28542132{
2855 IrInstGenExtern *instruction = ir_build_inst_gen<IrInstGenExtern>(&ira->new_irb,
2133 IrInstGenAtomicLoad *instruction = ir_build_inst_gen<IrInstGenAtomicLoad>(&ira->new_irb,
28562134 source_instr->scope, source_instr->source_node);
2857 instruction->base.value->type = expr_type;
2858 instruction->name = name;
2859 instruction->linkage = linkage;
2860 instruction->is_thread_local = is_thread_local;
2861
2862 return &instruction->base;
2863}
2864
2865static IrInstSrc *ir_build_load_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *ptr) {
2866 IrInstSrcLoadPtr *instruction = ir_build_instruction<IrInstSrcLoadPtr>(irb, scope, source_node);
2867 instruction->ptr = ptr;
2868
2869 ir_ref_instruction(ptr, irb->current_basic_block);
2870
2871 return &instruction->base;
2872}
2873
2874static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instruction,
2875 IrInstGen *ptr, ZigType *ty, IrInstGen *result_loc)
2876{
2877 IrInstGenLoadPtr *instruction = ir_build_inst_gen<IrInstGenLoadPtr>(
2878 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
2879 instruction->base.value->type = ty;
2135 instruction->base.value->type = operand_type;
28802136 instruction->ptr = ptr;
2881 instruction->result_loc = result_loc;
2882
2883 ir_ref_inst_gen(ptr);
2884 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
2885
2886 return &instruction->base;
2887}
2888
2889static IrInstSrc *ir_build_typeof_n(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2890 IrInstSrc **values, size_t value_count)
2891{
2892 assert(value_count >= 2);
2893
2894 IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node);
2895 instruction->value.list = values;
2896 instruction->value_count = value_count;
2897
2898 for (size_t i = 0; i < value_count; i++)
2899 ir_ref_instruction(values[i], irb->current_basic_block);
2900
2901 return &instruction->base;
2902}
2903
2904static IrInstSrc *ir_build_typeof_1(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) {
2905 IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node);
2906 instruction->value.scalar = value;
2907
2908 ir_ref_instruction(value, irb->current_basic_block);
2909
2910 return &instruction->base;
2911}
2912
2913static IrInstSrc *ir_build_set_cold(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_cold) {
2914 IrInstSrcSetCold *instruction = ir_build_instruction<IrInstSrcSetCold>(irb, scope, source_node);
2915 instruction->is_cold = is_cold;
2916
2917 ir_ref_instruction(is_cold, irb->current_basic_block);
2918
2919 return &instruction->base;
2920}
2921
2922static IrInstSrc *ir_build_set_runtime_safety(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2923 IrInstSrc *safety_on)
2924{
2925 IrInstSrcSetRuntimeSafety *inst = ir_build_instruction<IrInstSrcSetRuntimeSafety>(irb, scope, source_node);
2926 inst->safety_on = safety_on;
2927
2928 ir_ref_instruction(safety_on, irb->current_basic_block);
2929
2930 return &inst->base;
2931}
2932
2933static IrInstSrc *ir_build_set_float_mode(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2934 IrInstSrc *mode_value)
2935{
2936 IrInstSrcSetFloatMode *instruction = ir_build_instruction<IrInstSrcSetFloatMode>(irb, scope, source_node);
2937 instruction->mode_value = mode_value;
2938
2939 ir_ref_instruction(mode_value, irb->current_basic_block);
2940
2941 return &instruction->base;
2942}
2943
2944static IrInstSrc *ir_build_array_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *size,
2945 IrInstSrc *sentinel, IrInstSrc *child_type)
2946{
2947 IrInstSrcArrayType *instruction = ir_build_instruction<IrInstSrcArrayType>(irb, scope, source_node);
2948 instruction->size = size;
2949 instruction->sentinel = sentinel;
2950 instruction->child_type = child_type;
2951
2952 ir_ref_instruction(size, irb->current_basic_block);
2953 if (sentinel != nullptr) ir_ref_instruction(sentinel, irb->current_basic_block);
2954 ir_ref_instruction(child_type, irb->current_basic_block);
2955
2956 return &instruction->base;
2957}
2958
2959static IrInstSrc *ir_build_anyframe_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2960 IrInstSrc *payload_type)
2961{
2962 IrInstSrcAnyFrameType *instruction = ir_build_instruction<IrInstSrcAnyFrameType>(irb, scope, source_node);
2963 instruction->payload_type = payload_type;
2964
2965 if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block);
2966
2967 return &instruction->base;
2968}
2969
2970static IrInstSrc *ir_build_slice_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2971 IrInstSrc *child_type, bool is_const, bool is_volatile,
2972 IrInstSrc *sentinel, IrInstSrc *align_value, bool is_allow_zero)
2973{
2974 IrInstSrcSliceType *instruction = ir_build_instruction<IrInstSrcSliceType>(irb, scope, source_node);
2975 instruction->is_const = is_const;
2976 instruction->is_volatile = is_volatile;
2977 instruction->child_type = child_type;
2978 instruction->sentinel = sentinel;
2979 instruction->align_value = align_value;
2980 instruction->is_allow_zero = is_allow_zero;
2981
2982 if (sentinel != nullptr) ir_ref_instruction(sentinel, irb->current_basic_block);
2983 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);
2984 ir_ref_instruction(child_type, irb->current_basic_block);
2985
2986 return &instruction->base;
2987}
2988
2989static IrInstSrc *ir_build_asm_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2990 IrInstSrc *asm_template, IrInstSrc **input_list, IrInstSrc **output_types,
2991 ZigVar **output_vars, size_t return_count, bool has_side_effects, bool is_global)
2992{
2993 IrInstSrcAsm *instruction = ir_build_instruction<IrInstSrcAsm>(irb, scope, source_node);
2994 instruction->asm_template = asm_template;
2995 instruction->input_list = input_list;
2996 instruction->output_types = output_types;
2997 instruction->output_vars = output_vars;
2998 instruction->return_count = return_count;
2999 instruction->has_side_effects = has_side_effects;
3000 instruction->is_global = is_global;
3001
3002 assert(source_node->type == NodeTypeAsmExpr);
3003 for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) {
3004 IrInstSrc *output_type = output_types[i];
3005 if (output_type) ir_ref_instruction(output_type, irb->current_basic_block);
3006 }
3007
3008 for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) {
3009 IrInstSrc *input_value = input_list[i];
3010 ir_ref_instruction(input_value, irb->current_basic_block);
3011 }
3012
3013 return &instruction->base;
3014}
3015
3016static IrInstGen *ir_build_asm_gen(IrAnalyze *ira, IrInst *source_instr,
3017 Buf *asm_template, AsmToken *token_list, size_t token_list_len,
3018 IrInstGen **input_list, IrInstGen **output_types, ZigVar **output_vars, size_t return_count,
3019 bool has_side_effects, ZigType *return_type)
3020{
3021 IrInstGenAsm *instruction = ir_build_inst_gen<IrInstGenAsm>(&ira->new_irb, source_instr->scope, source_instr->source_node);
3022 instruction->base.value->type = return_type;
3023 instruction->asm_template = asm_template;
3024 instruction->token_list = token_list;
3025 instruction->token_list_len = token_list_len;
3026 instruction->input_list = input_list;
3027 instruction->output_types = output_types;
3028 instruction->output_vars = output_vars;
3029 instruction->return_count = return_count;
3030 instruction->has_side_effects = has_side_effects;
3031
3032 assert(source_instr->source_node->type == NodeTypeAsmExpr);
3033 for (size_t i = 0; i < source_instr->source_node->data.asm_expr.output_list.length; i += 1) {
3034 IrInstGen *output_type = output_types[i];
3035 if (output_type) ir_ref_inst_gen(output_type);
3036 }
3037
3038 for (size_t i = 0; i < source_instr->source_node->data.asm_expr.input_list.length; i += 1) {
3039 IrInstGen *input_value = input_list[i];
3040 ir_ref_inst_gen(input_value);
3041 }
3042
3043 return &instruction->base;
3044}
3045
3046static IrInstSrc *ir_build_size_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value,
3047 bool bit_size)
3048{
3049 IrInstSrcSizeOf *instruction = ir_build_instruction<IrInstSrcSizeOf>(irb, scope, source_node);
3050 instruction->type_value = type_value;
3051 instruction->bit_size = bit_size;
3052
3053 ir_ref_instruction(type_value, irb->current_basic_block);
3054
3055 return &instruction->base;
3056}
3057
3058static IrInstSrc *ir_build_test_non_null_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3059 IrInstSrc *value)
3060{
3061 IrInstSrcTestNonNull *instruction = ir_build_instruction<IrInstSrcTestNonNull>(irb, scope, source_node);
3062 instruction->value = value;
3063
3064 ir_ref_instruction(value, irb->current_basic_block);
3065
3066 return &instruction->base;
3067}
3068
3069static IrInstGen *ir_build_test_non_null_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) {
3070 IrInstGenTestNonNull *inst = ir_build_inst_gen<IrInstGenTestNonNull>(&ira->new_irb,
3071 source_instr->scope, source_instr->source_node);
3072 inst->base.value->type = ira->codegen->builtin_types.entry_bool;
3073 inst->value = value;
3074
3075 ir_ref_inst_gen(value);
3076
3077 return &inst->base;
3078}
3079
3080static IrInstSrc *ir_build_optional_unwrap_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3081 IrInstSrc *base_ptr, bool safety_check_on)
3082{
3083 IrInstSrcOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstSrcOptionalUnwrapPtr>(irb, scope, source_node);
3084 instruction->base_ptr = base_ptr;
3085 instruction->safety_check_on = safety_check_on;
3086
3087 ir_ref_instruction(base_ptr, irb->current_basic_block);
3088
3089 return &instruction->base;
3090}
3091
3092static IrInstGen *ir_build_optional_unwrap_ptr_gen(IrAnalyze *ira, IrInst *source_instr,
3093 IrInstGen *base_ptr, bool safety_check_on, bool initializing, ZigType *result_type)
3094{
3095 IrInstGenOptionalUnwrapPtr *inst = ir_build_inst_gen<IrInstGenOptionalUnwrapPtr>(&ira->new_irb,
3096 source_instr->scope, source_instr->source_node);
3097 inst->base.value->type = result_type;
3098 inst->base_ptr = base_ptr;
3099 inst->safety_check_on = safety_check_on;
3100 inst->initializing = initializing;
3101
3102 ir_ref_inst_gen(base_ptr);
3103
3104 return &inst->base;
3105}
3106
3107static IrInstGen *ir_build_optional_wrap(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_ty,
3108 IrInstGen *operand, IrInstGen *result_loc)
3109{
3110 IrInstGenOptionalWrap *instruction = ir_build_inst_gen<IrInstGenOptionalWrap>(
3111 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
3112 instruction->base.value->type = result_ty;
3113 instruction->operand = operand;
3114 instruction->result_loc = result_loc;
3115
3116 ir_ref_inst_gen(operand);
3117 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
3118
3119 return &instruction->base;
3120}
3121
3122static IrInstGen *ir_build_err_wrap_payload(IrAnalyze *ira, IrInst *source_instruction,
3123 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc)
3124{
3125 IrInstGenErrWrapPayload *instruction = ir_build_inst_gen<IrInstGenErrWrapPayload>(
3126 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
3127 instruction->base.value->type = result_type;
3128 instruction->operand = operand;
3129 instruction->result_loc = result_loc;
3130
3131 ir_ref_inst_gen(operand);
3132 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
3133
3134 return &instruction->base;
3135}
3136
3137static IrInstGen *ir_build_err_wrap_code(IrAnalyze *ira, IrInst *source_instruction,
3138 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc)
3139{
3140 IrInstGenErrWrapCode *instruction = ir_build_inst_gen<IrInstGenErrWrapCode>(
3141 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
3142 instruction->base.value->type = result_type;
3143 instruction->operand = operand;
3144 instruction->result_loc = result_loc;
3145
3146 ir_ref_inst_gen(operand);
3147 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
3148
3149 return &instruction->base;
3150}
3151
3152static IrInstSrc *ir_build_clz(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type,
3153 IrInstSrc *op)
3154{
3155 IrInstSrcClz *instruction = ir_build_instruction<IrInstSrcClz>(irb, scope, source_node);
3156 instruction->type = type;
3157 instruction->op = op;
3158
3159 ir_ref_instruction(type, irb->current_basic_block);
3160 ir_ref_instruction(op, irb->current_basic_block);
3161
3162 return &instruction->base;
3163}
3164
3165static IrInstGen *ir_build_clz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) {
3166 IrInstGenClz *instruction = ir_build_inst_gen<IrInstGenClz>(&ira->new_irb,
3167 source_instr->scope, source_instr->source_node);
3168 instruction->base.value->type = result_type;
3169 instruction->op = op;
3170
3171 ir_ref_inst_gen(op);
3172
3173 return &instruction->base;
3174}
3175
3176static IrInstSrc *ir_build_ctz(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type,
3177 IrInstSrc *op)
3178{
3179 IrInstSrcCtz *instruction = ir_build_instruction<IrInstSrcCtz>(irb, scope, source_node);
3180 instruction->type = type;
3181 instruction->op = op;
3182
3183 ir_ref_instruction(type, irb->current_basic_block);
3184 ir_ref_instruction(op, irb->current_basic_block);
3185
3186 return &instruction->base;
3187}
3188
3189static IrInstGen *ir_build_ctz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) {
3190 IrInstGenCtz *instruction = ir_build_inst_gen<IrInstGenCtz>(&ira->new_irb,
3191 source_instr->scope, source_instr->source_node);
3192 instruction->base.value->type = result_type;
3193 instruction->op = op;
3194
3195 ir_ref_inst_gen(op);
3196
3197 return &instruction->base;
3198}
3199
3200static IrInstSrc *ir_build_pop_count(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type,
3201 IrInstSrc *op)
3202{
3203 IrInstSrcPopCount *instruction = ir_build_instruction<IrInstSrcPopCount>(irb, scope, source_node);
3204 instruction->type = type;
3205 instruction->op = op;
3206
3207 ir_ref_instruction(type, irb->current_basic_block);
3208 ir_ref_instruction(op, irb->current_basic_block);
3209
3210 return &instruction->base;
3211}
3212
3213static IrInstGen *ir_build_pop_count_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type,
3214 IrInstGen *op)
3215{
3216 IrInstGenPopCount *instruction = ir_build_inst_gen<IrInstGenPopCount>(&ira->new_irb,
3217 source_instr->scope, source_instr->source_node);
3218 instruction->base.value->type = result_type;
3219 instruction->op = op;
3220
3221 ir_ref_inst_gen(op);
3222
3223 return &instruction->base;
3224}
3225
3226static IrInstSrc *ir_build_bswap(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type,
3227 IrInstSrc *op)
3228{
3229 IrInstSrcBswap *instruction = ir_build_instruction<IrInstSrcBswap>(irb, scope, source_node);
3230 instruction->type = type;
3231 instruction->op = op;
3232
3233 ir_ref_instruction(type, irb->current_basic_block);
3234 ir_ref_instruction(op, irb->current_basic_block);
3235
3236 return &instruction->base;
3237}
3238
3239static IrInstGen *ir_build_bswap_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *op_type,
3240 IrInstGen *op)
3241{
3242 IrInstGenBswap *instruction = ir_build_inst_gen<IrInstGenBswap>(&ira->new_irb,
3243 source_instr->scope, source_instr->source_node);
3244 instruction->base.value->type = op_type;
3245 instruction->op = op;
3246
3247 ir_ref_inst_gen(op);
3248
3249 return &instruction->base;
3250}
3251
3252static IrInstSrc *ir_build_bit_reverse(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type,
3253 IrInstSrc *op)
3254{
3255 IrInstSrcBitReverse *instruction = ir_build_instruction<IrInstSrcBitReverse>(irb, scope, source_node);
3256 instruction->type = type;
3257 instruction->op = op;
3258
3259 ir_ref_instruction(type, irb->current_basic_block);
3260 ir_ref_instruction(op, irb->current_basic_block);
3261
3262 return &instruction->base;
3263}
3264
3265static IrInstGen *ir_build_bit_reverse_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *int_type,
3266 IrInstGen *op)
3267{
3268 IrInstGenBitReverse *instruction = ir_build_inst_gen<IrInstGenBitReverse>(&ira->new_irb,
3269 source_instr->scope, source_instr->source_node);
3270 instruction->base.value->type = int_type;
3271 instruction->op = op;
3272
3273 ir_ref_inst_gen(op);
3274
3275 return &instruction->base;
3276}
3277
3278static IrInstSrcSwitchBr *ir_build_switch_br_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3279 IrInstSrc *target_value, IrBasicBlockSrc *else_block, size_t case_count, IrInstSrcSwitchBrCase *cases,
3280 IrInstSrc *is_comptime, IrInstSrc *switch_prongs_void)
3281{
3282 IrInstSrcSwitchBr *instruction = ir_build_instruction<IrInstSrcSwitchBr>(irb, scope, source_node);
3283 instruction->base.is_noreturn = true;
3284 instruction->target_value = target_value;
3285 instruction->else_block = else_block;
3286 instruction->case_count = case_count;
3287 instruction->cases = cases;
3288 instruction->is_comptime = is_comptime;
3289 instruction->switch_prongs_void = switch_prongs_void;
3290
3291 ir_ref_instruction(target_value, irb->current_basic_block);
3292 ir_ref_instruction(is_comptime, irb->current_basic_block);
3293 ir_ref_bb(else_block);
3294 ir_ref_instruction(switch_prongs_void, irb->current_basic_block);
3295
3296 for (size_t i = 0; i < case_count; i += 1) {
3297 ir_ref_instruction(cases[i].value, irb->current_basic_block);
3298 ir_ref_bb(cases[i].block);
3299 }
3300
3301 return instruction;
3302}
3303
3304static IrInstGenSwitchBr *ir_build_switch_br_gen(IrAnalyze *ira, IrInst *source_instr,
3305 IrInstGen *target_value, IrBasicBlockGen *else_block, size_t case_count, IrInstGenSwitchBrCase *cases)
3306{
3307 IrInstGenSwitchBr *instruction = ir_build_inst_noreturn<IrInstGenSwitchBr>(&ira->new_irb,
3308 source_instr->scope, source_instr->source_node);
3309 instruction->target_value = target_value;
3310 instruction->else_block = else_block;
3311 instruction->case_count = case_count;
3312 instruction->cases = cases;
3313
3314 ir_ref_inst_gen(target_value);
3315
3316 for (size_t i = 0; i < case_count; i += 1) {
3317 ir_ref_inst_gen(cases[i].value);
3318 }
3319
3320 return instruction;
3321}
3322
3323static IrInstSrc *ir_build_switch_target(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3324 IrInstSrc *target_value_ptr)
3325{
3326 IrInstSrcSwitchTarget *instruction = ir_build_instruction<IrInstSrcSwitchTarget>(irb, scope, source_node);
3327 instruction->target_value_ptr = target_value_ptr;
3328
3329 ir_ref_instruction(target_value_ptr, irb->current_basic_block);
3330
3331 return &instruction->base;
3332}
3333
3334static IrInstSrc *ir_build_switch_var(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3335 IrInstSrc *target_value_ptr, IrInstSrc **prongs_ptr, size_t prongs_len)
3336{
3337 IrInstSrcSwitchVar *instruction = ir_build_instruction<IrInstSrcSwitchVar>(irb, scope, source_node);
3338 instruction->target_value_ptr = target_value_ptr;
3339 instruction->prongs_ptr = prongs_ptr;
3340 instruction->prongs_len = prongs_len;
3341
3342 ir_ref_instruction(target_value_ptr, irb->current_basic_block);
3343 for (size_t i = 0; i < prongs_len; i += 1) {
3344 ir_ref_instruction(prongs_ptr[i], irb->current_basic_block);
3345 }
3346
3347 return &instruction->base;
3348}
3349
3350// For this instruction the switch_br must be set later.
3351static IrInstSrcSwitchElseVar *ir_build_switch_else_var(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3352 IrInstSrc *target_value_ptr)
3353{
3354 IrInstSrcSwitchElseVar *instruction = ir_build_instruction<IrInstSrcSwitchElseVar>(irb, scope, source_node);
3355 instruction->target_value_ptr = target_value_ptr;
3356
3357 ir_ref_instruction(target_value_ptr, irb->current_basic_block);
3358
3359 return instruction;
3360}
3361
3362static IrInstGen *ir_build_union_tag(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value,
3363 ZigType *tag_type)
3364{
3365 IrInstGenUnionTag *instruction = ir_build_inst_gen<IrInstGenUnionTag>(&ira->new_irb,
3366 source_instr->scope, source_instr->source_node);
3367 instruction->value = value;
3368 instruction->base.value->type = tag_type;
3369
3370 ir_ref_inst_gen(value);
3371
3372 return &instruction->base;
3373}
3374
3375static IrInstSrc *ir_build_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) {
3376 IrInstSrcImport *instruction = ir_build_instruction<IrInstSrcImport>(irb, scope, source_node);
3377 instruction->name = name;
3378
3379 ir_ref_instruction(name, irb->current_basic_block);
3380
3381 return &instruction->base;
3382}
3383
3384static IrInstSrc *ir_build_ref_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) {
3385 IrInstSrcRef *instruction = ir_build_instruction<IrInstSrcRef>(irb, scope, source_node);
3386 instruction->value = value;
3387
3388 ir_ref_instruction(value, irb->current_basic_block);
3389
3390 return &instruction->base;
3391}
3392
3393static IrInstGen *ir_build_ref_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type,
3394 IrInstGen *operand, IrInstGen *result_loc)
3395{
3396 IrInstGenRef *instruction = ir_build_inst_gen<IrInstGenRef>(&ira->new_irb,
3397 source_instruction->scope, source_instruction->source_node);
3398 instruction->base.value->type = result_type;
3399 instruction->operand = operand;
3400 instruction->result_loc = result_loc;
3401
3402 ir_ref_inst_gen(operand);
3403 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
3404
3405 return &instruction->base;
3406}
3407
3408static IrInstSrc *ir_build_compile_err(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *msg) {
3409 IrInstSrcCompileErr *instruction = ir_build_instruction<IrInstSrcCompileErr>(irb, scope, source_node);
3410 instruction->msg = msg;
3411
3412 ir_ref_instruction(msg, irb->current_basic_block);
3413
3414 return &instruction->base;
3415}
3416
3417static IrInstSrc *ir_build_compile_log(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3418 size_t msg_count, IrInstSrc **msg_list)
3419{
3420 IrInstSrcCompileLog *instruction = ir_build_instruction<IrInstSrcCompileLog>(irb, scope, source_node);
3421 instruction->msg_count = msg_count;
3422 instruction->msg_list = msg_list;
3423
3424 for (size_t i = 0; i < msg_count; i += 1) {
3425 ir_ref_instruction(msg_list[i], irb->current_basic_block);
3426 }
3427
3428 return &instruction->base;
3429}
3430
3431static IrInstSrc *ir_build_err_name(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) {
3432 IrInstSrcErrName *instruction = ir_build_instruction<IrInstSrcErrName>(irb, scope, source_node);
3433 instruction->value = value;
3434
3435 ir_ref_instruction(value, irb->current_basic_block);
3436
3437 return &instruction->base;
3438}
3439
3440static IrInstGen *ir_build_err_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value,
3441 ZigType *str_type)
3442{
3443 IrInstGenErrName *instruction = ir_build_inst_gen<IrInstGenErrName>(&ira->new_irb,
3444 source_instr->scope, source_instr->source_node);
3445 instruction->base.value->type = str_type;
3446 instruction->value = value;
3447
3448 ir_ref_inst_gen(value);
3449
3450 return &instruction->base;
3451}
3452
3453static IrInstSrc *ir_build_c_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
3454 IrInstSrcCImport *instruction = ir_build_instruction<IrInstSrcCImport>(irb, scope, source_node);
3455 return &instruction->base;
3456}
3457
3458static IrInstSrc *ir_build_c_include(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) {
3459 IrInstSrcCInclude *instruction = ir_build_instruction<IrInstSrcCInclude>(irb, scope, source_node);
3460 instruction->name = name;
3461
3462 ir_ref_instruction(name, irb->current_basic_block);
3463
3464 return &instruction->base;
3465}
3466
3467static IrInstSrc *ir_build_c_define(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name, IrInstSrc *value) {
3468 IrInstSrcCDefine *instruction = ir_build_instruction<IrInstSrcCDefine>(irb, scope, source_node);
3469 instruction->name = name;
3470 instruction->value = value;
3471
3472 ir_ref_instruction(name, irb->current_basic_block);
3473 ir_ref_instruction(value, irb->current_basic_block);
3474
3475 return &instruction->base;
3476}
3477
3478static IrInstSrc *ir_build_c_undef(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) {
3479 IrInstSrcCUndef *instruction = ir_build_instruction<IrInstSrcCUndef>(irb, scope, source_node);
3480 instruction->name = name;
3481
3482 ir_ref_instruction(name, irb->current_basic_block);
3483
3484 return &instruction->base;
3485}
3486
3487static IrInstSrc *ir_build_embed_file(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) {
3488 IrInstSrcEmbedFile *instruction = ir_build_instruction<IrInstSrcEmbedFile>(irb, scope, source_node);
3489 instruction->name = name;
3490
3491 ir_ref_instruction(name, irb->current_basic_block);
3492
3493 return &instruction->base;
3494}
3495
3496static IrInstSrc *ir_build_cmpxchg_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3497 IrInstSrc *type_value, IrInstSrc *ptr, IrInstSrc *cmp_value, IrInstSrc *new_value,
3498 IrInstSrc *success_order_value, IrInstSrc *failure_order_value, bool is_weak, ResultLoc *result_loc)
3499{
3500 IrInstSrcCmpxchg *instruction = ir_build_instruction<IrInstSrcCmpxchg>(irb, scope, source_node);
3501 instruction->type_value = type_value;
3502 instruction->ptr = ptr;
3503 instruction->cmp_value = cmp_value;
3504 instruction->new_value = new_value;
3505 instruction->success_order_value = success_order_value;
3506 instruction->failure_order_value = failure_order_value;
3507 instruction->is_weak = is_weak;
3508 instruction->result_loc = result_loc;
3509
3510 ir_ref_instruction(type_value, irb->current_basic_block);
3511 ir_ref_instruction(ptr, irb->current_basic_block);
3512 ir_ref_instruction(cmp_value, irb->current_basic_block);
3513 ir_ref_instruction(new_value, irb->current_basic_block);
3514 ir_ref_instruction(success_order_value, irb->current_basic_block);
3515 ir_ref_instruction(failure_order_value, irb->current_basic_block);
3516
3517 return &instruction->base;
3518}
3519
3520static IrInstGen *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type,
3521 IrInstGen *ptr, IrInstGen *cmp_value, IrInstGen *new_value,
3522 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstGen *result_loc)
3523{
3524 IrInstGenCmpxchg *instruction = ir_build_inst_gen<IrInstGenCmpxchg>(&ira->new_irb,
3525 source_instruction->scope, source_instruction->source_node);
3526 instruction->base.value->type = result_type;
3527 instruction->ptr = ptr;
3528 instruction->cmp_value = cmp_value;
3529 instruction->new_value = new_value;
3530 instruction->success_order = success_order;
3531 instruction->failure_order = failure_order;
3532 instruction->is_weak = is_weak;
3533 instruction->result_loc = result_loc;
3534
3535 ir_ref_inst_gen(ptr);
3536 ir_ref_inst_gen(cmp_value);
3537 ir_ref_inst_gen(new_value);
3538 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
3539
3540 return &instruction->base;
3541}
3542
3543static IrInstSrc *ir_build_fence(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *order) {
3544 IrInstSrcFence *instruction = ir_build_instruction<IrInstSrcFence>(irb, scope, source_node);
3545 instruction->order = order;
3546
3547 ir_ref_instruction(order, irb->current_basic_block);
3548
3549 return &instruction->base;
3550}
3551
3552static IrInstGen *ir_build_fence_gen(IrAnalyze *ira, IrInst *source_instr, AtomicOrder order) {
3553 IrInstGenFence *instruction = ir_build_inst_void<IrInstGenFence>(&ira->new_irb,
3554 source_instr->scope, source_instr->source_node);
3555 instruction->order = order;
3556
3557 return &instruction->base;
3558}
3559
3560static IrInstSrc *ir_build_reduce(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *op, IrInstSrc *value) {
3561 IrInstSrcReduce *instruction = ir_build_instruction<IrInstSrcReduce>(irb, scope, source_node);
3562 instruction->op = op;
3563 instruction->value = value;
3564
3565 ir_ref_instruction(op, irb->current_basic_block);
3566 ir_ref_instruction(value, irb->current_basic_block);
3567
3568 return &instruction->base;
3569}
3570
3571static IrInstGen *ir_build_reduce_gen(IrAnalyze *ira, IrInst *source_instruction, ReduceOp op, IrInstGen *value, ZigType *result_type) {
3572 IrInstGenReduce *instruction = ir_build_inst_gen<IrInstGenReduce>(&ira->new_irb,
3573 source_instruction->scope, source_instruction->source_node);
3574 instruction->base.value->type = result_type;
3575 instruction->op = op;
3576 instruction->value = value;
3577
3578 ir_ref_inst_gen(value);
3579
3580 return &instruction->base;
3581}
3582
3583static IrInstSrc *ir_build_truncate(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3584 IrInstSrc *dest_type, IrInstSrc *target)
3585{
3586 IrInstSrcTruncate *instruction = ir_build_instruction<IrInstSrcTruncate>(irb, scope, source_node);
3587 instruction->dest_type = dest_type;
3588 instruction->target = target;
3589
3590 ir_ref_instruction(dest_type, irb->current_basic_block);
3591 ir_ref_instruction(target, irb->current_basic_block);
3592
3593 return &instruction->base;
3594}
3595
3596static IrInstGen *ir_build_truncate_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *dest_type,
3597 IrInstGen *target)
3598{
3599 IrInstGenTruncate *instruction = ir_build_inst_gen<IrInstGenTruncate>(&ira->new_irb,
3600 source_instr->scope, source_instr->source_node);
3601 instruction->base.value->type = dest_type;
3602 instruction->target = target;
3603
3604 ir_ref_inst_gen(target);
3605
3606 return &instruction->base;
3607}
3608
3609static IrInstSrc *ir_build_int_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *dest_type,
3610 IrInstSrc *target)
3611{
3612 IrInstSrcIntCast *instruction = ir_build_instruction<IrInstSrcIntCast>(irb, scope, source_node);
3613 instruction->dest_type = dest_type;
3614 instruction->target = target;
3615
3616 ir_ref_instruction(dest_type, irb->current_basic_block);
3617 ir_ref_instruction(target, irb->current_basic_block);
3618
3619 return &instruction->base;
3620}
3621
3622static IrInstSrc *ir_build_float_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *dest_type,
3623 IrInstSrc *target)
3624{
3625 IrInstSrcFloatCast *instruction = ir_build_instruction<IrInstSrcFloatCast>(irb, scope, source_node);
3626 instruction->dest_type = dest_type;
3627 instruction->target = target;
3628
3629 ir_ref_instruction(dest_type, irb->current_basic_block);
3630 ir_ref_instruction(target, irb->current_basic_block);
3631
3632 return &instruction->base;
3633}
3634
3635static IrInstSrc *ir_build_err_set_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3636 IrInstSrc *dest_type, IrInstSrc *target)
3637{
3638 IrInstSrcErrSetCast *instruction = ir_build_instruction<IrInstSrcErrSetCast>(irb, scope, source_node);
3639 instruction->dest_type = dest_type;
3640 instruction->target = target;
3641
3642 ir_ref_instruction(dest_type, irb->current_basic_block);
3643 ir_ref_instruction(target, irb->current_basic_block);
3644
3645 return &instruction->base;
3646}
3647
3648static IrInstSrc *ir_build_int_to_float(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3649 IrInstSrc *dest_type, IrInstSrc *target)
3650{
3651 IrInstSrcIntToFloat *instruction = ir_build_instruction<IrInstSrcIntToFloat>(irb, scope, source_node);
3652 instruction->dest_type = dest_type;
3653 instruction->target = target;
3654
3655 ir_ref_instruction(dest_type, irb->current_basic_block);
3656 ir_ref_instruction(target, irb->current_basic_block);
3657
3658 return &instruction->base;
3659}
3660
3661static IrInstSrc *ir_build_float_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3662 IrInstSrc *dest_type, IrInstSrc *target)
3663{
3664 IrInstSrcFloatToInt *instruction = ir_build_instruction<IrInstSrcFloatToInt>(irb, scope, source_node);
3665 instruction->dest_type = dest_type;
3666 instruction->target = target;
3667
3668 ir_ref_instruction(dest_type, irb->current_basic_block);
3669 ir_ref_instruction(target, irb->current_basic_block);
3670
3671 return &instruction->base;
3672}
3673
3674static IrInstSrc *ir_build_bool_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target) {
3675 IrInstSrcBoolToInt *instruction = ir_build_instruction<IrInstSrcBoolToInt>(irb, scope, source_node);
3676 instruction->target = target;
3677
3678 ir_ref_instruction(target, irb->current_basic_block);
3679
3680 return &instruction->base;
3681}
3682
3683static IrInstSrc *ir_build_vector_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *len,
3684 IrInstSrc *elem_type)
3685{
3686 IrInstSrcVectorType *instruction = ir_build_instruction<IrInstSrcVectorType>(irb, scope, source_node);
3687 instruction->len = len;
3688 instruction->elem_type = elem_type;
3689
3690 ir_ref_instruction(len, irb->current_basic_block);
3691 ir_ref_instruction(elem_type, irb->current_basic_block);
3692
3693 return &instruction->base;
3694}
3695
3696static IrInstSrc *ir_build_shuffle_vector(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3697 IrInstSrc *scalar_type, IrInstSrc *a, IrInstSrc *b, IrInstSrc *mask)
3698{
3699 IrInstSrcShuffleVector *instruction = ir_build_instruction<IrInstSrcShuffleVector>(irb, scope, source_node);
3700 instruction->scalar_type = scalar_type;
3701 instruction->a = a;
3702 instruction->b = b;
3703 instruction->mask = mask;
3704
3705 if (scalar_type != nullptr) ir_ref_instruction(scalar_type, irb->current_basic_block);
3706 ir_ref_instruction(a, irb->current_basic_block);
3707 ir_ref_instruction(b, irb->current_basic_block);
3708 ir_ref_instruction(mask, irb->current_basic_block);
3709
3710 return &instruction->base;
3711}
3712
3713static IrInstGen *ir_build_shuffle_vector_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
3714 ZigType *result_type, IrInstGen *a, IrInstGen *b, IrInstGen *mask)
3715{
3716 IrInstGenShuffleVector *inst = ir_build_inst_gen<IrInstGenShuffleVector>(&ira->new_irb, scope, source_node);
3717 inst->base.value->type = result_type;
3718 inst->a = a;
3719 inst->b = b;
3720 inst->mask = mask;
3721
3722 ir_ref_inst_gen(a);
3723 ir_ref_inst_gen(b);
3724 ir_ref_inst_gen(mask);
3725
3726 return &inst->base;
3727}
3728
3729static IrInstSrc *ir_build_splat_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3730 IrInstSrc *len, IrInstSrc *scalar)
3731{
3732 IrInstSrcSplat *instruction = ir_build_instruction<IrInstSrcSplat>(irb, scope, source_node);
3733 instruction->len = len;
3734 instruction->scalar = scalar;
3735
3736 ir_ref_instruction(len, irb->current_basic_block);
3737 ir_ref_instruction(scalar, irb->current_basic_block);
3738
3739 return &instruction->base;
3740}
3741
3742static IrInstGen *ir_build_splat_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type,
3743 IrInstGen *scalar)
3744{
3745 IrInstGenSplat *instruction = ir_build_inst_gen<IrInstGenSplat>(
3746 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
3747 instruction->base.value->type = result_type;
3748 instruction->scalar = scalar;
3749
3750 ir_ref_inst_gen(scalar);
3751
3752 return &instruction->base;
3753}
3754
3755static IrInstSrc *ir_build_bool_not(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) {
3756 IrInstSrcBoolNot *instruction = ir_build_instruction<IrInstSrcBoolNot>(irb, scope, source_node);
3757 instruction->value = value;
3758
3759 ir_ref_instruction(value, irb->current_basic_block);
3760
3761 return &instruction->base;
3762}
3763
3764static IrInstGen *ir_build_bool_not_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) {
3765 IrInstGenBoolNot *instruction = ir_build_inst_gen<IrInstGenBoolNot>(&ira->new_irb,
3766 source_instr->scope, source_instr->source_node);
3767 instruction->base.value->type = ira->codegen->builtin_types.entry_bool;
3768 instruction->value = value;
3769
3770 ir_ref_inst_gen(value);
3771
3772 return &instruction->base;
3773}
3774
3775static IrInstSrc *ir_build_memset_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3776 IrInstSrc *dest_ptr, IrInstSrc *byte, IrInstSrc *count)
3777{
3778 IrInstSrcMemset *instruction = ir_build_instruction<IrInstSrcMemset>(irb, scope, source_node);
3779 instruction->dest_ptr = dest_ptr;
3780 instruction->byte = byte;
3781 instruction->count = count;
3782
3783 ir_ref_instruction(dest_ptr, irb->current_basic_block);
3784 ir_ref_instruction(byte, irb->current_basic_block);
3785 ir_ref_instruction(count, irb->current_basic_block);
3786
3787 return &instruction->base;
3788}
3789
3790static IrInstGen *ir_build_memset_gen(IrAnalyze *ira, IrInst *source_instr,
3791 IrInstGen *dest_ptr, IrInstGen *byte, IrInstGen *count)
3792{
3793 IrInstGenMemset *instruction = ir_build_inst_void<IrInstGenMemset>(&ira->new_irb,
3794 source_instr->scope, source_instr->source_node);
3795 instruction->dest_ptr = dest_ptr;
3796 instruction->byte = byte;
3797 instruction->count = count;
3798
3799 ir_ref_inst_gen(dest_ptr);
3800 ir_ref_inst_gen(byte);
3801 ir_ref_inst_gen(count);
3802
3803 return &instruction->base;
3804}
3805
3806static IrInstSrc *ir_build_memcpy_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3807 IrInstSrc *dest_ptr, IrInstSrc *src_ptr, IrInstSrc *count)
3808{
3809 IrInstSrcMemcpy *instruction = ir_build_instruction<IrInstSrcMemcpy>(irb, scope, source_node);
3810 instruction->dest_ptr = dest_ptr;
3811 instruction->src_ptr = src_ptr;
3812 instruction->count = count;
3813
3814 ir_ref_instruction(dest_ptr, irb->current_basic_block);
3815 ir_ref_instruction(src_ptr, irb->current_basic_block);
3816 ir_ref_instruction(count, irb->current_basic_block);
3817
3818 return &instruction->base;
3819}
3820
3821static IrInstGen *ir_build_memcpy_gen(IrAnalyze *ira, IrInst *source_instr,
3822 IrInstGen *dest_ptr, IrInstGen *src_ptr, IrInstGen *count)
3823{
3824 IrInstGenMemcpy *instruction = ir_build_inst_void<IrInstGenMemcpy>(&ira->new_irb,
3825 source_instr->scope, source_instr->source_node);
3826 instruction->dest_ptr = dest_ptr;
3827 instruction->src_ptr = src_ptr;
3828 instruction->count = count;
3829
3830 ir_ref_inst_gen(dest_ptr);
3831 ir_ref_inst_gen(src_ptr);
3832 ir_ref_inst_gen(count);
3833
3834 return &instruction->base;
3835}
3836
3837static IrInstSrc *ir_build_slice_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3838 IrInstSrc *ptr, IrInstSrc *start, IrInstSrc *end, IrInstSrc *sentinel,
3839 bool safety_check_on, ResultLoc *result_loc)
3840{
3841 IrInstSrcSlice *instruction = ir_build_instruction<IrInstSrcSlice>(irb, scope, source_node);
3842 instruction->ptr = ptr;
3843 instruction->start = start;
3844 instruction->end = end;
3845 instruction->sentinel = sentinel;
3846 instruction->safety_check_on = safety_check_on;
3847 instruction->result_loc = result_loc;
3848
3849 ir_ref_instruction(ptr, irb->current_basic_block);
3850 ir_ref_instruction(start, irb->current_basic_block);
3851 if (end) ir_ref_instruction(end, irb->current_basic_block);
3852 if (sentinel) ir_ref_instruction(sentinel, irb->current_basic_block);
3853
3854 return &instruction->base;
3855}
3856
3857static IrInstGen *ir_build_slice_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *slice_type,
3858 IrInstGen *ptr, IrInstGen *start, IrInstGen *end, bool safety_check_on, IrInstGen *result_loc,
3859 ZigValue *sentinel)
3860{
3861 IrInstGenSlice *instruction = ir_build_inst_gen<IrInstGenSlice>(
3862 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
3863 instruction->base.value->type = slice_type;
3864 instruction->ptr = ptr;
3865 instruction->start = start;
3866 instruction->end = end;
3867 instruction->safety_check_on = safety_check_on;
3868 instruction->result_loc = result_loc;
3869 instruction->sentinel = sentinel;
3870
3871 ir_ref_inst_gen(ptr);
3872 ir_ref_inst_gen(start);
3873 if (end != nullptr) ir_ref_inst_gen(end);
3874 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
3875
3876 return &instruction->base;
3877}
3878
3879static IrInstSrc *ir_build_breakpoint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
3880 IrInstSrcBreakpoint *instruction = ir_build_instruction<IrInstSrcBreakpoint>(irb, scope, source_node);
3881 return &instruction->base;
3882}
3883
3884static IrInstGen *ir_build_breakpoint_gen(IrAnalyze *ira, IrInst *source_instr) {
3885 IrInstGenBreakpoint *instruction = ir_build_inst_void<IrInstGenBreakpoint>(&ira->new_irb,
3886 source_instr->scope, source_instr->source_node);
3887 return &instruction->base;
3888}
3889
3890static IrInstSrc *ir_build_return_address_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
3891 IrInstSrcReturnAddress *instruction = ir_build_instruction<IrInstSrcReturnAddress>(irb, scope, source_node);
3892 return &instruction->base;
3893}
3894
3895static IrInstGen *ir_build_return_address_gen(IrAnalyze *ira, IrInst *source_instr) {
3896 IrInstGenReturnAddress *inst = ir_build_inst_gen<IrInstGenReturnAddress>(&ira->new_irb, source_instr->scope, source_instr->source_node);
3897 inst->base.value->type = ira->codegen->builtin_types.entry_usize;
3898 return &inst->base;
3899}
3900
3901static IrInstSrc *ir_build_frame_address_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
3902 IrInstSrcFrameAddress *inst = ir_build_instruction<IrInstSrcFrameAddress>(irb, scope, source_node);
3903 return &inst->base;
3904}
3905
3906static IrInstGen *ir_build_frame_address_gen(IrAnalyze *ira, IrInst *source_instr) {
3907 IrInstGenFrameAddress *inst = ir_build_inst_gen<IrInstGenFrameAddress>(&ira->new_irb, source_instr->scope, source_instr->source_node);
3908 inst->base.value->type = ira->codegen->builtin_types.entry_usize;
3909 return &inst->base;
3910}
3911
3912static IrInstSrc *ir_build_handle_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
3913 IrInstSrcFrameHandle *inst = ir_build_instruction<IrInstSrcFrameHandle>(irb, scope, source_node);
3914 return &inst->base;
3915}
3916
3917static IrInstGen *ir_build_handle_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *ty) {
3918 IrInstGenFrameHandle *inst = ir_build_inst_gen<IrInstGenFrameHandle>(&ira->new_irb, source_instr->scope, source_instr->source_node);
3919 inst->base.value->type = ty;
3920 return &inst->base;
3921}
3922
3923static IrInstSrc *ir_build_frame_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *fn) {
3924 IrInstSrcFrameType *inst = ir_build_instruction<IrInstSrcFrameType>(irb, scope, source_node);
3925 inst->fn = fn;
3926
3927 ir_ref_instruction(fn, irb->current_basic_block);
3928
3929 return &inst->base;
3930}
3931
3932static IrInstSrc *ir_build_frame_size_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *fn) {
3933 IrInstSrcFrameSize *inst = ir_build_instruction<IrInstSrcFrameSize>(irb, scope, source_node);
3934 inst->fn = fn;
3935
3936 ir_ref_instruction(fn, irb->current_basic_block);
3937
3938 return &inst->base;
3939}
3940
3941static IrInstGen *ir_build_frame_size_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *fn)
3942{
3943 IrInstGenFrameSize *inst = ir_build_inst_gen<IrInstGenFrameSize>(&ira->new_irb, source_instr->scope, source_instr->source_node);
3944 inst->base.value->type = ira->codegen->builtin_types.entry_usize;
3945 inst->fn = fn;
3946
3947 ir_ref_inst_gen(fn);
3948
3949 return &inst->base;
3950}
3951
3952static IrInstSrc *ir_build_overflow_op_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3953 IrOverflowOp op, IrInstSrc *type_value, IrInstSrc *op1, IrInstSrc *op2, IrInstSrc *result_ptr)
3954{
3955 IrInstSrcOverflowOp *instruction = ir_build_instruction<IrInstSrcOverflowOp>(irb, scope, source_node);
3956 instruction->op = op;
3957 instruction->type_value = type_value;
3958 instruction->op1 = op1;
3959 instruction->op2 = op2;
3960 instruction->result_ptr = result_ptr;
3961
3962 ir_ref_instruction(type_value, irb->current_basic_block);
3963 ir_ref_instruction(op1, irb->current_basic_block);
3964 ir_ref_instruction(op2, irb->current_basic_block);
3965 ir_ref_instruction(result_ptr, irb->current_basic_block);
3966
3967 return &instruction->base;
3968}
3969
3970static IrInstGen *ir_build_overflow_op_gen(IrAnalyze *ira, IrInst *source_instr,
3971 IrOverflowOp op, IrInstGen *op1, IrInstGen *op2, IrInstGen *result_ptr,
3972 ZigType *result_ptr_type)
3973{
3974 IrInstGenOverflowOp *instruction = ir_build_inst_gen<IrInstGenOverflowOp>(&ira->new_irb,
3975 source_instr->scope, source_instr->source_node);
3976 instruction->base.value->type = ira->codegen->builtin_types.entry_bool;
3977 instruction->op = op;
3978 instruction->op1 = op1;
3979 instruction->op2 = op2;
3980 instruction->result_ptr = result_ptr;
3981 instruction->result_ptr_type = result_ptr_type;
3982
3983 ir_ref_inst_gen(op1);
3984 ir_ref_inst_gen(op2);
3985 ir_ref_inst_gen(result_ptr);
3986
3987 return &instruction->base;
3988}
3989
3990static IrInstSrc *ir_build_float_op_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *operand,
3991 BuiltinFnId fn_id)
3992{
3993 IrInstSrcFloatOp *instruction = ir_build_instruction<IrInstSrcFloatOp>(irb, scope, source_node);
3994 instruction->operand = operand;
3995 instruction->fn_id = fn_id;
3996
3997 ir_ref_instruction(operand, irb->current_basic_block);
3998
3999 return &instruction->base;
4000}
4001
4002static IrInstGen *ir_build_float_op_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand,
4003 BuiltinFnId fn_id, ZigType *operand_type)
4004{
4005 IrInstGenFloatOp *instruction = ir_build_inst_gen<IrInstGenFloatOp>(&ira->new_irb,
4006 source_instr->scope, source_instr->source_node);
4007 instruction->base.value->type = operand_type;
4008 instruction->operand = operand;
4009 instruction->fn_id = fn_id;
4010
4011 ir_ref_inst_gen(operand);
4012
4013 return &instruction->base;
4014}
4015
4016static IrInstSrc *ir_build_mul_add_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4017 IrInstSrc *type_value, IrInstSrc *op1, IrInstSrc *op2, IrInstSrc *op3)
4018{
4019 IrInstSrcMulAdd *instruction = ir_build_instruction<IrInstSrcMulAdd>(irb, scope, source_node);
4020 instruction->type_value = type_value;
4021 instruction->op1 = op1;
4022 instruction->op2 = op2;
4023 instruction->op3 = op3;
4024
4025 ir_ref_instruction(type_value, irb->current_basic_block);
4026 ir_ref_instruction(op1, irb->current_basic_block);
4027 ir_ref_instruction(op2, irb->current_basic_block);
4028 ir_ref_instruction(op3, irb->current_basic_block);
4029
4030 return &instruction->base;
4031}
4032
4033static IrInstGen *ir_build_mul_add_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *op1, IrInstGen *op2,
4034 IrInstGen *op3, ZigType *expr_type)
4035{
4036 IrInstGenMulAdd *instruction = ir_build_inst_gen<IrInstGenMulAdd>(&ira->new_irb,
4037 source_instr->scope, source_instr->source_node);
4038 instruction->base.value->type = expr_type;
4039 instruction->op1 = op1;
4040 instruction->op2 = op2;
4041 instruction->op3 = op3;
4042
4043 ir_ref_inst_gen(op1);
4044 ir_ref_inst_gen(op2);
4045 ir_ref_inst_gen(op3);
4046
4047 return &instruction->base;
4048}
4049
4050static IrInstSrc *ir_build_align_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value) {
4051 IrInstSrcAlignOf *instruction = ir_build_instruction<IrInstSrcAlignOf>(irb, scope, source_node);
4052 instruction->type_value = type_value;
4053
4054 ir_ref_instruction(type_value, irb->current_basic_block);
4055
4056 return &instruction->base;
4057}
4058
4059static IrInstSrc *ir_build_test_err_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4060 IrInstSrc *base_ptr, bool resolve_err_set, bool base_ptr_is_payload)
4061{
4062 IrInstSrcTestErr *instruction = ir_build_instruction<IrInstSrcTestErr>(irb, scope, source_node);
4063 instruction->base_ptr = base_ptr;
4064 instruction->resolve_err_set = resolve_err_set;
4065 instruction->base_ptr_is_payload = base_ptr_is_payload;
4066
4067 ir_ref_instruction(base_ptr, irb->current_basic_block);
4068
4069 return &instruction->base;
4070}
4071
4072static IrInstGen *ir_build_test_err_gen(IrAnalyze *ira, IrInst *source_instruction, IrInstGen *err_union) {
4073 IrInstGenTestErr *instruction = ir_build_inst_gen<IrInstGenTestErr>(
4074 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
4075 instruction->base.value->type = ira->codegen->builtin_types.entry_bool;
4076 instruction->err_union = err_union;
4077
4078 ir_ref_inst_gen(err_union);
4079
4080 return &instruction->base;
4081}
4082
4083static IrInstSrc *ir_build_unwrap_err_code_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4084 IrInstSrc *err_union_ptr)
4085{
4086 IrInstSrcUnwrapErrCode *inst = ir_build_instruction<IrInstSrcUnwrapErrCode>(irb, scope, source_node);
4087 inst->err_union_ptr = err_union_ptr;
4088
4089 ir_ref_instruction(err_union_ptr, irb->current_basic_block);
4090
4091 return &inst->base;
4092}
4093
4094static IrInstGen *ir_build_unwrap_err_code_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
4095 IrInstGen *err_union_ptr, ZigType *result_type)
4096{
4097 IrInstGenUnwrapErrCode *inst = ir_build_inst_gen<IrInstGenUnwrapErrCode>(&ira->new_irb, scope, source_node);
4098 inst->base.value->type = result_type;
4099 inst->err_union_ptr = err_union_ptr;
4100
4101 ir_ref_inst_gen(err_union_ptr);
4102
4103 return &inst->base;
4104}
4105
4106static IrInstSrc *ir_build_unwrap_err_payload_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4107 IrInstSrc *value, bool safety_check_on, bool initializing)
4108{
4109 IrInstSrcUnwrapErrPayload *inst = ir_build_instruction<IrInstSrcUnwrapErrPayload>(irb, scope, source_node);
4110 inst->value = value;
4111 inst->safety_check_on = safety_check_on;
4112 inst->initializing = initializing;
4113
4114 ir_ref_instruction(value, irb->current_basic_block);
4115
4116 return &inst->base;
4117}
4118
4119static IrInstGen *ir_build_unwrap_err_payload_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
4120 IrInstGen *value, bool safety_check_on, bool initializing, ZigType *result_type)
4121{
4122 IrInstGenUnwrapErrPayload *inst = ir_build_inst_gen<IrInstGenUnwrapErrPayload>(&ira->new_irb, scope, source_node);
4123 inst->base.value->type = result_type;
4124 inst->value = value;
4125 inst->safety_check_on = safety_check_on;
4126 inst->initializing = initializing;
4127
4128 ir_ref_inst_gen(value);
4129
4130 return &inst->base;
4131}
4132
4133static IrInstSrc *ir_build_fn_proto(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4134 IrInstSrc **param_types, IrInstSrc *align_value, IrInstSrc *callconv_value,
4135 IrInstSrc *return_type, bool is_var_args)
4136{
4137 IrInstSrcFnProto *instruction = ir_build_instruction<IrInstSrcFnProto>(irb, scope, source_node);
4138 instruction->param_types = param_types;
4139 instruction->align_value = align_value;
4140 instruction->callconv_value = callconv_value;
4141 instruction->return_type = return_type;
4142 instruction->is_var_args = is_var_args;
4143
4144 assert(source_node->type == NodeTypeFnProto);
4145 size_t param_count = source_node->data.fn_proto.params.length;
4146 if (is_var_args) param_count -= 1;
4147 for (size_t i = 0; i < param_count; i += 1) {
4148 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block);
4149 }
4150 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block);
4151 if (callconv_value != nullptr) ir_ref_instruction(callconv_value, irb->current_basic_block);
4152 ir_ref_instruction(return_type, irb->current_basic_block);
4153
4154 return &instruction->base;
4155}
4156
4157static IrInstSrc *ir_build_test_comptime(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) {
4158 IrInstSrcTestComptime *instruction = ir_build_instruction<IrInstSrcTestComptime>(irb, scope, source_node);
4159 instruction->value = value;
4160
4161 ir_ref_instruction(value, irb->current_basic_block);
4162
4163 return &instruction->base;
4164}
4165
4166static IrInstSrc *ir_build_ptr_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4167 IrInstSrc *dest_type, IrInstSrc *ptr, bool safety_check_on)
4168{
4169 IrInstSrcPtrCast *instruction = ir_build_instruction<IrInstSrcPtrCast>(
4170 irb, scope, source_node);
4171 instruction->dest_type = dest_type;
4172 instruction->ptr = ptr;
4173 instruction->safety_check_on = safety_check_on;
4174
4175 ir_ref_instruction(dest_type, irb->current_basic_block);
4176 ir_ref_instruction(ptr, irb->current_basic_block);
4177
4178 return &instruction->base;
4179}
4180
4181static IrInstGen *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInst *source_instruction,
4182 ZigType *ptr_type, IrInstGen *ptr, bool safety_check_on)
4183{
4184 IrInstGenPtrCast *instruction = ir_build_inst_gen<IrInstGenPtrCast>(
4185 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
4186 instruction->base.value->type = ptr_type;
4187 instruction->ptr = ptr;
4188 instruction->safety_check_on = safety_check_on;
4189
4190 ir_ref_inst_gen(ptr);
4191
4192 return &instruction->base;
4193}
4194
4195static IrInstSrc *ir_build_implicit_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4196 IrInstSrc *operand, ResultLocCast *result_loc_cast)
4197{
4198 IrInstSrcImplicitCast *instruction = ir_build_instruction<IrInstSrcImplicitCast>(irb, scope, source_node);
4199 instruction->operand = operand;
4200 instruction->result_loc_cast = result_loc_cast;
4201
4202 ir_ref_instruction(operand, irb->current_basic_block);
4203
4204 return &instruction->base;
4205}
4206
4207static IrInstSrc *ir_build_bit_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4208 IrInstSrc *operand, ResultLocBitCast *result_loc_bit_cast)
4209{
4210 IrInstSrcBitCast *instruction = ir_build_instruction<IrInstSrcBitCast>(irb, scope, source_node);
4211 instruction->operand = operand;
4212 instruction->result_loc_bit_cast = result_loc_bit_cast;
4213
4214 ir_ref_instruction(operand, irb->current_basic_block);
4215
4216 return &instruction->base;
4217}
4218
4219static IrInstGen *ir_build_bit_cast_gen(IrAnalyze *ira, IrInst *source_instruction,
4220 IrInstGen *operand, ZigType *ty)
4221{
4222 IrInstGenBitCast *instruction = ir_build_inst_gen<IrInstGenBitCast>(
4223 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
4224 instruction->base.value->type = ty;
4225 instruction->operand = operand;
4226
4227 ir_ref_inst_gen(operand);
4228
4229 return &instruction->base;
4230}
4231
4232static IrInstGen *ir_build_widen_or_shorten(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target,
4233 ZigType *result_type)
4234{
4235 IrInstGenWidenOrShorten *inst = ir_build_inst_gen<IrInstGenWidenOrShorten>(&ira->new_irb, scope, source_node);
4236 inst->base.value->type = result_type;
4237 inst->target = target;
4238
4239 ir_ref_inst_gen(target);
4240
4241 return &inst->base;
4242}
4243
4244static IrInstSrc *ir_build_int_to_ptr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4245 IrInstSrc *dest_type, IrInstSrc *target)
4246{
4247 IrInstSrcIntToPtr *instruction = ir_build_instruction<IrInstSrcIntToPtr>(irb, scope, source_node);
4248 instruction->dest_type = dest_type;
4249 instruction->target = target;
4250
4251 ir_ref_instruction(dest_type, irb->current_basic_block);
4252 ir_ref_instruction(target, irb->current_basic_block);
4253
4254 return &instruction->base;
4255}
4256
4257static IrInstGen *ir_build_int_to_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
4258 IrInstGen *target, ZigType *ptr_type)
4259{
4260 IrInstGenIntToPtr *instruction = ir_build_inst_gen<IrInstGenIntToPtr>(&ira->new_irb, scope, source_node);
4261 instruction->base.value->type = ptr_type;
4262 instruction->target = target;
4263
4264 ir_ref_inst_gen(target);
4265
4266 return &instruction->base;
4267}
4268
4269static IrInstSrc *ir_build_ptr_to_int_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4270 IrInstSrc *target)
4271{
4272 IrInstSrcPtrToInt *inst = ir_build_instruction<IrInstSrcPtrToInt>(irb, scope, source_node);
4273 inst->target = target;
4274
4275 ir_ref_instruction(target, irb->current_basic_block);
4276
4277 return &inst->base;
4278}
4279
4280static IrInstGen *ir_build_ptr_to_int_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target) {
4281 IrInstGenPtrToInt *inst = ir_build_inst_gen<IrInstGenPtrToInt>(&ira->new_irb, source_instr->scope, source_instr->source_node);
4282 inst->base.value->type = ira->codegen->builtin_types.entry_usize;
4283 inst->target = target;
4284
4285 ir_ref_inst_gen(target);
4286
4287 return &inst->base;
4288}
4289
4290static IrInstSrc *ir_build_int_to_enum_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4291 IrInstSrc *dest_type, IrInstSrc *target)
4292{
4293 IrInstSrcIntToEnum *instruction = ir_build_instruction<IrInstSrcIntToEnum>(irb, scope, source_node);
4294 instruction->dest_type = dest_type;
4295 instruction->target = target;
4296
4297 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block);
4298 ir_ref_instruction(target, irb->current_basic_block);
4299
4300 return &instruction->base;
4301}
4302
4303static IrInstGen *ir_build_int_to_enum_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
4304 ZigType *dest_type, IrInstGen *target)
4305{
4306 IrInstGenIntToEnum *instruction = ir_build_inst_gen<IrInstGenIntToEnum>(&ira->new_irb, scope, source_node);
4307 instruction->base.value->type = dest_type;
4308 instruction->target = target;
4309
4310 ir_ref_inst_gen(target);
4311
4312 return &instruction->base;
4313}
4314
4315static IrInstSrc *ir_build_enum_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4316 IrInstSrc *target)
4317{
4318 IrInstSrcEnumToInt *instruction = ir_build_instruction<IrInstSrcEnumToInt>(
4319 irb, scope, source_node);
4320 instruction->target = target;
4321
4322 ir_ref_instruction(target, irb->current_basic_block);
4323
4324 return &instruction->base;
4325}
4326
4327static IrInstSrc *ir_build_int_to_err_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4328 IrInstSrc *target)
4329{
4330 IrInstSrcIntToErr *instruction = ir_build_instruction<IrInstSrcIntToErr>(irb, scope, source_node);
4331 instruction->target = target;
4332
4333 ir_ref_instruction(target, irb->current_basic_block);
4334
4335 return &instruction->base;
4336}
4337
4338static IrInstGen *ir_build_int_to_err_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target,
4339 ZigType *wanted_type)
4340{
4341 IrInstGenIntToErr *instruction = ir_build_inst_gen<IrInstGenIntToErr>(&ira->new_irb, scope, source_node);
4342 instruction->base.value->type = wanted_type;
4343 instruction->target = target;
4344
4345 ir_ref_inst_gen(target);
4346
4347 return &instruction->base;
4348}
4349
4350static IrInstSrc *ir_build_err_to_int_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4351 IrInstSrc *target)
4352{
4353 IrInstSrcErrToInt *instruction = ir_build_instruction<IrInstSrcErrToInt>(
4354 irb, scope, source_node);
4355 instruction->target = target;
4356
4357 ir_ref_instruction(target, irb->current_basic_block);
4358
4359 return &instruction->base;
4360}
4361
4362static IrInstGen *ir_build_err_to_int_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target,
4363 ZigType *wanted_type)
4364{
4365 IrInstGenErrToInt *instruction = ir_build_inst_gen<IrInstGenErrToInt>(&ira->new_irb, scope, source_node);
4366 instruction->base.value->type = wanted_type;
4367 instruction->target = target;
4368
4369 ir_ref_inst_gen(target);
4370
4371 return &instruction->base;
4372}
4373
4374static IrInstSrc *ir_build_check_switch_prongs(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4375 IrInstSrc *target_value, IrInstSrcCheckSwitchProngsRange *ranges, size_t range_count,
4376 AstNode* else_prong, bool have_underscore_prong)
4377{
4378 IrInstSrcCheckSwitchProngs *instruction = heap::c_allocator.create<IrInstSrcCheckSwitchProngs>();
4379 instruction->base.id = have_underscore_prong ?
4380 IrInstSrcIdCheckSwitchProngsUnderYes : IrInstSrcIdCheckSwitchProngsUnderNo;
4381 instruction->base.base.scope = scope;
4382 instruction->base.base.source_node = source_node;
4383 instruction->base.base.debug_id = exec_next_debug_id(irb->exec);
4384 instruction->base.owner_bb = irb->current_basic_block;
4385 ir_instruction_append(irb->current_basic_block, &instruction->base);
4386
4387 instruction->target_value = target_value;
4388 instruction->ranges = ranges;
4389 instruction->range_count = range_count;
4390 instruction->else_prong = else_prong;
4391
4392 ir_ref_instruction(target_value, irb->current_basic_block);
4393 for (size_t i = 0; i < range_count; i += 1) {
4394 ir_ref_instruction(ranges[i].start, irb->current_basic_block);
4395 ir_ref_instruction(ranges[i].end, irb->current_basic_block);
4396 }
4397
4398 return &instruction->base;
4399}
4400
4401static IrInstSrc *ir_build_check_statement_is_void(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4402 IrInstSrc* statement_value)
4403{
4404 IrInstSrcCheckStatementIsVoid *instruction = ir_build_instruction<IrInstSrcCheckStatementIsVoid>(
4405 irb, scope, source_node);
4406 instruction->statement_value = statement_value;
4407
4408 ir_ref_instruction(statement_value, irb->current_basic_block);
4409
4410 return &instruction->base;
4411}
4412
4413static IrInstSrc *ir_build_type_name(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4414 IrInstSrc *type_value)
4415{
4416 IrInstSrcTypeName *instruction = ir_build_instruction<IrInstSrcTypeName>(irb, scope, source_node);
4417 instruction->type_value = type_value;
4418
4419 ir_ref_instruction(type_value, irb->current_basic_block);
4420
4421 return &instruction->base;
4422}
4423
4424static IrInstSrc *ir_build_decl_ref(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) {
4425 IrInstSrcDeclRef *instruction = ir_build_instruction<IrInstSrcDeclRef>(irb, scope, source_node);
4426 instruction->tld = tld;
4427 instruction->lval = lval;
4428
4429 return &instruction->base;
4430}
4431
4432static IrInstSrc *ir_build_panic_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *msg) {
4433 IrInstSrcPanic *instruction = ir_build_instruction<IrInstSrcPanic>(irb, scope, source_node);
4434 instruction->base.is_noreturn = true;
4435 instruction->msg = msg;
4436
4437 ir_ref_instruction(msg, irb->current_basic_block);
4438
4439 return &instruction->base;
4440}
4441
4442static IrInstGen *ir_build_panic_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *msg) {
4443 IrInstGenPanic *instruction = ir_build_inst_noreturn<IrInstGenPanic>(&ira->new_irb,
4444 source_instr->scope, source_instr->source_node);
4445 instruction->msg = msg;
4446
4447 ir_ref_inst_gen(msg);
4448
4449 return &instruction->base;
4450}
4451
4452static IrInstSrc *ir_build_tag_name_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target) {
4453 IrInstSrcTagName *instruction = ir_build_instruction<IrInstSrcTagName>(irb, scope, source_node);
4454 instruction->target = target;
4455
4456 ir_ref_instruction(target, irb->current_basic_block);
4457
4458 return &instruction->base;
4459}
4460
4461static IrInstGen *ir_build_tag_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target,
4462 ZigType *result_type)
4463{
4464 IrInstGenTagName *instruction = ir_build_inst_gen<IrInstGenTagName>(&ira->new_irb,
4465 source_instr->scope, source_instr->source_node);
4466 instruction->base.value->type = result_type;
4467 instruction->target = target;
4468
4469 ir_ref_inst_gen(target);
4470
4471 return &instruction->base;
4472}
4473
4474static IrInstSrc *ir_build_field_parent_ptr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4475 IrInstSrc *type_value, IrInstSrc *field_name, IrInstSrc *field_ptr)
4476{
4477 IrInstSrcFieldParentPtr *inst = ir_build_instruction<IrInstSrcFieldParentPtr>(
4478 irb, scope, source_node);
4479 inst->type_value = type_value;
4480 inst->field_name = field_name;
4481 inst->field_ptr = field_ptr;
4482
4483 ir_ref_instruction(type_value, irb->current_basic_block);
4484 ir_ref_instruction(field_name, irb->current_basic_block);
4485 ir_ref_instruction(field_ptr, irb->current_basic_block);
4486
4487 return &inst->base;
4488}
4489
4490static IrInstGen *ir_build_field_parent_ptr_gen(IrAnalyze *ira, IrInst *source_instr,
4491 IrInstGen *field_ptr, TypeStructField *field, ZigType *result_type)
4492{
4493 IrInstGenFieldParentPtr *inst = ir_build_inst_gen<IrInstGenFieldParentPtr>(&ira->new_irb,
4494 source_instr->scope, source_instr->source_node);
4495 inst->base.value->type = result_type;
4496 inst->field_ptr = field_ptr;
4497 inst->field = field;
4498
4499 ir_ref_inst_gen(field_ptr);
4500
4501 return &inst->base;
4502}
4503
4504static IrInstSrc *ir_build_byte_offset_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4505 IrInstSrc *type_value, IrInstSrc *field_name)
4506{
4507 IrInstSrcByteOffsetOf *instruction = ir_build_instruction<IrInstSrcByteOffsetOf>(irb, scope, source_node);
4508 instruction->type_value = type_value;
4509 instruction->field_name = field_name;
4510
4511 ir_ref_instruction(type_value, irb->current_basic_block);
4512 ir_ref_instruction(field_name, irb->current_basic_block);
4513
4514 return &instruction->base;
4515}
4516
4517static IrInstSrc *ir_build_bit_offset_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4518 IrInstSrc *type_value, IrInstSrc *field_name)
4519{
4520 IrInstSrcBitOffsetOf *instruction = ir_build_instruction<IrInstSrcBitOffsetOf>(irb, scope, source_node);
4521 instruction->type_value = type_value;
4522 instruction->field_name = field_name;
4523
4524 ir_ref_instruction(type_value, irb->current_basic_block);
4525 ir_ref_instruction(field_name, irb->current_basic_block);
4526
4527 return &instruction->base;
4528}
4529
4530static IrInstSrc *ir_build_type_info(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value) {
4531 IrInstSrcTypeInfo *instruction = ir_build_instruction<IrInstSrcTypeInfo>(irb, scope, source_node);
4532 instruction->type_value = type_value;
4533
4534 ir_ref_instruction(type_value, irb->current_basic_block);
4535
4536 return &instruction->base;
4537}
4538
4539static IrInstSrc *ir_build_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_info) {
4540 IrInstSrcType *instruction = ir_build_instruction<IrInstSrcType>(irb, scope, source_node);
4541 instruction->type_info = type_info;
4542
4543 ir_ref_instruction(type_info, irb->current_basic_block);
4544
4545 return &instruction->base;
4546}
4547
4548static IrInstSrc *ir_build_set_eval_branch_quota(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4549 IrInstSrc *new_quota)
4550{
4551 IrInstSrcSetEvalBranchQuota *instruction = ir_build_instruction<IrInstSrcSetEvalBranchQuota>(irb, scope, source_node);
4552 instruction->new_quota = new_quota;
4553
4554 ir_ref_instruction(new_quota, irb->current_basic_block);
4555
4556 return &instruction->base;
4557}
4558
4559static IrInstSrc *ir_build_align_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4560 IrInstSrc *align_bytes, IrInstSrc *target)
4561{
4562 IrInstSrcAlignCast *instruction = ir_build_instruction<IrInstSrcAlignCast>(irb, scope, source_node);
4563 instruction->align_bytes = align_bytes;
4564 instruction->target = target;
4565
4566 ir_ref_instruction(align_bytes, irb->current_basic_block);
4567 ir_ref_instruction(target, irb->current_basic_block);
4568
4569 return &instruction->base;
4570}
4571
4572static IrInstGen *ir_build_align_cast_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target,
4573 ZigType *result_type)
4574{
4575 IrInstGenAlignCast *instruction = ir_build_inst_gen<IrInstGenAlignCast>(&ira->new_irb, scope, source_node);
4576 instruction->base.value->type = result_type;
4577 instruction->target = target;
4578
4579 ir_ref_inst_gen(target);
4580
4581 return &instruction->base;
4582}
4583
4584static IrInstSrc *ir_build_resolve_result(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4585 ResultLoc *result_loc, IrInstSrc *ty)
4586{
4587 IrInstSrcResolveResult *instruction = ir_build_instruction<IrInstSrcResolveResult>(irb, scope, source_node);
4588 instruction->result_loc = result_loc;
4589 instruction->ty = ty;
4590
4591 if (ty != nullptr) ir_ref_instruction(ty, irb->current_basic_block);
4592
4593 return &instruction->base;
4594}
4595
4596static IrInstSrc *ir_build_reset_result(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4597 ResultLoc *result_loc)
4598{
4599 IrInstSrcResetResult *instruction = ir_build_instruction<IrInstSrcResetResult>(irb, scope, source_node);
4600 instruction->result_loc = result_loc;
4601 instruction->base.is_gen = true;
4602
4603 return &instruction->base;
4604}
4605
4606static IrInstSrc *ir_build_set_align_stack(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4607 IrInstSrc *align_bytes)
4608{
4609 IrInstSrcSetAlignStack *instruction = ir_build_instruction<IrInstSrcSetAlignStack>(irb, scope, source_node);
4610 instruction->align_bytes = align_bytes;
4611
4612 ir_ref_instruction(align_bytes, irb->current_basic_block);
4613
4614 return &instruction->base;
4615}
4616
4617static IrInstSrc *ir_build_arg_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4618 IrInstSrc *fn_type, IrInstSrc *arg_index, bool allow_var)
4619{
4620 IrInstSrcArgType *instruction = heap::c_allocator.create<IrInstSrcArgType>();
4621 instruction->base.id = allow_var ?
4622 IrInstSrcIdArgTypeAllowVarTrue : IrInstSrcIdArgTypeAllowVarFalse;
4623 instruction->base.base.scope = scope;
4624 instruction->base.base.source_node = source_node;
4625 instruction->base.base.debug_id = exec_next_debug_id(irb->exec);
4626 instruction->base.owner_bb = irb->current_basic_block;
4627 ir_instruction_append(irb->current_basic_block, &instruction->base);
4628
4629 instruction->fn_type = fn_type;
4630 instruction->arg_index = arg_index;
4631
4632 ir_ref_instruction(fn_type, irb->current_basic_block);
4633 ir_ref_instruction(arg_index, irb->current_basic_block);
4634
4635 return &instruction->base;
4636}
4637
4638static IrInstSrc *ir_build_error_return_trace_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4639 IrInstErrorReturnTraceOptional optional)
4640{
4641 IrInstSrcErrorReturnTrace *inst = ir_build_instruction<IrInstSrcErrorReturnTrace>(irb, scope, source_node);
4642 inst->optional = optional;
4643
4644 return &inst->base;
4645}
4646
4647static IrInstGen *ir_build_error_return_trace_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node,
4648 IrInstErrorReturnTraceOptional optional, ZigType *result_type)
4649{
4650 IrInstGenErrorReturnTrace *inst = ir_build_inst_gen<IrInstGenErrorReturnTrace>(&ira->new_irb, scope, source_node);
4651 inst->base.value->type = result_type;
4652 inst->optional = optional;
4653
4654 return &inst->base;
4655}
4656
4657static IrInstSrc *ir_build_error_union(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4658 IrInstSrc *err_set, IrInstSrc *payload)
4659{
4660 IrInstSrcErrorUnion *instruction = ir_build_instruction<IrInstSrcErrorUnion>(irb, scope, source_node);
4661 instruction->err_set = err_set;
4662 instruction->payload = payload;
4663
4664 ir_ref_instruction(err_set, irb->current_basic_block);
4665 ir_ref_instruction(payload, irb->current_basic_block);
4666
4667 return &instruction->base;
4668}
4669
4670static IrInstSrc *ir_build_atomic_rmw_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4671 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *op, IrInstSrc *operand,
4672 IrInstSrc *ordering)
4673{
4674 IrInstSrcAtomicRmw *instruction = ir_build_instruction<IrInstSrcAtomicRmw>(irb, scope, source_node);
4675 instruction->operand_type = operand_type;
4676 instruction->ptr = ptr;
4677 instruction->op = op;
4678 instruction->operand = operand;
4679 instruction->ordering = ordering;
4680
4681 ir_ref_instruction(operand_type, irb->current_basic_block);
4682 ir_ref_instruction(ptr, irb->current_basic_block);
4683 ir_ref_instruction(op, irb->current_basic_block);
4684 ir_ref_instruction(operand, irb->current_basic_block);
4685 ir_ref_instruction(ordering, irb->current_basic_block);
4686
4687 return &instruction->base;
4688}
4689
4690static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr,
4691 IrInstGen *ptr, IrInstGen *operand, AtomicRmwOp op, AtomicOrder ordering, ZigType *operand_type)
4692{
4693 IrInstGenAtomicRmw *instruction = ir_build_inst_gen<IrInstGenAtomicRmw>(&ira->new_irb, source_instr->scope, source_instr->source_node);
4694 instruction->base.value->type = operand_type;
4695 instruction->ptr = ptr;
4696 instruction->op = op;
4697 instruction->operand = operand;
4698 instruction->ordering = ordering;
4699
4700 ir_ref_inst_gen(ptr);
4701 ir_ref_inst_gen(operand);
4702
4703 return &instruction->base;
4704}
4705
4706static IrInstSrc *ir_build_atomic_load_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4707 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *ordering)
4708{
4709 IrInstSrcAtomicLoad *instruction = ir_build_instruction<IrInstSrcAtomicLoad>(irb, scope, source_node);
4710 instruction->operand_type = operand_type;
4711 instruction->ptr = ptr;
4712 instruction->ordering = ordering;
4713
4714 ir_ref_instruction(operand_type, irb->current_basic_block);
4715 ir_ref_instruction(ptr, irb->current_basic_block);
4716 ir_ref_instruction(ordering, irb->current_basic_block);
4717
4718 return &instruction->base;
4719}
4720
4721static IrInstGen *ir_build_atomic_load_gen(IrAnalyze *ira, IrInst *source_instr,
4722 IrInstGen *ptr, AtomicOrder ordering, ZigType *operand_type)
4723{
4724 IrInstGenAtomicLoad *instruction = ir_build_inst_gen<IrInstGenAtomicLoad>(&ira->new_irb,
4725 source_instr->scope, source_instr->source_node);
4726 instruction->base.value->type = operand_type;
4727 instruction->ptr = ptr;
4728 instruction->ordering = ordering;
4729
4730 ir_ref_inst_gen(ptr);
4731
4732 return &instruction->base;
4733}
4734
4735static IrInstSrc *ir_build_atomic_store_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4736 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *value, IrInstSrc *ordering)
4737{
4738 IrInstSrcAtomicStore *instruction = ir_build_instruction<IrInstSrcAtomicStore>(irb, scope, source_node);
4739 instruction->operand_type = operand_type;
4740 instruction->ptr = ptr;
4741 instruction->value = value;
4742 instruction->ordering = ordering;
4743
4744 ir_ref_instruction(operand_type, irb->current_basic_block);
4745 ir_ref_instruction(ptr, irb->current_basic_block);
4746 ir_ref_instruction(value, irb->current_basic_block);
4747 ir_ref_instruction(ordering, irb->current_basic_block);
4748
4749 return &instruction->base;
4750}
4751
4752static IrInstGen *ir_build_atomic_store_gen(IrAnalyze *ira, IrInst *source_instr,
4753 IrInstGen *ptr, IrInstGen *value, AtomicOrder ordering)
4754{
4755 IrInstGenAtomicStore *instruction = ir_build_inst_void<IrInstGenAtomicStore>(&ira->new_irb,
4756 source_instr->scope, source_instr->source_node);
4757 instruction->ptr = ptr;
4758 instruction->value = value;
4759 instruction->ordering = ordering;
4760
4761 ir_ref_inst_gen(ptr);
4762 ir_ref_inst_gen(value);
4763
4764 return &instruction->base;
4765}
4766
4767static IrInstSrc *ir_build_save_err_ret_addr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
4768 IrInstSrcSaveErrRetAddr *inst = ir_build_instruction<IrInstSrcSaveErrRetAddr>(irb, scope, source_node);
4769 return &inst->base;
4770}
4771
4772static IrInstGen *ir_build_save_err_ret_addr_gen(IrAnalyze *ira, IrInst *source_instr) {
4773 IrInstGenSaveErrRetAddr *inst = ir_build_inst_void<IrInstGenSaveErrRetAddr>(&ira->new_irb,
4774 source_instr->scope, source_instr->source_node);
4775 return &inst->base;
4776}
4777
4778static IrInstSrc *ir_build_add_implicit_return_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4779 IrInstSrc *value, ResultLocReturn *result_loc_ret)
4780{
4781 IrInstSrcAddImplicitReturnType *inst = ir_build_instruction<IrInstSrcAddImplicitReturnType>(irb, scope, source_node);
4782 inst->value = value;
4783 inst->result_loc_ret = result_loc_ret;
4784
4785 ir_ref_instruction(value, irb->current_basic_block);
4786
4787 return &inst->base;
4788}
4789
4790static IrInstSrc *ir_build_has_decl(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4791 IrInstSrc *container, IrInstSrc *name)
4792{
4793 IrInstSrcHasDecl *instruction = ir_build_instruction<IrInstSrcHasDecl>(irb, scope, source_node);
4794 instruction->container = container;
4795 instruction->name = name;
4796
4797 ir_ref_instruction(container, irb->current_basic_block);
4798 ir_ref_instruction(name, irb->current_basic_block);
4799
4800 return &instruction->base;
4801}
4802
4803static IrInstSrc *ir_build_undeclared_identifier(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *name) {
4804 IrInstSrcUndeclaredIdent *instruction = ir_build_instruction<IrInstSrcUndeclaredIdent>(irb, scope, source_node);
4805 instruction->name = name;
4806
4807 return &instruction->base;
4808}
4809
4810static IrInstSrc *ir_build_check_runtime_scope(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *scope_is_comptime, IrInstSrc *is_comptime) {
4811 IrInstSrcCheckRuntimeScope *instruction = ir_build_instruction<IrInstSrcCheckRuntimeScope>(irb, scope, source_node);
4812 instruction->scope_is_comptime = scope_is_comptime;
4813 instruction->is_comptime = is_comptime;
4814
4815 ir_ref_instruction(scope_is_comptime, irb->current_basic_block);
4816 ir_ref_instruction(is_comptime, irb->current_basic_block);
4817
4818 return &instruction->base;
4819}
4820
4821static IrInstSrc *ir_build_union_init_named_field(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4822 IrInstSrc *union_type, IrInstSrc *field_name, IrInstSrc *field_result_loc, IrInstSrc *result_loc)
4823{
4824 IrInstSrcUnionInitNamedField *instruction = ir_build_instruction<IrInstSrcUnionInitNamedField>(irb, scope, source_node);
4825 instruction->union_type = union_type;
4826 instruction->field_name = field_name;
4827 instruction->field_result_loc = field_result_loc;
4828 instruction->result_loc = result_loc;
4829
4830 ir_ref_instruction(union_type, irb->current_basic_block);
4831 ir_ref_instruction(field_name, irb->current_basic_block);
4832 ir_ref_instruction(field_result_loc, irb->current_basic_block);
4833 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block);
4834
4835 return &instruction->base;
4836}
4837
4838
4839static IrInstGen *ir_build_vector_to_array(IrAnalyze *ira, IrInst *source_instruction,
4840 ZigType *result_type, IrInstGen *vector, IrInstGen *result_loc)
4841{
4842 IrInstGenVectorToArray *instruction = ir_build_inst_gen<IrInstGenVectorToArray>(&ira->new_irb,
4843 source_instruction->scope, source_instruction->source_node);
4844 instruction->base.value->type = result_type;
4845 instruction->vector = vector;
4846 instruction->result_loc = result_loc;
4847
4848 ir_ref_inst_gen(vector);
4849 ir_ref_inst_gen(result_loc);
4850
4851 return &instruction->base;
4852}
4853
4854static IrInstGen *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInst *source_instruction,
4855 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc)
4856{
4857 IrInstGenPtrOfArrayToSlice *instruction = ir_build_inst_gen<IrInstGenPtrOfArrayToSlice>(&ira->new_irb,
4858 source_instruction->scope, source_instruction->source_node);
4859 instruction->base.value->type = result_type;
4860 instruction->operand = operand;
4861 instruction->result_loc = result_loc;
4862
4863 ir_ref_inst_gen(operand);
4864 ir_ref_inst_gen(result_loc);
4865
4866 return &instruction->base;
4867}
4868
4869static IrInstGen *ir_build_array_to_vector(IrAnalyze *ira, IrInst *source_instruction,
4870 IrInstGen *array, ZigType *result_type)
4871{
4872 IrInstGenArrayToVector *instruction = ir_build_inst_gen<IrInstGenArrayToVector>(&ira->new_irb,
4873 source_instruction->scope, source_instruction->source_node);
4874 instruction->base.value->type = result_type;
4875 instruction->array = array;
4876
4877 ir_ref_inst_gen(array);
4878
4879 return &instruction->base;
4880}
4881
4882static IrInstGen *ir_build_assert_zero(IrAnalyze *ira, IrInst *source_instruction,
4883 IrInstGen *target)
4884{
4885 IrInstGenAssertZero *instruction = ir_build_inst_gen<IrInstGenAssertZero>(&ira->new_irb,
4886 source_instruction->scope, source_instruction->source_node);
4887 instruction->base.value->type = ira->codegen->builtin_types.entry_void;
4888 instruction->target = target;
4889
4890 ir_ref_inst_gen(target);
4891
4892 return &instruction->base;
4893}
4894
4895static IrInstGen *ir_build_assert_non_null(IrAnalyze *ira, IrInst *source_instruction,
4896 IrInstGen *target)
4897{
4898 IrInstGenAssertNonNull *instruction = ir_build_inst_gen<IrInstGenAssertNonNull>(&ira->new_irb,
4899 source_instruction->scope, source_instruction->source_node);
4900 instruction->base.value->type = ira->codegen->builtin_types.entry_void;
4901 instruction->target = target;
4902
4903 ir_ref_inst_gen(target);
4904
4905 return &instruction->base;
4906}
4907
4908static IrInstSrc *ir_build_alloca_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4909 IrInstSrc *align, const char *name_hint, IrInstSrc *is_comptime)
4910{
4911 IrInstSrcAlloca *instruction = ir_build_instruction<IrInstSrcAlloca>(irb, scope, source_node);
4912 instruction->base.is_gen = true;
4913 instruction->align = align;
4914 instruction->name_hint = name_hint;
4915 instruction->is_comptime = is_comptime;
4916
4917 if (align != nullptr) ir_ref_instruction(align, irb->current_basic_block);
4918 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block);
4919
4920 return &instruction->base;
4921}
4922
4923static IrInstGenAlloca *ir_build_alloca_gen(IrAnalyze *ira, IrInst *source_instruction,
4924 uint32_t align, const char *name_hint)
4925{
4926 IrInstGenAlloca *instruction = ir_create_inst_gen<IrInstGenAlloca>(&ira->new_irb,
4927 source_instruction->scope, source_instruction->source_node);
4928 instruction->align = align;
4929 instruction->name_hint = name_hint;
4930
4931 return instruction;
4932}
4933
4934static IrInstSrc *ir_build_end_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4935 IrInstSrc *value, ResultLoc *result_loc)
4936{
4937 IrInstSrcEndExpr *instruction = ir_build_instruction<IrInstSrcEndExpr>(irb, scope, source_node);
4938 instruction->base.is_gen = true;
4939 instruction->value = value;
4940 instruction->result_loc = result_loc;
4941
4942 ir_ref_instruction(value, irb->current_basic_block);
4943
4944 return &instruction->base;
4945}
4946
4947static IrInstSrcSuspendBegin *ir_build_suspend_begin_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
4948 return ir_build_instruction<IrInstSrcSuspendBegin>(irb, scope, source_node);
4949}
4950
4951static IrInstGen *ir_build_suspend_begin_gen(IrAnalyze *ira, IrInst *source_instr) {
4952 IrInstGenSuspendBegin *inst = ir_build_inst_void<IrInstGenSuspendBegin>(&ira->new_irb,
4953 source_instr->scope, source_instr->source_node);
4954 return &inst->base;
4955}
4956
4957static IrInstSrc *ir_build_suspend_finish_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4958 IrInstSrcSuspendBegin *begin)
4959{
4960 IrInstSrcSuspendFinish *inst = ir_build_instruction<IrInstSrcSuspendFinish>(irb, scope, source_node);
4961 inst->begin = begin;
4962
4963 ir_ref_instruction(&begin->base, irb->current_basic_block);
4964
4965 return &inst->base;
4966}
4967
4968static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSuspendBegin *begin) {
4969 IrInstGenSuspendFinish *inst = ir_build_inst_void<IrInstGenSuspendFinish>(&ira->new_irb,
4970 source_instr->scope, source_instr->source_node);
4971 inst->begin = begin;
4972
4973 ir_ref_inst_gen(&begin->base);
4974
4975 return &inst->base;
4976}
4977
4978static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4979 IrInstSrc *frame, ResultLoc *result_loc, bool is_nosuspend)
4980{
4981 IrInstSrcAwait *instruction = ir_build_instruction<IrInstSrcAwait>(irb, scope, source_node);
4982 instruction->frame = frame;
4983 instruction->result_loc = result_loc;
4984 instruction->is_nosuspend = is_nosuspend;
4985
4986 ir_ref_instruction(frame, irb->current_basic_block);
4987
4988 return &instruction->base;
4989}
4990
4991static IrInstGenAwait *ir_build_await_gen(IrAnalyze *ira, IrInst *source_instruction,
4992 IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc, bool is_nosuspend)
4993{
4994 IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb,
4995 source_instruction->scope, source_instruction->source_node);
4996 instruction->base.value->type = result_type;
4997 instruction->frame = frame;
4998 instruction->result_loc = result_loc;
4999 instruction->is_nosuspend = is_nosuspend;
5000
5001 ir_ref_inst_gen(frame);
5002 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
5003
5004 return instruction;
5005}
5006
5007static IrInstSrc *ir_build_resume_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *frame) {
5008 IrInstSrcResume *instruction = ir_build_instruction<IrInstSrcResume>(irb, scope, source_node);
5009 instruction->frame = frame;
5010
5011 ir_ref_instruction(frame, irb->current_basic_block);
5012
5013 return &instruction->base;
5014}
5015
5016static IrInstGen *ir_build_resume_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *frame) {
5017 IrInstGenResume *instruction = ir_build_inst_void<IrInstGenResume>(&ira->new_irb,
5018 source_instr->scope, source_instr->source_node);
5019 instruction->frame = frame;
5020
5021 ir_ref_inst_gen(frame);
5022
5023 return &instruction->base;
5024}
5025
5026static IrInstSrcSpillBegin *ir_build_spill_begin_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
5027 IrInstSrc *operand, SpillId spill_id)
5028{
5029 IrInstSrcSpillBegin *instruction = ir_build_instruction<IrInstSrcSpillBegin>(irb, scope, source_node);
5030 instruction->operand = operand;
5031 instruction->spill_id = spill_id;
5032
5033 ir_ref_instruction(operand, irb->current_basic_block);
5034
5035 return instruction;
5036}
5037
5038static IrInstGen *ir_build_spill_begin_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand,
5039 SpillId spill_id)
5040{
5041 IrInstGenSpillBegin *instruction = ir_build_inst_void<IrInstGenSpillBegin>(&ira->new_irb,
5042 source_instr->scope, source_instr->source_node);
5043 instruction->operand = operand;
5044 instruction->spill_id = spill_id;
5045
5046 ir_ref_inst_gen(operand);
5047
5048 return &instruction->base;
5049}
5050
5051static IrInstSrc *ir_build_spill_end_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
5052 IrInstSrcSpillBegin *begin)
5053{
5054 IrInstSrcSpillEnd *instruction = ir_build_instruction<IrInstSrcSpillEnd>(irb, scope, source_node);
5055 instruction->begin = begin;
5056
5057 ir_ref_instruction(&begin->base, irb->current_basic_block);
5058
5059 return &instruction->base;
5060}
5061
5062static IrInstGen *ir_build_spill_end_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSpillBegin *begin,
5063 ZigType *result_type)
5064{
5065 IrInstGenSpillEnd *instruction = ir_build_inst_gen<IrInstGenSpillEnd>(&ira->new_irb,
5066 source_instr->scope, source_instr->source_node);
5067 instruction->base.value->type = result_type;
5068 instruction->begin = begin;
5069
5070 ir_ref_inst_gen(&begin->base);
5071
5072 return &instruction->base;
5073}
5074
5075static IrInstGen *ir_build_vector_extract_elem(IrAnalyze *ira, IrInst *source_instruction,
5076 IrInstGen *vector, IrInstGen *index)
5077{
5078 IrInstGenVectorExtractElem *instruction = ir_build_inst_gen<IrInstGenVectorExtractElem>(
5079 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
5080 instruction->base.value->type = vector->value->type->data.vector.elem_type;
5081 instruction->vector = vector;
5082 instruction->index = index;
5083
5084 ir_ref_inst_gen(vector);
5085 ir_ref_inst_gen(index);
5086
5087 return &instruction->base;
5088}
5089
5090static IrInstSrc *ir_build_wasm_memory_size_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *index) {
5091 IrInstSrcWasmMemorySize *instruction = ir_build_instruction<IrInstSrcWasmMemorySize>(irb, scope, source_node);
5092 instruction->index = index;
5093
5094 ir_ref_instruction(index, irb->current_basic_block);
5095
5096 return &instruction->base;
5097}
5098
5099static IrInstGen *ir_build_wasm_memory_size_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *index) {
5100 IrInstGenWasmMemorySize *instruction = ir_build_inst_gen<IrInstGenWasmMemorySize>(&ira->new_irb,
5101 source_instr->scope, source_instr->source_node);
5102 instruction->base.value->type = ira->codegen->builtin_types.entry_u32;
5103 instruction->index = index;
5104
5105 ir_ref_inst_gen(index);
5106
5107 return &instruction->base;
5108}
5109
5110static IrInstSrc *ir_build_wasm_memory_grow_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *index, IrInstSrc *delta) {
5111 IrInstSrcWasmMemoryGrow *instruction = ir_build_instruction<IrInstSrcWasmMemoryGrow>(irb, scope, source_node);
5112 instruction->index = index;
5113 instruction->delta = delta;
5114
5115 ir_ref_instruction(index, irb->current_basic_block);
5116 ir_ref_instruction(delta, irb->current_basic_block);
5117
5118 return &instruction->base;
5119}
5120
5121static IrInstGen *ir_build_wasm_memory_grow_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *index, IrInstGen *delta) {
5122 IrInstGenWasmMemoryGrow *instruction = ir_build_inst_gen<IrInstGenWasmMemoryGrow>(&ira->new_irb,
5123 source_instr->scope, source_instr->source_node);
5124 instruction->base.value->type = ira->codegen->builtin_types.entry_i32;
5125 instruction->index = index;
5126 instruction->delta = delta;
5127
5128 ir_ref_inst_gen(index);
5129 ir_ref_inst_gen(delta);
5130
5131 return &instruction->base;
5132}
5133
5134static IrInstSrc *ir_build_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
5135 IrInstSrcSrc *instruction = ir_build_instruction<IrInstSrcSrc>(irb, scope, source_node);
5136
5137 return &instruction->base;
5138}
5139
5140static void ir_count_defers(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
5141 results[ReturnKindUnconditional] = 0;
5142 results[ReturnKindError] = 0;
5143
5144 Scope *scope = inner_scope;
5145
5146 while (scope != outer_scope) {
5147 assert(scope);
5148 switch (scope->id) {
5149 case ScopeIdDefer: {
5150 AstNode *defer_node = scope->source_node;
5151 assert(defer_node->type == NodeTypeDefer);
5152 ReturnKind defer_kind = defer_node->data.defer.kind;
5153 results[defer_kind] += 1;
5154 scope = scope->parent;
5155 continue;
5156 }
5157 case ScopeIdDecls:
5158 case ScopeIdFnDef:
5159 return;
5160 case ScopeIdBlock:
5161 case ScopeIdVarDecl:
5162 case ScopeIdLoop:
5163 case ScopeIdSuspend:
5164 case ScopeIdCompTime:
5165 case ScopeIdNoSuspend:
5166 case ScopeIdRuntime:
5167 case ScopeIdTypeOf:
5168 case ScopeIdExpr:
5169 scope = scope->parent;
5170 continue;
5171 case ScopeIdDeferExpr:
5172 case ScopeIdCImport:
5173 zig_unreachable();
5174 }
5175 }
5176}
5177
5178static IrInstSrc *ir_mark_gen(IrInstSrc *instruction) {
5179 instruction->is_gen = true;
5180 return instruction;
5181}
5182
5183static bool ir_gen_defers_for_block(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_scope, bool *is_noreturn, IrInstSrc *err_value) {
5184 Scope *scope = inner_scope;
5185 if (is_noreturn != nullptr) *is_noreturn = false;
5186 while (scope != outer_scope) {
5187 if (!scope)
5188 return true;
5189
5190 switch (scope->id) {
5191 case ScopeIdDefer: {
5192 AstNode *defer_node = scope->source_node;
5193 assert(defer_node->type == NodeTypeDefer);
5194 ReturnKind defer_kind = defer_node->data.defer.kind;
5195 AstNode *defer_expr_node = defer_node->data.defer.expr;
5196 AstNode *defer_var_node = defer_node->data.defer.err_payload;
5197
5198 if (defer_kind == ReturnKindError && err_value == nullptr) {
5199 // This is an `errdefer` but we're generating code for a
5200 // `return` that doesn't return an error, skip it
5201 scope = scope->parent;
5202 continue;
5203 }
5204
5205 Scope *defer_expr_scope = defer_node->data.defer.expr_scope;
5206 if (defer_var_node != nullptr) {
5207 assert(defer_kind == ReturnKindError);
5208 assert(defer_var_node->type == NodeTypeSymbol);
5209 Buf *var_name = defer_var_node->data.symbol_expr.symbol;
5210
5211 if (defer_expr_node->type == NodeTypeUnreachable) {
5212 add_node_error(irb->codegen, defer_var_node,
5213 buf_sprintf("unused variable: '%s'", buf_ptr(var_name)));
5214 return false;
5215 }
5216
5217 IrInstSrc *is_comptime;
5218 if (ir_should_inline(irb->exec, defer_expr_scope)) {
5219 is_comptime = ir_build_const_bool(irb, defer_expr_scope,
5220 defer_expr_node, true);
5221 } else {
5222 is_comptime = ir_build_test_comptime(irb, defer_expr_scope,
5223 defer_expr_node, err_value);
5224 }
5225
5226 ZigVar *err_var = ir_create_var(irb, defer_var_node, defer_expr_scope,
5227 var_name, true, true, false, is_comptime);
5228 build_decl_var_and_init(irb, defer_expr_scope, defer_var_node, err_var, err_value,
5229 buf_ptr(var_name), is_comptime);
5230
5231 defer_expr_scope = err_var->child_scope;
5232 }
5233
5234 IrInstSrc *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope);
5235 if (defer_expr_value == irb->codegen->invalid_inst_src)
5236 return irb->codegen->invalid_inst_src;
5237
5238 if (defer_expr_value->is_noreturn) {
5239 if (is_noreturn != nullptr) *is_noreturn = true;
5240 } else {
5241 ir_mark_gen(ir_build_check_statement_is_void(irb, defer_expr_scope, defer_expr_node,
5242 defer_expr_value));
5243 }
5244 scope = scope->parent;
5245 continue;
5246 }
5247 case ScopeIdDecls:
5248 case ScopeIdFnDef:
5249 return true;
5250 case ScopeIdBlock:
5251 case ScopeIdVarDecl:
5252 case ScopeIdLoop:
5253 case ScopeIdSuspend:
5254 case ScopeIdCompTime:
5255 case ScopeIdNoSuspend:
5256 case ScopeIdRuntime:
5257 case ScopeIdTypeOf:
5258 case ScopeIdExpr:
5259 scope = scope->parent;
5260 continue;
5261 case ScopeIdDeferExpr:
5262 case ScopeIdCImport:
5263 zig_unreachable();
5264 }
5265 }
5266 return true;
5267}
5268
5269static void ir_set_cursor_at_end_gen(IrBuilderGen *irb, IrBasicBlockGen *basic_block) {
5270 assert(basic_block);
5271 irb->current_basic_block = basic_block;
5272}
5273
5274static void ir_set_cursor_at_end(IrBuilderSrc *irb, IrBasicBlockSrc *basic_block) {
5275 assert(basic_block);
5276 irb->current_basic_block = basic_block;
5277}
5278
5279static void ir_append_basic_block_gen(IrBuilderGen *irb, IrBasicBlockGen *bb) {
5280 assert(!bb->already_appended);
5281 bb->already_appended = true;
5282 irb->exec->basic_block_list.append(bb);
5283}
5284
5285static void ir_set_cursor_at_end_and_append_block_gen(IrBuilderGen *irb, IrBasicBlockGen *basic_block) {
5286 ir_append_basic_block_gen(irb, basic_block);
5287 ir_set_cursor_at_end_gen(irb, basic_block);
5288}
5289
5290static void ir_set_cursor_at_end_and_append_block(IrBuilderSrc *irb, IrBasicBlockSrc *basic_block) {
5291 basic_block->index = irb->exec->basic_block_list.length;
5292 irb->exec->basic_block_list.append(basic_block);
5293 ir_set_cursor_at_end(irb, basic_block);
5294}
5295
5296static ScopeSuspend *get_scope_suspend(Scope *scope) {
5297 while (scope) {
5298 if (scope->id == ScopeIdSuspend)
5299 return (ScopeSuspend *)scope;
5300 if (scope->id == ScopeIdFnDef)
5301 return nullptr;
5302
5303 scope = scope->parent;
5304 }
5305 return nullptr;
5306}
5307
5308static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) {
5309 while (scope) {
5310 if (scope->id == ScopeIdDeferExpr)
5311 return (ScopeDeferExpr *)scope;
5312 if (scope->id == ScopeIdFnDef)
5313 return nullptr;
5314
5315 scope = scope->parent;
5316 }
5317 return nullptr;
5318}
5319
5320static IrInstSrc *ir_gen_return(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
5321 assert(node->type == NodeTypeReturnExpr);
5322
5323 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope);
5324 if (scope_defer_expr) {
5325 if (!scope_defer_expr->reported_err) {
5326 add_node_error(irb->codegen, node, buf_sprintf("cannot return from defer expression"));
5327 scope_defer_expr->reported_err = true;
5328 }
5329 return irb->codegen->invalid_inst_src;
5330 }
5331
5332 Scope *outer_scope = irb->exec->begin_scope;
5333
5334 AstNode *expr_node = node->data.return_expr.expr;
5335 switch (node->data.return_expr.kind) {
5336 case ReturnKindUnconditional:
5337 {
5338 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
5339 result_loc_ret->base.id = ResultLocIdReturn;
5340 ir_build_reset_result(irb, scope, node, &result_loc_ret->base);
5341
5342 IrInstSrc *return_value;
5343 if (expr_node) {
5344 // Temporarily set this so that if we return a type it gets the name of the function
5345 ZigFn *prev_name_fn = irb->exec->name_fn;
5346 irb->exec->name_fn = exec_fn_entry(irb->exec);
5347 return_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_ret->base);
5348 irb->exec->name_fn = prev_name_fn;
5349 if (return_value == irb->codegen->invalid_inst_src)
5350 return irb->codegen->invalid_inst_src;
5351 } else {
5352 return_value = ir_build_const_void(irb, scope, node);
5353 ir_build_end_expr(irb, scope, node, return_value, &result_loc_ret->base);
5354 }
5355
5356 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value, result_loc_ret));
5357
5358 size_t defer_counts[2];
5359 ir_count_defers(irb, scope, outer_scope, defer_counts);
5360 bool have_err_defers = defer_counts[ReturnKindError] > 0;
5361 if (!have_err_defers && !irb->codegen->have_err_ret_tracing) {
5362 // only generate unconditional defers
5363 if (!ir_gen_defers_for_block(irb, scope, outer_scope, nullptr, nullptr))
5364 return irb->codegen->invalid_inst_src;
5365 IrInstSrc *result = ir_build_return_src(irb, scope, node, nullptr);
5366 result_loc_ret->base.source_instruction = result;
5367 return result;
5368 }
5369 bool should_inline = ir_should_inline(irb->exec, scope);
5370
5371 IrBasicBlockSrc *err_block = ir_create_basic_block(irb, scope, "ErrRetErr");
5372 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk");
5373
5374 IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node, return_value, false, true);
5375
5376 IrInstSrc *is_comptime;
5377 if (should_inline) {
5378 is_comptime = ir_build_const_bool(irb, scope, node, should_inline);
5379 } else {
5380 is_comptime = ir_build_test_comptime(irb, scope, node, is_err);
5381 }
5382
5383 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime));
5384 IrBasicBlockSrc *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt");
5385
5386 ir_set_cursor_at_end_and_append_block(irb, err_block);
5387 if (!ir_gen_defers_for_block(irb, scope, outer_scope, nullptr, return_value))
5388 return irb->codegen->invalid_inst_src;
5389 if (irb->codegen->have_err_ret_tracing && !should_inline) {
5390 ir_build_save_err_ret_addr_src(irb, scope, node);
5391 }
5392 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);
5393
5394 ir_set_cursor_at_end_and_append_block(irb, ok_block);
5395 if (!ir_gen_defers_for_block(irb, scope, outer_scope, nullptr, nullptr))
5396 return irb->codegen->invalid_inst_src;
5397 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime);
5398
5399 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block);
5400 IrInstSrc *result = ir_build_return_src(irb, scope, node, nullptr);
5401 result_loc_ret->base.source_instruction = result;
5402 return result;
5403 }
5404 case ReturnKindError:
5405 {
5406 assert(expr_node);
5407 IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
5408 if (err_union_ptr == irb->codegen->invalid_inst_src)
5409 return irb->codegen->invalid_inst_src;
5410 IrInstSrc *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr, true, false);
5411
5412 IrBasicBlockSrc *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn");
5413 IrBasicBlockSrc *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue");
5414 IrInstSrc *is_comptime;
5415 bool should_inline = ir_should_inline(irb->exec, scope);
5416 if (should_inline) {
5417 is_comptime = ir_build_const_bool(irb, scope, node, true);
5418 } else {
5419 is_comptime = ir_build_test_comptime(irb, scope, node, is_err_val);
5420 }
5421 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime));
5422
5423 ir_set_cursor_at_end_and_append_block(irb, return_block);
5424 IrInstSrc *err_val_ptr = ir_build_unwrap_err_code_src(irb, scope, node, err_union_ptr);
5425 IrInstSrc *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr);
5426 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val, nullptr));
5427 IrInstSrcSpillBegin *spill_begin = ir_build_spill_begin_src(irb, scope, node, err_val,
5428 SpillIdRetErrCode);
5429 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
5430 result_loc_ret->base.id = ResultLocIdReturn;
5431 ir_build_reset_result(irb, scope, node, &result_loc_ret->base);
5432 ir_build_end_expr(irb, scope, node, err_val, &result_loc_ret->base);
5433
5434 bool is_noreturn = false;
5435 if (!ir_gen_defers_for_block(irb, scope, outer_scope, &is_noreturn, err_val)) {
5436 return irb->codegen->invalid_inst_src;
5437 }
5438 if (!is_noreturn) {
5439 if (irb->codegen->have_err_ret_tracing && !should_inline) {
5440 ir_build_save_err_ret_addr_src(irb, scope, node);
5441 }
5442 err_val = ir_build_spill_end_src(irb, scope, node, spill_begin);
5443 IrInstSrc *ret_inst = ir_build_return_src(irb, scope, node, err_val);
5444 result_loc_ret->base.source_instruction = ret_inst;
5445 }
5446
5447 ir_set_cursor_at_end_and_append_block(irb, continue_block);
5448 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(irb, scope, node, err_union_ptr, false, false);
5449 if (lval == LValPtr)
5450 return unwrapped_ptr;
5451 else
5452 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, unwrapped_ptr), result_loc);
5453 }
5454 }
5455 zig_unreachable();
5456}
5457
5458static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
5459 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime,
5460 bool skip_name_check)
5461{
5462 ZigVar *variable_entry = heap::c_allocator.create<ZigVar>();
5463 variable_entry->parent_scope = parent_scope;
5464 variable_entry->shadowable = is_shadowable;
5465 variable_entry->is_comptime = is_comptime;
5466 variable_entry->src_arg_index = SIZE_MAX;
5467 variable_entry->const_value = codegen->pass1_arena->create<ZigValue>();
5468
5469 if (is_comptime != nullptr) {
5470 is_comptime->base.ref_count += 1;
5471 }
5472
5473 if (name) {
5474 variable_entry->name = strdup(buf_ptr(name));
5475
5476 if (!skip_name_check) {
5477 ZigVar *existing_var = find_variable(codegen, parent_scope, name, nullptr);
5478 if (existing_var && !existing_var->shadowable) {
5479 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) {
5480 ErrorMsg *msg = add_node_error(codegen, node,
5481 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
5482 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
5483 }
5484 variable_entry->var_type = codegen->builtin_types.entry_invalid;
5485 } else {
5486 ZigType *type;
5487 if (get_primitive_type(codegen, name, &type) != ErrorPrimitiveTypeNotFound) {
5488 add_node_error(codegen, node,
5489 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name)));
5490 variable_entry->var_type = codegen->builtin_types.entry_invalid;
5491 } else {
5492 Tld *tld = find_decl(codegen, parent_scope, name);
5493 if (tld != nullptr) {
5494 bool want_err_msg = true;
5495 if (tld->id == TldIdVar) {
5496 ZigVar *var = reinterpret_cast<TldVar *>(tld)->var;
5497 if (var != nullptr && var->var_type != nullptr && type_is_invalid(var->var_type)) {
5498 want_err_msg = false;
5499 }
5500 }
5501 if (want_err_msg) {
5502 ErrorMsg *msg = add_node_error(codegen, node,
5503 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
5504 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here"));
5505 }
5506 variable_entry->var_type = codegen->builtin_types.entry_invalid;
5507 }
5508 }
5509 }
5510 }
5511 } else {
5512 assert(is_shadowable);
5513 // TODO make this name not actually be in scope. user should be able to make a variable called "_anon"
5514 // might already be solved, let's just make sure it has test coverage
5515 // maybe we put a prefix on this so the debug info doesn't clobber user debug info for same named variables
5516 variable_entry->name = "_anon";
5517 }
5518
5519 variable_entry->src_is_const = src_is_const;
5520 variable_entry->gen_is_const = gen_is_const;
5521 variable_entry->decl_node = node;
5522 variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry);
5523
5524 return variable_entry;
5525}
5526
5527// Set name to nullptr to make the variable anonymous (not visible to programmer).
5528// After you call this function var->child_scope has the variable in scope
5529static ZigVar *ir_create_var(IrBuilderSrc *irb, AstNode *node, Scope *scope, Buf *name,
5530 bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime)
5531{
5532 bool is_underscored = name ? buf_eql_str(name, "_") : false;
5533 ZigVar *var = create_local_var(irb->codegen, node, scope,
5534 (is_underscored ? nullptr : name), src_is_const, gen_is_const,
5535 (is_underscored ? true : is_shadowable), is_comptime, false);
5536 assert(var->child_scope);
5537 return var;
5538}
5539
5540static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) {
5541 ResultLocPeer *result = heap::c_allocator.create<ResultLocPeer>();
5542 result->base.id = ResultLocIdPeer;
5543 result->base.source_instruction = peer_parent->base.source_instruction;
5544 result->parent = peer_parent;
5545 result->base.allow_write_through_const = peer_parent->parent->allow_write_through_const;
5546 return result;
5547}
5548
5549static bool is_duplicate_label(CodeGen *g, Scope *scope, AstNode *node, Buf *name) {
5550 if (name == nullptr) return false;
5551
5552 for (;;) {
5553 if (scope == nullptr || scope->id == ScopeIdFnDef) {
5554 break;
5555 } else if (scope->id == ScopeIdBlock || scope->id == ScopeIdLoop) {
5556 Buf *this_block_name = scope->id == ScopeIdBlock ? ((ScopeBlock *)scope)->name : ((ScopeLoop *)scope)->name;
5557 if (this_block_name != nullptr && buf_eql_buf(name, this_block_name)) {
5558 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("redeclaration of label '%s'", buf_ptr(name)));
5559 add_error_note(g, msg, scope->source_node, buf_sprintf("previous declaration is here"));
5560 return true;
5561 }
5562 }
5563 scope = scope->parent;
5564 }
5565 return false;
5566}
5567
5568static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *block_node, LVal lval,
5569 ResultLoc *result_loc)
5570{
5571 assert(block_node->type == NodeTypeBlock);
5572
5573 ZigList<IrInstSrc *> incoming_values = {0};
5574 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
5575
5576 if (is_duplicate_label(irb->codegen, parent_scope, block_node, block_node->data.block.name))
5577 return irb->codegen->invalid_inst_src;
5578
5579 ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope);
5580
5581 Scope *outer_block_scope = &scope_block->base;
5582 Scope *child_scope = outer_block_scope;
5583
5584 ZigFn *fn_entry = scope_fn_entry(parent_scope);
5585 if (fn_entry && fn_entry->child_scope == parent_scope) {
5586 fn_entry->def_scope = scope_block;
5587 }
5588
5589 if (block_node->data.block.statements.length == 0) {
5590 if (scope_block->name != nullptr) {
5591 add_node_error(irb->codegen, block_node, buf_sprintf("unused block label"));
5592 }
5593 // {}
5594 return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc);
5595 }
5596
5597 if (block_node->data.block.name != nullptr) {
5598 scope_block->lval = lval;
5599 scope_block->incoming_blocks = &incoming_blocks;
5600 scope_block->incoming_values = &incoming_values;
5601 scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd");
5602 scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node,
5603 ir_should_inline(irb->exec, parent_scope));
5604
5605 scope_block->peer_parent = heap::c_allocator.create<ResultLocPeerParent>();
5606 scope_block->peer_parent->base.id = ResultLocIdPeerParent;
5607 scope_block->peer_parent->base.source_instruction = scope_block->is_comptime;
5608 scope_block->peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const;
5609 scope_block->peer_parent->end_bb = scope_block->end_block;
5610 scope_block->peer_parent->is_comptime = scope_block->is_comptime;
5611 scope_block->peer_parent->parent = result_loc;
5612 ir_build_reset_result(irb, parent_scope, block_node, &scope_block->peer_parent->base);
5613 }
5614
5615 bool is_continuation_unreachable = false;
5616 bool found_invalid_inst = false;
5617 IrInstSrc *noreturn_return_value = nullptr;
5618 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) {
5619 AstNode *statement_node = block_node->data.block.statements.at(i);
5620
5621 IrInstSrc *statement_value = ir_gen_node(irb, statement_node, child_scope);
5622 if (statement_value == irb->codegen->invalid_inst_src) {
5623 // keep generating all the elements of the block in case of error,
5624 // we want to collect other compile errors
5625 found_invalid_inst = true;
5626 continue;
5627 }
5628
5629 is_continuation_unreachable = instr_is_unreachable(statement_value);
5630 if (is_continuation_unreachable) {
5631 // keep the last noreturn statement value around in case we need to return it
5632 noreturn_return_value = statement_value;
5633 }
5634 // This logic must be kept in sync with
5635 // [STMT_EXPR_TEST_THING] <--- (search this token)
5636 if (statement_node->type == NodeTypeDefer) {
5637 // defer starts a new scope
5638 child_scope = statement_node->data.defer.child_scope;
5639 assert(child_scope);
5640 } else if (statement_value->id == IrInstSrcIdDeclVar) {
5641 // variable declarations start a new scope
5642 IrInstSrcDeclVar *decl_var_instruction = (IrInstSrcDeclVar *)statement_value;
5643 child_scope = decl_var_instruction->var->child_scope;
5644 } else if (!is_continuation_unreachable) {
5645 // this statement's value must be void
5646 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value));
5647 }
5648 }
5649
5650 if (scope_block->name != nullptr && scope_block->name_used == false) {
5651 add_node_error(irb->codegen, block_node, buf_sprintf("unused block label"));
5652 }
5653
5654 if (found_invalid_inst)
5655 return irb->codegen->invalid_inst_src;
5656
5657 if (is_continuation_unreachable) {
5658 assert(noreturn_return_value != nullptr);
5659 if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) {
5660 return noreturn_return_value;
5661 }
5662
5663 if (scope_block->peer_parent != nullptr && scope_block->peer_parent->peers.length != 0) {
5664 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block;
5665 }
5666 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block);
5667 IrInstSrc *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length,
5668 incoming_blocks.items, incoming_values.items, scope_block->peer_parent);
5669 return ir_expr_wrap(irb, parent_scope, phi, result_loc);
5670 } else {
5671 incoming_blocks.append(irb->current_basic_block);
5672 IrInstSrc *else_expr_result = ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node));
5673
5674 if (scope_block->peer_parent != nullptr) {
5675 ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent);
5676 scope_block->peer_parent->peers.append(peer_result);
5677 ir_build_end_expr(irb, parent_scope, block_node, else_expr_result, &peer_result->base);
5678
5679 if (scope_block->peer_parent->peers.length != 0) {
5680 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block;
5681 }
5682 }
5683
5684 incoming_values.append(else_expr_result);
5685 }
5686
5687 bool is_return_from_fn = block_node == irb->main_block_node;
5688 if (!is_return_from_fn) {
5689 if (!ir_gen_defers_for_block(irb, child_scope, outer_block_scope, nullptr, nullptr))
5690 return irb->codegen->invalid_inst_src;
5691 }
5692
5693 IrInstSrc *result;
5694 if (block_node->data.block.name != nullptr) {
5695 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime));
5696 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block);
5697 IrInstSrc *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length,
5698 incoming_blocks.items, incoming_values.items, scope_block->peer_parent);
5699 result = ir_expr_wrap(irb, parent_scope, phi, result_loc);
5700 } else {
5701 IrInstSrc *void_inst = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node));
5702 result = ir_lval_wrap(irb, parent_scope, void_inst, lval, result_loc);
5703 }
5704 if (!is_return_from_fn)
5705 return result;
5706
5707 // no need for save_err_ret_addr because this cannot return error
5708 // only generate unconditional defers
5709
5710 ir_mark_gen(ir_build_add_implicit_return_type(irb, child_scope, block_node, result, nullptr));
5711 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
5712 result_loc_ret->base.id = ResultLocIdReturn;
5713 ir_build_reset_result(irb, parent_scope, block_node, &result_loc_ret->base);
5714 ir_mark_gen(ir_build_end_expr(irb, parent_scope, block_node, result, &result_loc_ret->base));
5715 if (!ir_gen_defers_for_block(irb, child_scope, outer_block_scope, nullptr, nullptr))
5716 return irb->codegen->invalid_inst_src;
5717 return ir_mark_gen(ir_build_return_src(irb, child_scope, result->base.source_node, result));
5718}
5719
5720static IrInstSrc *ir_gen_bin_op_id(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrBinOp op_id) {
5721 Scope *inner_scope = scope;
5722 if (op_id == IrBinOpArrayCat || op_id == IrBinOpArrayMult) {
5723 inner_scope = create_comptime_scope(irb->codegen, node, scope);
5724 }
5725
5726 IrInstSrc *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, inner_scope);
5727 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, inner_scope);
5728
5729 if (op1 == irb->codegen->invalid_inst_src || op2 == irb->codegen->invalid_inst_src)
5730 return irb->codegen->invalid_inst_src;
5731
5732 return ir_build_bin_op(irb, scope, node, op_id, op1, op2, true);
5733}
5734
5735static IrInstSrc *ir_gen_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
5736 IrInstSrc *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope);
5737 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
5738
5739 if (op1 == irb->codegen->invalid_inst_src || op2 == irb->codegen->invalid_inst_src)
5740 return irb->codegen->invalid_inst_src;
5741
5742 // TODO only pass type_name when the || operator is the top level AST node in the var decl expr
5743 Buf bare_name = BUF_INIT;
5744 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error", scope, node, &bare_name);
5745
5746 return ir_build_merge_err_sets(irb, scope, node, op1, op2, type_name);
5747}
5748
5749static IrInstSrc *ir_gen_assign(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
5750 IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValAssign, nullptr);
5751 if (lvalue == irb->codegen->invalid_inst_src)
5752 return irb->codegen->invalid_inst_src;
5753
5754 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
5755 result_loc_inst->base.id = ResultLocIdInstruction;
5756 result_loc_inst->base.source_instruction = lvalue;
5757 ir_ref_instruction(lvalue, irb->current_basic_block);
5758 ir_build_reset_result(irb, scope, node, &result_loc_inst->base);
5759
5760 IrInstSrc *rvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op2, scope, LValNone,
5761 &result_loc_inst->base);
5762 if (rvalue == irb->codegen->invalid_inst_src)
5763 return irb->codegen->invalid_inst_src;
5764
5765 return ir_build_const_void(irb, scope, node);
5766}
5767
5768static IrInstSrc *ir_gen_assign_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrBinOp op_id) {
5769 IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValAssign, nullptr);
5770 if (lvalue == irb->codegen->invalid_inst_src)
5771 return lvalue;
5772 IrInstSrc *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue);
5773 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
5774 if (op2 == irb->codegen->invalid_inst_src)
5775 return op2;
5776 IrInstSrc *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true);
5777 ir_build_store_ptr(irb, scope, node, lvalue, result);
5778 return ir_build_const_void(irb, scope, node);
5779}
5780
5781static IrInstSrc *ir_gen_bool_or(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
5782 assert(node->type == NodeTypeBinOpExpr);
5783
5784 IrInstSrc *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope);
5785 if (val1 == irb->codegen->invalid_inst_src)
5786 return irb->codegen->invalid_inst_src;
5787 IrBasicBlockSrc *post_val1_block = irb->current_basic_block;
5788
5789 IrInstSrc *is_comptime;
5790 if (ir_should_inline(irb->exec, scope)) {
5791 is_comptime = ir_build_const_bool(irb, scope, node, true);
5792 } else {
5793 is_comptime = ir_build_test_comptime(irb, scope, node, val1);
5794 }
5795
5796 // block for when val1 == false
5797 IrBasicBlockSrc *false_block = ir_create_basic_block(irb, scope, "BoolOrFalse");
5798 // block for when val1 == true (don't even evaluate the second part)
5799 IrBasicBlockSrc *true_block = ir_create_basic_block(irb, scope, "BoolOrTrue");
5800
5801 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime);
5802
5803 ir_set_cursor_at_end_and_append_block(irb, false_block);
5804 IrInstSrc *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
5805 if (val2 == irb->codegen->invalid_inst_src)
5806 return irb->codegen->invalid_inst_src;
5807 IrBasicBlockSrc *post_val2_block = irb->current_basic_block;
5808
5809 ir_build_br(irb, scope, node, true_block, is_comptime);
5810
5811 ir_set_cursor_at_end_and_append_block(irb, true_block);
5812
5813 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
5814 incoming_values[0] = val1;
5815 incoming_values[1] = val2;
5816 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
5817 incoming_blocks[0] = post_val1_block;
5818 incoming_blocks[1] = post_val2_block;
5819
5820 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr);
5821}
5822
5823static IrInstSrc *ir_gen_bool_and(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
5824 assert(node->type == NodeTypeBinOpExpr);
5825
5826 IrInstSrc *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope);
5827 if (val1 == irb->codegen->invalid_inst_src)
5828 return irb->codegen->invalid_inst_src;
5829 IrBasicBlockSrc *post_val1_block = irb->current_basic_block;
5830
5831 IrInstSrc *is_comptime;
5832 if (ir_should_inline(irb->exec, scope)) {
5833 is_comptime = ir_build_const_bool(irb, scope, node, true);
5834 } else {
5835 is_comptime = ir_build_test_comptime(irb, scope, node, val1);
5836 }
5837
5838 // block for when val1 == true
5839 IrBasicBlockSrc *true_block = ir_create_basic_block(irb, scope, "BoolAndTrue");
5840 // block for when val1 == false (don't even evaluate the second part)
5841 IrBasicBlockSrc *false_block = ir_create_basic_block(irb, scope, "BoolAndFalse");
5842
5843 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime);
5844
5845 ir_set_cursor_at_end_and_append_block(irb, true_block);
5846 IrInstSrc *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
5847 if (val2 == irb->codegen->invalid_inst_src)
5848 return irb->codegen->invalid_inst_src;
5849 IrBasicBlockSrc *post_val2_block = irb->current_basic_block;
5850
5851 ir_build_br(irb, scope, node, false_block, is_comptime);
5852
5853 ir_set_cursor_at_end_and_append_block(irb, false_block);
5854
5855 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
5856 incoming_values[0] = val1;
5857 incoming_values[1] = val2;
5858 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
5859 incoming_blocks[0] = post_val1_block;
5860 incoming_blocks[1] = post_val2_block;
5861
5862 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr);
5863}
5864
5865static ResultLocPeerParent *ir_build_result_peers(IrBuilderSrc *irb, IrInstSrc *cond_br_inst,
5866 IrBasicBlockSrc *end_block, ResultLoc *parent, IrInstSrc *is_comptime)
5867{
5868 ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>();
5869 peer_parent->base.id = ResultLocIdPeerParent;
5870 peer_parent->base.source_instruction = cond_br_inst;
5871 peer_parent->base.allow_write_through_const = parent->allow_write_through_const;
5872 peer_parent->end_bb = end_block;
5873 peer_parent->is_comptime = is_comptime;
5874 peer_parent->parent = parent;
5875
5876 IrInstSrc *popped_inst = irb->current_basic_block->instruction_list.pop();
5877 ir_assert(popped_inst == cond_br_inst, &cond_br_inst->base);
5878
5879 ir_build_reset_result(irb, cond_br_inst->base.scope, cond_br_inst->base.source_node, &peer_parent->base);
5880 irb->current_basic_block->instruction_list.append(popped_inst);
5881
5882 return peer_parent;
5883}
5884
5885static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilderSrc *irb, IrInstSrc *cond_br_inst,
5886 IrBasicBlockSrc *else_block, IrBasicBlockSrc *end_block, ResultLoc *parent, IrInstSrc *is_comptime)
5887{
5888 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, parent, is_comptime);
5889
5890 peer_parent->peers.append(create_peer_result(peer_parent));
5891 peer_parent->peers.last()->next_bb = else_block;
5892
5893 peer_parent->peers.append(create_peer_result(peer_parent));
5894 peer_parent->peers.last()->next_bb = end_block;
5895
5896 return peer_parent;
5897}
5898
5899static IrInstSrc *ir_gen_orelse(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval,
5900 ResultLoc *result_loc)
5901{
5902 assert(node->type == NodeTypeBinOpExpr);
5903
5904 AstNode *op1_node = node->data.bin_op_expr.op1;
5905 AstNode *op2_node = node->data.bin_op_expr.op2;
5906
5907 IrInstSrc *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr);
5908 if (maybe_ptr == irb->codegen->invalid_inst_src)
5909 return irb->codegen->invalid_inst_src;
5910
5911 IrInstSrc *maybe_val = ir_build_load_ptr(irb, parent_scope, node, maybe_ptr);
5912 IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, parent_scope, node, maybe_val);
5913
5914 IrInstSrc *is_comptime;
5915 if (ir_should_inline(irb->exec, parent_scope)) {
5916 is_comptime = ir_build_const_bool(irb, parent_scope, node, true);
5917 } else {
5918 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_non_null);
5919 }
5920
5921 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull");
5922 IrBasicBlockSrc *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull");
5923 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd");
5924 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime);
5925
5926 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block,
5927 result_loc, is_comptime);
5928
5929 ir_set_cursor_at_end_and_append_block(irb, null_block);
5930 IrInstSrc *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, LValNone,
5931 &peer_parent->peers.at(0)->base);
5932 if (null_result == irb->codegen->invalid_inst_src)
5933 return irb->codegen->invalid_inst_src;
5934 IrBasicBlockSrc *after_null_block = irb->current_basic_block;
5935 if (!instr_is_unreachable(null_result))
5936 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime));
5937
5938 ir_set_cursor_at_end_and_append_block(irb, ok_block);
5939 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false);
5940 IrInstSrc *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr);
5941 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base);
5942 IrBasicBlockSrc *after_ok_block = irb->current_basic_block;
5943 ir_build_br(irb, parent_scope, node, end_block, is_comptime);
5944
5945 ir_set_cursor_at_end_and_append_block(irb, end_block);
5946 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
5947 incoming_values[0] = null_result;
5948 incoming_values[1] = unwrapped_payload;
5949 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
5950 incoming_blocks[0] = after_null_block;
5951 incoming_blocks[1] = after_ok_block;
5952 IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent);
5953 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc);
5954}
5955
5956static IrInstSrc *ir_gen_error_union(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) {
5957 assert(node->type == NodeTypeBinOpExpr);
5958
5959 AstNode *op1_node = node->data.bin_op_expr.op1;
5960 AstNode *op2_node = node->data.bin_op_expr.op2;
5961
5962 IrInstSrc *err_set = ir_gen_node(irb, op1_node, parent_scope);
5963 if (err_set == irb->codegen->invalid_inst_src)
5964 return irb->codegen->invalid_inst_src;
5965
5966 IrInstSrc *payload = ir_gen_node(irb, op2_node, parent_scope);
5967 if (payload == irb->codegen->invalid_inst_src)
5968 return irb->codegen->invalid_inst_src;
5969
5970 return ir_build_error_union(irb, parent_scope, node, err_set, payload);
5971}
5972
5973static IrInstSrc *ir_gen_bin_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
5974 assert(node->type == NodeTypeBinOpExpr);
5975
5976 BinOpType bin_op_type = node->data.bin_op_expr.bin_op;
5977 switch (bin_op_type) {
5978 case BinOpTypeInvalid:
5979 zig_unreachable();
5980 case BinOpTypeAssign:
5981 return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc);
5982 case BinOpTypeAssignTimes:
5983 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMult), lval, result_loc);
5984 case BinOpTypeAssignTimesWrap:
5985 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap), lval, result_loc);
5986 case BinOpTypeAssignDiv:
5987 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc);
5988 case BinOpTypeAssignMod:
5989 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc);
5990 case BinOpTypeAssignPlus:
5991 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAdd), lval, result_loc);
5992 case BinOpTypeAssignPlusWrap:
5993 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap), lval, result_loc);
5994 case BinOpTypeAssignMinus:
5995 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSub), lval, result_loc);
5996 case BinOpTypeAssignMinusWrap:
5997 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap), lval, result_loc);
5998 case BinOpTypeAssignBitShiftLeft:
5999 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc);
6000 case BinOpTypeAssignBitShiftRight:
6001 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc);
6002 case BinOpTypeAssignBitAnd:
6003 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd), lval, result_loc);
6004 case BinOpTypeAssignBitXor:
6005 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinXor), lval, result_loc);
6006 case BinOpTypeAssignBitOr:
6007 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinOr), lval, result_loc);
6008 case BinOpTypeBoolOr:
6009 return ir_lval_wrap(irb, scope, ir_gen_bool_or(irb, scope, node), lval, result_loc);
6010 case BinOpTypeBoolAnd:
6011 return ir_lval_wrap(irb, scope, ir_gen_bool_and(irb, scope, node), lval, result_loc);
6012 case BinOpTypeCmpEq:
6013 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq), lval, result_loc);
6014 case BinOpTypeCmpNotEq:
6015 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq), lval, result_loc);
6016 case BinOpTypeCmpLessThan:
6017 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan), lval, result_loc);
6018 case BinOpTypeCmpGreaterThan:
6019 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan), lval, result_loc);
6020 case BinOpTypeCmpLessOrEq:
6021 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq), lval, result_loc);
6022 case BinOpTypeCmpGreaterOrEq:
6023 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc);
6024 case BinOpTypeBinOr:
6025 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr), lval, result_loc);
6026 case BinOpTypeBinXor:
6027 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor), lval, result_loc);
6028 case BinOpTypeBinAnd:
6029 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd), lval, result_loc);
6030 case BinOpTypeBitShiftLeft:
6031 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc);
6032 case BinOpTypeBitShiftRight:
6033 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc);
6034 case BinOpTypeAdd:
6035 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd), lval, result_loc);
6036 case BinOpTypeAddWrap:
6037 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap), lval, result_loc);
6038 case BinOpTypeSub:
6039 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSub), lval, result_loc);
6040 case BinOpTypeSubWrap:
6041 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap), lval, result_loc);
6042 case BinOpTypeMult:
6043 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMult), lval, result_loc);
6044 case BinOpTypeMultWrap:
6045 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap), lval, result_loc);
6046 case BinOpTypeDiv:
6047 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc);
6048 case BinOpTypeMod:
6049 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc);
6050 case BinOpTypeArrayCat:
6051 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat), lval, result_loc);
6052 case BinOpTypeArrayMult:
6053 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult), lval, result_loc);
6054 case BinOpTypeMergeErrorSets:
6055 return ir_lval_wrap(irb, scope, ir_gen_merge_err_sets(irb, scope, node), lval, result_loc);
6056 case BinOpTypeUnwrapOptional:
6057 return ir_gen_orelse(irb, scope, node, lval, result_loc);
6058 case BinOpTypeErrorUnion:
6059 return ir_lval_wrap(irb, scope, ir_gen_error_union(irb, scope, node), lval, result_loc);
6060 }
6061 zig_unreachable();
6062}
6063
6064static IrInstSrc *ir_gen_int_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
6065 assert(node->type == NodeTypeIntLiteral);
6066
6067 return ir_build_const_bigint(irb, scope, node, node->data.int_literal.bigint);
6068}
6069
6070static IrInstSrc *ir_gen_float_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
6071 assert(node->type == NodeTypeFloatLiteral);
6072
6073 if (node->data.float_literal.overflow) {
6074 add_node_error(irb->codegen, node, buf_sprintf("float literal out of range of any type"));
6075 return irb->codegen->invalid_inst_src;
6076 }
6077
6078 return ir_build_const_bigfloat(irb, scope, node, node->data.float_literal.bigfloat);
6079}
6080
6081static IrInstSrc *ir_gen_char_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
6082 assert(node->type == NodeTypeCharLiteral);
6083
6084 return ir_build_const_uint(irb, scope, node, node->data.char_literal.value);
6085}
6086
6087static IrInstSrc *ir_gen_null_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
6088 assert(node->type == NodeTypeNullLiteral);
6089
6090 return ir_build_const_null(irb, scope, node);
6091}
6092
6093static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode *node, Buf *var_name) {
6094 ScopeDecls *scope_decls = nullptr;
6095 while (scope != nullptr) {
6096 if (scope->id == ScopeIdDecls) {
6097 scope_decls = reinterpret_cast<ScopeDecls *>(scope);
6098 }
6099 scope = scope->parent;
6100 }
6101 TldVar *tld_var = heap::c_allocator.create<TldVar>();
6102 init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base);
6103 tld_var->base.resolution = TldResolutionInvalid;
6104 tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false,
6105 g->invalid_inst_gen->value, &tld_var->base, g->builtin_types.entry_invalid);
6106 scope_decls->decl_table.put(var_name, &tld_var->base);
6107}
6108
6109static IrInstSrc *ir_gen_symbol(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
6110 Error err;
6111 assert(node->type == NodeTypeSymbol);
6112
6113 Buf *variable_name = node->data.symbol_expr.symbol;
6114
6115 if (buf_eql_str(variable_name, "_")) {
6116 if (lval == LValAssign) {
6117 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, node);
6118 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>();
6119 const_instruction->value->type = get_pointer_to_type(irb->codegen,
6120 irb->codegen->builtin_types.entry_void, false);
6121 const_instruction->value->special = ConstValSpecialStatic;
6122 const_instruction->value->data.x_ptr.special = ConstPtrSpecialDiscard;
6123 return &const_instruction->base;
6124 } else {
6125 add_node_error(irb->codegen, node, buf_sprintf("`_` may only be used to assign things to"));
6126 return irb->codegen->invalid_inst_src;
6127 }
6128 }
6129
6130 ZigType *primitive_type;
6131 if ((err = get_primitive_type(irb->codegen, variable_name, &primitive_type))) {
6132 if (err == ErrorOverflow) {
6133 add_node_error(irb->codegen, node,
6134 buf_sprintf("primitive integer type '%s' exceeds maximum bit width of 65535",
6135 buf_ptr(variable_name)));
6136 return irb->codegen->invalid_inst_src;
6137 }
6138 assert(err == ErrorPrimitiveTypeNotFound);
6139 } else {
6140 IrInstSrc *value = ir_build_const_type(irb, scope, node, primitive_type);
6141 if (lval == LValPtr || lval == LValAssign) {
6142 return ir_build_ref_src(irb, scope, node, value);
6143 } else {
6144 return ir_expr_wrap(irb, scope, value, result_loc);
6145 }
6146 }
6147
6148 ScopeFnDef *crossed_fndef_scope;
6149 ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope);
6150 if (var) {
6151 IrInstSrc *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope);
6152 if (lval == LValPtr || lval == LValAssign) {
6153 return var_ptr;
6154 } else {
6155 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, var_ptr), result_loc);
6156 }
6157 }
6158
6159 Tld *tld = find_decl(irb->codegen, scope, variable_name);
6160 if (tld) {
6161 IrInstSrc *decl_ref = ir_build_decl_ref(irb, scope, node, tld, lval);
6162 if (lval == LValPtr || lval == LValAssign) {
6163 return decl_ref;
6164 } else {
6165 return ir_expr_wrap(irb, scope, decl_ref, result_loc);
6166 }
6167 }
6168
6169 if (get_container_scope(node->owner)->any_imports_failed) {
6170 // skip the error message since we had a failing import in this file
6171 // if an import breaks we don't need redundant undeclared identifier errors
6172 return irb->codegen->invalid_inst_src;
6173 }
6174
6175 return ir_build_undeclared_identifier(irb, scope, node, variable_name);
6176}
6177
6178static IrInstSrc *ir_gen_array_access(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
6179 ResultLoc *result_loc)
6180{
6181 assert(node->type == NodeTypeArrayAccessExpr);
6182
6183 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;
6184 IrInstSrc *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr);
6185 if (array_ref_instruction == irb->codegen->invalid_inst_src)
6186 return array_ref_instruction;
6187
6188 // Create an usize-typed result location to hold the subscript value, this
6189 // makes it possible for the compiler to infer the subscript expression type
6190 // if needed
6191 IrInstSrc *usize_type_inst = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize);
6192 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, usize_type_inst, no_result_loc());
6193
6194 AstNode *subscript_node = node->data.array_access_expr.subscript;
6195 IrInstSrc *subscript_value = ir_gen_node_extra(irb, subscript_node, scope, LValNone, &result_loc_cast->base);
6196 if (subscript_value == irb->codegen->invalid_inst_src)
6197 return irb->codegen->invalid_inst_src;
6198
6199 IrInstSrc *subscript_instruction = ir_build_implicit_cast(irb, scope, subscript_node, subscript_value, result_loc_cast);
6200
6201 IrInstSrc *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction,
6202 subscript_instruction, true, PtrLenSingle, nullptr);
6203 if (lval == LValPtr || lval == LValAssign)
6204 return ptr_instruction;
6205
6206 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction);
6207 return ir_expr_wrap(irb, scope, load_ptr, result_loc);
6208}
6209
6210static IrInstSrc *ir_gen_field_access(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
6211 assert(node->type == NodeTypeFieldAccessExpr);
6212
6213 AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
6214 Buf *field_name = node->data.field_access_expr.field_name;
6215
6216 IrInstSrc *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr);
6217 if (container_ref_instruction == irb->codegen->invalid_inst_src)
6218 return container_ref_instruction;
6219
6220 return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name, false);
6221}
6222
6223static IrInstSrc *ir_gen_overflow_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrOverflowOp op) {
6224 assert(node->type == NodeTypeFnCallExpr);
6225
6226 AstNode *type_node = node->data.fn_call_expr.params.at(0);
6227 AstNode *op1_node = node->data.fn_call_expr.params.at(1);
6228 AstNode *op2_node = node->data.fn_call_expr.params.at(2);
6229 AstNode *result_ptr_node = node->data.fn_call_expr.params.at(3);
6230
6231
6232 IrInstSrc *type_value = ir_gen_node(irb, type_node, scope);
6233 if (type_value == irb->codegen->invalid_inst_src)
6234 return irb->codegen->invalid_inst_src;
6235
6236 IrInstSrc *op1 = ir_gen_node(irb, op1_node, scope);
6237 if (op1 == irb->codegen->invalid_inst_src)
6238 return irb->codegen->invalid_inst_src;
6239
6240 IrInstSrc *op2 = ir_gen_node(irb, op2_node, scope);
6241 if (op2 == irb->codegen->invalid_inst_src)
6242 return irb->codegen->invalid_inst_src;
6243
6244 IrInstSrc *result_ptr = ir_gen_node(irb, result_ptr_node, scope);
6245 if (result_ptr == irb->codegen->invalid_inst_src)
6246 return irb->codegen->invalid_inst_src;
6247
6248 return ir_build_overflow_op_src(irb, scope, node, op, type_value, op1, op2, result_ptr);
6249}
6250
6251static IrInstSrc *ir_gen_mul_add(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
6252 assert(node->type == NodeTypeFnCallExpr);
6253
6254 AstNode *type_node = node->data.fn_call_expr.params.at(0);
6255 AstNode *op1_node = node->data.fn_call_expr.params.at(1);
6256 AstNode *op2_node = node->data.fn_call_expr.params.at(2);
6257 AstNode *op3_node = node->data.fn_call_expr.params.at(3);
6258
6259 IrInstSrc *type_value = ir_gen_node(irb, type_node, scope);
6260 if (type_value == irb->codegen->invalid_inst_src)
6261 return irb->codegen->invalid_inst_src;
6262
6263 IrInstSrc *op1 = ir_gen_node(irb, op1_node, scope);
6264 if (op1 == irb->codegen->invalid_inst_src)
6265 return irb->codegen->invalid_inst_src;
6266
6267 IrInstSrc *op2 = ir_gen_node(irb, op2_node, scope);
6268 if (op2 == irb->codegen->invalid_inst_src)
6269 return irb->codegen->invalid_inst_src;
6270
6271 IrInstSrc *op3 = ir_gen_node(irb, op3_node, scope);
6272 if (op3 == irb->codegen->invalid_inst_src)
6273 return irb->codegen->invalid_inst_src;
6274
6275 return ir_build_mul_add_src(irb, scope, node, type_value, op1, op2, op3);
6276}
6277
6278static IrInstSrc *ir_gen_this(IrBuilderSrc *irb, Scope *orig_scope, AstNode *node) {
6279 for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) {
6280 if (it_scope->id == ScopeIdDecls) {
6281 ScopeDecls *decls_scope = (ScopeDecls *)it_scope;
6282 ZigType *container_type = decls_scope->container_type;
6283 if (container_type != nullptr) {
6284 return ir_build_const_type(irb, orig_scope, node, container_type);
6285 } else {
6286 return ir_build_const_import(irb, orig_scope, node, decls_scope->import);
6287 }
6288 }
6289 }
6290 zig_unreachable();
6291}
6292
6293static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *await_node, AstNode *call_node,
6294 LVal lval, ResultLoc *result_loc)
6295{
6296 if (call_node->data.fn_call_expr.params.length != 4) {
6297 add_node_error(irb->codegen, call_node,
6298 buf_sprintf("expected 4 arguments, found %" ZIG_PRI_usize,
6299 call_node->data.fn_call_expr.params.length));
6300 return irb->codegen->invalid_inst_src;
6301 }
6302
6303 AstNode *bytes_node = call_node->data.fn_call_expr.params.at(0);
6304 IrInstSrc *bytes = ir_gen_node(irb, bytes_node, scope);
6305 if (bytes == irb->codegen->invalid_inst_src)
6306 return bytes;
6307
6308 AstNode *ret_ptr_node = call_node->data.fn_call_expr.params.at(1);
6309 IrInstSrc *ret_ptr = ir_gen_node(irb, ret_ptr_node, scope);
6310 if (ret_ptr == irb->codegen->invalid_inst_src)
6311 return ret_ptr;
6312
6313 AstNode *fn_ref_node = call_node->data.fn_call_expr.params.at(2);
6314 IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope);
6315 if (fn_ref == irb->codegen->invalid_inst_src)
6316 return fn_ref;
6317
6318 CallModifier modifier = (await_node == nullptr) ? CallModifierAsync : CallModifierNone;
6319 bool is_async_call_builtin = true;
6320 AstNode *args_node = call_node->data.fn_call_expr.params.at(3);
6321 if (args_node->type == NodeTypeContainerInitExpr) {
6322 if (args_node->data.container_init_expr.kind == ContainerInitKindArray ||
6323 args_node->data.container_init_expr.entries.length == 0)
6324 {
6325 size_t arg_count = args_node->data.container_init_expr.entries.length;
6326 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count);
6327 for (size_t i = 0; i < arg_count; i += 1) {
6328 AstNode *arg_node = args_node->data.container_init_expr.entries.at(i);
6329 IrInstSrc *arg = ir_gen_node(irb, arg_node, scope);
6330 if (arg == irb->codegen->invalid_inst_src)
6331 return arg;
6332 args[i] = arg;
6333 }
6334
6335 IrInstSrc *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args,
6336 ret_ptr, modifier, is_async_call_builtin, bytes, result_loc);
6337 return ir_lval_wrap(irb, scope, call, lval, result_loc);
6338 } else {
6339 exec_add_error_node(irb->codegen, irb->exec, args_node,
6340 buf_sprintf("TODO: @asyncCall with anon struct literal"));
6341 return irb->codegen->invalid_inst_src;
6342 }
6343 }
6344 IrInstSrc *args = ir_gen_node(irb, args_node, scope);
6345 if (args == irb->codegen->invalid_inst_src)
6346 return args;
6347
6348 IrInstSrc *call = ir_build_async_call_extra(irb, scope, call_node, modifier, fn_ref, ret_ptr, bytes, args, result_loc);
6349 return ir_lval_wrap(irb, scope, call, lval, result_loc);
6350}
6351
6352static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
6353 AstNode *fn_ref_node, CallModifier modifier, IrInstSrc *options,
6354 AstNode **args_ptr, size_t args_len, LVal lval, ResultLoc *result_loc)
6355{
6356 IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope);
6357 if (fn_ref == irb->codegen->invalid_inst_src)
6358 return fn_ref;
6359
6360 IrInstSrc *fn_type = ir_build_typeof_1(irb, scope, source_node, fn_ref);
6361
6362 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len);
6363 for (size_t i = 0; i < args_len; i += 1) {
6364 AstNode *arg_node = args_ptr[i];
6365
6366 IrInstSrc *arg_index = ir_build_const_usize(irb, scope, arg_node, i);
6367 IrInstSrc *arg_type = ir_build_arg_type(irb, scope, source_node, fn_type, arg_index, true);
6368 ResultLoc *no_result = no_result_loc();
6369 ir_build_reset_result(irb, scope, source_node, no_result);
6370 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result);
6371
6372 IrInstSrc *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base);
6373 if (arg == irb->codegen->invalid_inst_src)
6374 return arg;
6375
6376 args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast);
6377 }
6378
6379 IrInstSrc *fn_call;
6380 if (options != nullptr) {
6381 fn_call = ir_build_call_args(irb, scope, source_node, options, fn_ref, args, args_len, result_loc);
6382 } else {
6383 fn_call = ir_build_call_src(irb, scope, source_node, nullptr, fn_ref, args_len, args, nullptr,
6384 modifier, false, nullptr, result_loc);
6385 }
6386 return ir_lval_wrap(irb, scope, fn_call, lval, result_loc);
6387}
6388
6389static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
6390 ResultLoc *result_loc)
6391{
6392 assert(node->type == NodeTypeFnCallExpr);
6393
6394 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
6395 Buf *name = fn_ref_expr->data.symbol_expr.symbol;
6396 auto entry = irb->codegen->builtin_fn_table.maybe_get(name);
6397
6398 if (!entry) {
6399 add_node_error(irb->codegen, node,
6400 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name)));
6401 return irb->codegen->invalid_inst_src;
6402 }
6403
6404 BuiltinFnEntry *builtin_fn = entry->value;
6405 size_t actual_param_count = node->data.fn_call_expr.params.length;
6406
6407 if (builtin_fn->param_count != SIZE_MAX && builtin_fn->param_count != actual_param_count) {
6408 add_node_error(irb->codegen, node,
6409 buf_sprintf("expected %" ZIG_PRI_usize " argument(s), found %" ZIG_PRI_usize,
6410 builtin_fn->param_count, actual_param_count));
6411 return irb->codegen->invalid_inst_src;
6412 }
6413
6414 switch (builtin_fn->id) {
6415 case BuiltinFnIdInvalid:
6416 zig_unreachable();
6417 case BuiltinFnIdTypeof:
6418 {
6419 Scope *sub_scope = create_typeof_scope(irb->codegen, node, scope);
6420
6421 size_t arg_count = node->data.fn_call_expr.params.length;
6422
6423 IrInstSrc *type_of;
6424
6425 if (arg_count == 0) {
6426 add_node_error(irb->codegen, node,
6427 buf_sprintf("expected at least 1 argument, found 0"));
6428 return irb->codegen->invalid_inst_src;
6429 } else if (arg_count == 1) {
6430 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6431 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, sub_scope);
6432 if (arg0_value == irb->codegen->invalid_inst_src)
6433 return arg0_value;
6434
6435 type_of = ir_build_typeof_1(irb, scope, node, arg0_value);
6436 } else {
6437 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count);
6438 for (size_t i = 0; i < arg_count; i += 1) {
6439 AstNode *arg_node = node->data.fn_call_expr.params.at(i);
6440 IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope);
6441 if (arg == irb->codegen->invalid_inst_src)
6442 return irb->codegen->invalid_inst_src;
6443 args[i] = arg;
6444 }
6445
6446 type_of = ir_build_typeof_n(irb, scope, node, args, arg_count);
6447 }
6448 return ir_lval_wrap(irb, scope, type_of, lval, result_loc);
6449 }
6450 case BuiltinFnIdSetCold:
6451 {
6452 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6453 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6454 if (arg0_value == irb->codegen->invalid_inst_src)
6455 return arg0_value;
6456
6457 IrInstSrc *set_cold = ir_build_set_cold(irb, scope, node, arg0_value);
6458 return ir_lval_wrap(irb, scope, set_cold, lval, result_loc);
6459 }
6460 case BuiltinFnIdSetRuntimeSafety:
6461 {
6462 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6463 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6464 if (arg0_value == irb->codegen->invalid_inst_src)
6465 return arg0_value;
6466
6467 IrInstSrc *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value);
6468 return ir_lval_wrap(irb, scope, set_safety, lval, result_loc);
6469 }
6470 case BuiltinFnIdSetFloatMode:
6471 {
6472 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6473 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6474 if (arg0_value == irb->codegen->invalid_inst_src)
6475 return arg0_value;
6476
6477 IrInstSrc *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value);
6478 return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc);
6479 }
6480 case BuiltinFnIdSizeof:
6481 case BuiltinFnIdBitSizeof:
6482 {
6483 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6484 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6485 if (arg0_value == irb->codegen->invalid_inst_src)
6486 return arg0_value;
6487
6488 IrInstSrc *size_of = ir_build_size_of(irb, scope, node, arg0_value, builtin_fn->id == BuiltinFnIdBitSizeof);
6489 return ir_lval_wrap(irb, scope, size_of, lval, result_loc);
6490 }
6491 case BuiltinFnIdImport:
6492 {
6493 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6494 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6495 if (arg0_value == irb->codegen->invalid_inst_src)
6496 return arg0_value;
6497
6498 IrInstSrc *import = ir_build_import(irb, scope, node, arg0_value);
6499 return ir_lval_wrap(irb, scope, import, lval, result_loc);
6500 }
6501 case BuiltinFnIdCImport:
6502 {
6503 IrInstSrc *c_import = ir_build_c_import(irb, scope, node);
6504 return ir_lval_wrap(irb, scope, c_import, lval, result_loc);
6505 }
6506 case BuiltinFnIdCInclude:
6507 {
6508 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6509 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6510 if (arg0_value == irb->codegen->invalid_inst_src)
6511 return arg0_value;
6512
6513 if (!exec_c_import_buf(irb->exec)) {
6514 add_node_error(irb->codegen, node, buf_sprintf("C include valid only inside C import block"));
6515 return irb->codegen->invalid_inst_src;
6516 }
6517
6518 IrInstSrc *c_include = ir_build_c_include(irb, scope, node, arg0_value);
6519 return ir_lval_wrap(irb, scope, c_include, lval, result_loc);
6520 }
6521 case BuiltinFnIdCDefine:
6522 {
6523 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6524 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6525 if (arg0_value == irb->codegen->invalid_inst_src)
6526 return arg0_value;
6527
6528 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6529 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6530 if (arg1_value == irb->codegen->invalid_inst_src)
6531 return arg1_value;
6532
6533 if (!exec_c_import_buf(irb->exec)) {
6534 add_node_error(irb->codegen, node, buf_sprintf("C define valid only inside C import block"));
6535 return irb->codegen->invalid_inst_src;
6536 }
6537
6538 IrInstSrc *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value);
6539 return ir_lval_wrap(irb, scope, c_define, lval, result_loc);
6540 }
6541 case BuiltinFnIdCUndef:
6542 {
6543 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6544 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6545 if (arg0_value == irb->codegen->invalid_inst_src)
6546 return arg0_value;
6547
6548 if (!exec_c_import_buf(irb->exec)) {
6549 add_node_error(irb->codegen, node, buf_sprintf("C undef valid only inside C import block"));
6550 return irb->codegen->invalid_inst_src;
6551 }
6552
6553 IrInstSrc *c_undef = ir_build_c_undef(irb, scope, node, arg0_value);
6554 return ir_lval_wrap(irb, scope, c_undef, lval, result_loc);
6555 }
6556 case BuiltinFnIdCompileErr:
6557 {
6558 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6559 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6560 if (arg0_value == irb->codegen->invalid_inst_src)
6561 return arg0_value;
6562
6563 IrInstSrc *compile_err = ir_build_compile_err(irb, scope, node, arg0_value);
6564 return ir_lval_wrap(irb, scope, compile_err, lval, result_loc);
6565 }
6566 case BuiltinFnIdCompileLog:
6567 {
6568 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(actual_param_count);
6569
6570 for (size_t i = 0; i < actual_param_count; i += 1) {
6571 AstNode *arg_node = node->data.fn_call_expr.params.at(i);
6572 args[i] = ir_gen_node(irb, arg_node, scope);
6573 if (args[i] == irb->codegen->invalid_inst_src)
6574 return irb->codegen->invalid_inst_src;
6575 }
6576
6577 IrInstSrc *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args);
6578 return ir_lval_wrap(irb, scope, compile_log, lval, result_loc);
6579 }
6580 case BuiltinFnIdErrName:
6581 {
6582 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6583 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6584 if (arg0_value == irb->codegen->invalid_inst_src)
6585 return arg0_value;
6586
6587 IrInstSrc *err_name = ir_build_err_name(irb, scope, node, arg0_value);
6588 return ir_lval_wrap(irb, scope, err_name, lval, result_loc);
6589 }
6590 case BuiltinFnIdEmbedFile:
6591 {
6592 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6593 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6594 if (arg0_value == irb->codegen->invalid_inst_src)
6595 return arg0_value;
6596
6597 IrInstSrc *embed_file = ir_build_embed_file(irb, scope, node, arg0_value);
6598 return ir_lval_wrap(irb, scope, embed_file, lval, result_loc);
6599 }
6600 case BuiltinFnIdCmpxchgWeak:
6601 case BuiltinFnIdCmpxchgStrong:
6602 {
6603 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6604 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6605 if (arg0_value == irb->codegen->invalid_inst_src)
6606 return arg0_value;
6607
6608 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6609 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6610 if (arg1_value == irb->codegen->invalid_inst_src)
6611 return arg1_value;
6612
6613 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
6614 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope);
6615 if (arg2_value == irb->codegen->invalid_inst_src)
6616 return arg2_value;
6617
6618 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
6619 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope);
6620 if (arg3_value == irb->codegen->invalid_inst_src)
6621 return arg3_value;
6622
6623 AstNode *arg4_node = node->data.fn_call_expr.params.at(4);
6624 IrInstSrc *arg4_value = ir_gen_node(irb, arg4_node, scope);
6625 if (arg4_value == irb->codegen->invalid_inst_src)
6626 return arg4_value;
6627
6628 AstNode *arg5_node = node->data.fn_call_expr.params.at(5);
6629 IrInstSrc *arg5_value = ir_gen_node(irb, arg5_node, scope);
6630 if (arg5_value == irb->codegen->invalid_inst_src)
6631 return arg5_value;
6632
6633 IrInstSrc *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value,
6634 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak),
6635 result_loc);
6636 return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc);
6637 }
6638 case BuiltinFnIdFence:
6639 {
6640 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6641 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6642 if (arg0_value == irb->codegen->invalid_inst_src)
6643 return arg0_value;
6644
6645 IrInstSrc *fence = ir_build_fence(irb, scope, node, arg0_value);
6646 return ir_lval_wrap(irb, scope, fence, lval, result_loc);
6647 }
6648 case BuiltinFnIdReduce:
6649 {
6650 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6651 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6652 if (arg0_value == irb->codegen->invalid_inst_src)
6653 return arg0_value;
6654
6655 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6656 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6657 if (arg1_value == irb->codegen->invalid_inst_src)
6658 return arg1_value;
6659
6660 IrInstSrc *reduce = ir_build_reduce(irb, scope, node, arg0_value, arg1_value);
6661 return ir_lval_wrap(irb, scope, reduce, lval, result_loc);
6662 }
6663 case BuiltinFnIdDivExact:
6664 {
6665 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6666 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6667 if (arg0_value == irb->codegen->invalid_inst_src)
6668 return arg0_value;
6669
6670 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6671 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6672 if (arg1_value == irb->codegen->invalid_inst_src)
6673 return arg1_value;
6674
6675 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true);
6676 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
6677 }
6678 case BuiltinFnIdDivTrunc:
6679 {
6680 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6681 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6682 if (arg0_value == irb->codegen->invalid_inst_src)
6683 return arg0_value;
6684
6685 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6686 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6687 if (arg1_value == irb->codegen->invalid_inst_src)
6688 return arg1_value;
6689
6690 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true);
6691 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
6692 }
6693 case BuiltinFnIdDivFloor:
6694 {
6695 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6696 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6697 if (arg0_value == irb->codegen->invalid_inst_src)
6698 return arg0_value;
6699
6700 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6701 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6702 if (arg1_value == irb->codegen->invalid_inst_src)
6703 return arg1_value;
6704
6705 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true);
6706 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
6707 }
6708 case BuiltinFnIdRem:
6709 {
6710 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6711 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6712 if (arg0_value == irb->codegen->invalid_inst_src)
6713 return arg0_value;
6714
6715 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6716 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6717 if (arg1_value == irb->codegen->invalid_inst_src)
6718 return arg1_value;
6719
6720 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true);
6721 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
6722 }
6723 case BuiltinFnIdMod:
6724 {
6725 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6726 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6727 if (arg0_value == irb->codegen->invalid_inst_src)
6728 return arg0_value;
6729
6730 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6731 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6732 if (arg1_value == irb->codegen->invalid_inst_src)
6733 return arg1_value;
6734
6735 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true);
6736 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
6737 }
6738 case BuiltinFnIdSqrt:
6739 case BuiltinFnIdSin:
6740 case BuiltinFnIdCos:
6741 case BuiltinFnIdExp:
6742 case BuiltinFnIdExp2:
6743 case BuiltinFnIdLog:
6744 case BuiltinFnIdLog2:
6745 case BuiltinFnIdLog10:
6746 case BuiltinFnIdFabs:
6747 case BuiltinFnIdFloor:
6748 case BuiltinFnIdCeil:
6749 case BuiltinFnIdTrunc:
6750 case BuiltinFnIdNearbyInt:
6751 case BuiltinFnIdRound:
6752 {
6753 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6754 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6755 if (arg0_value == irb->codegen->invalid_inst_src)
6756 return arg0_value;
6757
6758 IrInstSrc *inst = ir_build_float_op_src(irb, scope, node, arg0_value, builtin_fn->id);
6759 return ir_lval_wrap(irb, scope, inst, lval, result_loc);
6760 }
6761 case BuiltinFnIdTruncate:
6762 {
6763 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6764 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6765 if (arg0_value == irb->codegen->invalid_inst_src)
6766 return arg0_value;
6767
6768 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6769 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6770 if (arg1_value == irb->codegen->invalid_inst_src)
6771 return arg1_value;
6772
6773 IrInstSrc *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value);
6774 return ir_lval_wrap(irb, scope, truncate, lval, result_loc);
6775 }
6776 case BuiltinFnIdIntCast:
6777 {
6778 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6779 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6780 if (arg0_value == irb->codegen->invalid_inst_src)
6781 return arg0_value;
6782
6783 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6784 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6785 if (arg1_value == irb->codegen->invalid_inst_src)
6786 return arg1_value;
6787
6788 IrInstSrc *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value);
6789 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6790 }
6791 case BuiltinFnIdFloatCast:
6792 {
6793 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6794 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6795 if (arg0_value == irb->codegen->invalid_inst_src)
6796 return arg0_value;
6797
6798 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6799 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6800 if (arg1_value == irb->codegen->invalid_inst_src)
6801 return arg1_value;
6802
6803 IrInstSrc *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value);
6804 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6805 }
6806 case BuiltinFnIdErrSetCast:
6807 {
6808 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6809 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6810 if (arg0_value == irb->codegen->invalid_inst_src)
6811 return arg0_value;
6812
6813 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6814 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6815 if (arg1_value == irb->codegen->invalid_inst_src)
6816 return arg1_value;
6817
6818 IrInstSrc *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value);
6819 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6820 }
6821 case BuiltinFnIdIntToFloat:
6822 {
6823 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6824 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6825 if (arg0_value == irb->codegen->invalid_inst_src)
6826 return arg0_value;
6827
6828 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6829 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6830 if (arg1_value == irb->codegen->invalid_inst_src)
6831 return arg1_value;
6832
6833 IrInstSrc *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value);
6834 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6835 }
6836 case BuiltinFnIdFloatToInt:
6837 {
6838 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6839 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6840 if (arg0_value == irb->codegen->invalid_inst_src)
6841 return arg0_value;
6842
6843 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6844 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6845 if (arg1_value == irb->codegen->invalid_inst_src)
6846 return arg1_value;
6847
6848 IrInstSrc *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value);
6849 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6850 }
6851 case BuiltinFnIdErrToInt:
6852 {
6853 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6854 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6855 if (arg0_value == irb->codegen->invalid_inst_src)
6856 return arg0_value;
6857
6858 IrInstSrc *result = ir_build_err_to_int_src(irb, scope, node, arg0_value);
6859 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6860 }
6861 case BuiltinFnIdIntToErr:
6862 {
6863 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6864 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6865 if (arg0_value == irb->codegen->invalid_inst_src)
6866 return arg0_value;
6867
6868 IrInstSrc *result = ir_build_int_to_err_src(irb, scope, node, arg0_value);
6869 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6870 }
6871 case BuiltinFnIdBoolToInt:
6872 {
6873 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6874 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6875 if (arg0_value == irb->codegen->invalid_inst_src)
6876 return arg0_value;
6877
6878 IrInstSrc *result = ir_build_bool_to_int(irb, scope, node, arg0_value);
6879 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6880 }
6881 case BuiltinFnIdVectorType:
6882 {
6883 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6884 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6885 if (arg0_value == irb->codegen->invalid_inst_src)
6886 return arg0_value;
6887
6888 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6889 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6890 if (arg1_value == irb->codegen->invalid_inst_src)
6891 return arg1_value;
6892
6893 IrInstSrc *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value);
6894 return ir_lval_wrap(irb, scope, vector_type, lval, result_loc);
6895 }
6896 case BuiltinFnIdShuffle:
6897 {
6898 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6899 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6900 if (arg0_value == irb->codegen->invalid_inst_src)
6901 return arg0_value;
6902
6903 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6904 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6905 if (arg1_value == irb->codegen->invalid_inst_src)
6906 return arg1_value;
6907
6908 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
6909 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope);
6910 if (arg2_value == irb->codegen->invalid_inst_src)
6911 return arg2_value;
6912
6913 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
6914 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope);
6915 if (arg3_value == irb->codegen->invalid_inst_src)
6916 return arg3_value;
6917
6918 IrInstSrc *shuffle_vector = ir_build_shuffle_vector(irb, scope, node,
6919 arg0_value, arg1_value, arg2_value, arg3_value);
6920 return ir_lval_wrap(irb, scope, shuffle_vector, lval, result_loc);
6921 }
6922 case BuiltinFnIdSplat:
6923 {
6924 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6925 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6926 if (arg0_value == irb->codegen->invalid_inst_src)
6927 return arg0_value;
6928
6929 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6930 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6931 if (arg1_value == irb->codegen->invalid_inst_src)
6932 return arg1_value;
6933
6934 IrInstSrc *splat = ir_build_splat_src(irb, scope, node,
6935 arg0_value, arg1_value);
6936 return ir_lval_wrap(irb, scope, splat, lval, result_loc);
6937 }
6938 case BuiltinFnIdMemcpy:
6939 {
6940 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6941 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6942 if (arg0_value == irb->codegen->invalid_inst_src)
6943 return arg0_value;
6944
6945 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6946 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6947 if (arg1_value == irb->codegen->invalid_inst_src)
6948 return arg1_value;
6949
6950 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
6951 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope);
6952 if (arg2_value == irb->codegen->invalid_inst_src)
6953 return arg2_value;
6954
6955 IrInstSrc *ir_memcpy = ir_build_memcpy_src(irb, scope, node, arg0_value, arg1_value, arg2_value);
6956 return ir_lval_wrap(irb, scope, ir_memcpy, lval, result_loc);
6957 }
6958 case BuiltinFnIdMemset:
6959 {
6960 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6961 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6962 if (arg0_value == irb->codegen->invalid_inst_src)
6963 return arg0_value;
6964
6965 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6966 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6967 if (arg1_value == irb->codegen->invalid_inst_src)
6968 return arg1_value;
6969
6970 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
6971 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope);
6972 if (arg2_value == irb->codegen->invalid_inst_src)
6973 return arg2_value;
6974
6975 IrInstSrc *ir_memset = ir_build_memset_src(irb, scope, node, arg0_value, arg1_value, arg2_value);
6976 return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc);
6977 }
6978 case BuiltinFnIdWasmMemorySize:
6979 {
6980 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6981 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6982 if (arg0_value == irb->codegen->invalid_inst_src)
6983 return arg0_value;
6984
6985 IrInstSrc *ir_wasm_memory_size = ir_build_wasm_memory_size_src(irb, scope, node, arg0_value);
6986 return ir_lval_wrap(irb, scope, ir_wasm_memory_size, lval, result_loc);
6987 }
6988 case BuiltinFnIdWasmMemoryGrow:
6989 {
6990 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6991 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6992 if (arg0_value == irb->codegen->invalid_inst_src)
6993 return arg0_value;
6994
6995 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6996 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6997 if (arg1_value == irb->codegen->invalid_inst_src)
6998 return arg1_value;
6999
7000 IrInstSrc *ir_wasm_memory_grow = ir_build_wasm_memory_grow_src(irb, scope, node, arg0_value, arg1_value);
7001 return ir_lval_wrap(irb, scope, ir_wasm_memory_grow, lval, result_loc);
7002 }
7003 case BuiltinFnIdField:
7004 {
7005 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7006 IrInstSrc *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr);
7007 if (arg0_value == irb->codegen->invalid_inst_src)
7008 return arg0_value;
7009
7010 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7011 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7012 if (arg1_value == irb->codegen->invalid_inst_src)
7013 return arg1_value;
7014
7015 IrInstSrc *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node,
7016 arg0_value, arg1_value, false);
7017
7018 if (lval == LValPtr || lval == LValAssign)
7019 return ptr_instruction;
7020
7021 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction);
7022 return ir_expr_wrap(irb, scope, load_ptr, result_loc);
7023 }
7024 case BuiltinFnIdHasField:
7025 {
7026 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7027 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7028 if (arg0_value == irb->codegen->invalid_inst_src)
7029 return arg0_value;
7030
7031 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7032 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7033 if (arg1_value == irb->codegen->invalid_inst_src)
7034 return arg1_value;
7035
7036 IrInstSrc *type_info = ir_build_has_field(irb, scope, node, arg0_value, arg1_value);
7037 return ir_lval_wrap(irb, scope, type_info, lval, result_loc);
7038 }
7039 case BuiltinFnIdTypeInfo:
7040 {
7041 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7042 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7043 if (arg0_value == irb->codegen->invalid_inst_src)
7044 return arg0_value;
7045
7046 IrInstSrc *type_info = ir_build_type_info(irb, scope, node, arg0_value);
7047 return ir_lval_wrap(irb, scope, type_info, lval, result_loc);
7048 }
7049 case BuiltinFnIdType:
7050 {
7051 AstNode *arg_node = node->data.fn_call_expr.params.at(0);
7052 IrInstSrc *arg = ir_gen_node(irb, arg_node, scope);
7053 if (arg == irb->codegen->invalid_inst_src)
7054 return arg;
7055
7056 IrInstSrc *type = ir_build_type(irb, scope, node, arg);
7057 return ir_lval_wrap(irb, scope, type, lval, result_loc);
7058 }
7059 case BuiltinFnIdBreakpoint:
7060 return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval, result_loc);
7061 case BuiltinFnIdReturnAddress:
7062 return ir_lval_wrap(irb, scope, ir_build_return_address_src(irb, scope, node), lval, result_loc);
7063 case BuiltinFnIdFrameAddress:
7064 return ir_lval_wrap(irb, scope, ir_build_frame_address_src(irb, scope, node), lval, result_loc);
7065 case BuiltinFnIdFrameHandle:
7066 if (!irb->exec->fn_entry) {
7067 add_node_error(irb->codegen, node, buf_sprintf("@frame() called outside of function definition"));
7068 return irb->codegen->invalid_inst_src;
7069 }
7070 return ir_lval_wrap(irb, scope, ir_build_handle_src(irb, scope, node), lval, result_loc);
7071 case BuiltinFnIdFrameType: {
7072 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7073 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7074 if (arg0_value == irb->codegen->invalid_inst_src)
7075 return arg0_value;
7076
7077 IrInstSrc *frame_type = ir_build_frame_type(irb, scope, node, arg0_value);
7078 return ir_lval_wrap(irb, scope, frame_type, lval, result_loc);
7079 }
7080 case BuiltinFnIdFrameSize: {
7081 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7082 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7083 if (arg0_value == irb->codegen->invalid_inst_src)
7084 return arg0_value;
7085
7086 IrInstSrc *frame_size = ir_build_frame_size_src(irb, scope, node, arg0_value);
7087 return ir_lval_wrap(irb, scope, frame_size, lval, result_loc);
7088 }
7089 case BuiltinFnIdAlignOf:
7090 {
7091 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7092 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7093 if (arg0_value == irb->codegen->invalid_inst_src)
7094 return arg0_value;
7095
7096 IrInstSrc *align_of = ir_build_align_of(irb, scope, node, arg0_value);
7097 return ir_lval_wrap(irb, scope, align_of, lval, result_loc);
7098 }
7099 case BuiltinFnIdAddWithOverflow:
7100 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval, result_loc);
7101 case BuiltinFnIdSubWithOverflow:
7102 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval, result_loc);
7103 case BuiltinFnIdMulWithOverflow:
7104 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval, result_loc);
7105 case BuiltinFnIdShlWithOverflow:
7106 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval, result_loc);
7107 case BuiltinFnIdMulAdd:
7108 return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval, result_loc);
7109 case BuiltinFnIdTypeName:
7110 {
7111 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7112 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7113 if (arg0_value == irb->codegen->invalid_inst_src)
7114 return arg0_value;
7115
7116 IrInstSrc *type_name = ir_build_type_name(irb, scope, node, arg0_value);
7117 return ir_lval_wrap(irb, scope, type_name, lval, result_loc);
7118 }
7119 case BuiltinFnIdPanic:
7120 {
7121 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7122 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7123 if (arg0_value == irb->codegen->invalid_inst_src)
7124 return arg0_value;
7125
7126 IrInstSrc *panic = ir_build_panic_src(irb, scope, node, arg0_value);
7127 return ir_lval_wrap(irb, scope, panic, lval, result_loc);
7128 }
7129 case BuiltinFnIdPtrCast:
7130 {
7131 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7132 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7133 if (arg0_value == irb->codegen->invalid_inst_src)
7134 return arg0_value;
7135
7136 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7137 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7138 if (arg1_value == irb->codegen->invalid_inst_src)
7139 return arg1_value;
7140
7141 IrInstSrc *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true);
7142 return ir_lval_wrap(irb, scope, ptr_cast, lval, result_loc);
7143 }
7144 case BuiltinFnIdBitCast:
7145 {
7146 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0);
7147 IrInstSrc *dest_type = ir_gen_node(irb, dest_type_node, scope);
7148 if (dest_type == irb->codegen->invalid_inst_src)
7149 return dest_type;
7150
7151 ResultLocBitCast *result_loc_bit_cast = heap::c_allocator.create<ResultLocBitCast>();
7152 result_loc_bit_cast->base.id = ResultLocIdBitCast;
7153 result_loc_bit_cast->base.source_instruction = dest_type;
7154 result_loc_bit_cast->base.allow_write_through_const = result_loc->allow_write_through_const;
7155 ir_ref_instruction(dest_type, irb->current_basic_block);
7156 result_loc_bit_cast->parent = result_loc;
7157
7158 ir_build_reset_result(irb, scope, node, &result_loc_bit_cast->base);
7159
7160 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7161 IrInstSrc *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone,
7162 &result_loc_bit_cast->base);
7163 if (arg1_value == irb->codegen->invalid_inst_src)
7164 return arg1_value;
7165
7166 IrInstSrc *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast);
7167 return ir_lval_wrap(irb, scope, bitcast, lval, result_loc);
7168 }
7169 case BuiltinFnIdAs:
7170 {
7171 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0);
7172 IrInstSrc *dest_type = ir_gen_node(irb, dest_type_node, scope);
7173 if (dest_type == irb->codegen->invalid_inst_src)
7174 return dest_type;
7175
7176 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, dest_type, result_loc);
7177
7178 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7179 IrInstSrc *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone,
7180 &result_loc_cast->base);
7181 if (arg1_value == irb->codegen->invalid_inst_src)
7182 return arg1_value;
7183
7184 IrInstSrc *result = ir_build_implicit_cast(irb, scope, node, arg1_value, result_loc_cast);
7185 return ir_lval_wrap(irb, scope, result, lval, result_loc);
7186 }
7187 case BuiltinFnIdIntToPtr:
7188 {
7189 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7190 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7191 if (arg0_value == irb->codegen->invalid_inst_src)
7192 return arg0_value;
7193
7194 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7195 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7196 if (arg1_value == irb->codegen->invalid_inst_src)
7197 return arg1_value;
7198
7199 IrInstSrc *int_to_ptr = ir_build_int_to_ptr_src(irb, scope, node, arg0_value, arg1_value);
7200 return ir_lval_wrap(irb, scope, int_to_ptr, lval, result_loc);
7201 }
7202 case BuiltinFnIdPtrToInt:
7203 {
7204 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7205 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7206 if (arg0_value == irb->codegen->invalid_inst_src)
7207 return arg0_value;
7208
7209 IrInstSrc *ptr_to_int = ir_build_ptr_to_int_src(irb, scope, node, arg0_value);
7210 return ir_lval_wrap(irb, scope, ptr_to_int, lval, result_loc);
7211 }
7212 case BuiltinFnIdTagName:
7213 {
7214 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7215 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7216 if (arg0_value == irb->codegen->invalid_inst_src)
7217 return arg0_value;
7218
7219 IrInstSrc *tag_name = ir_build_tag_name_src(irb, scope, node, arg0_value);
7220 return ir_lval_wrap(irb, scope, tag_name, lval, result_loc);
7221 }
7222 case BuiltinFnIdFieldParentPtr:
7223 {
7224 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7225 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7226 if (arg0_value == irb->codegen->invalid_inst_src)
7227 return arg0_value;
7228
7229 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7230 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7231 if (arg1_value == irb->codegen->invalid_inst_src)
7232 return arg1_value;
7233
7234 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
7235 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope);
7236 if (arg2_value == irb->codegen->invalid_inst_src)
7237 return arg2_value;
7238
7239 IrInstSrc *field_parent_ptr = ir_build_field_parent_ptr_src(irb, scope, node,
7240 arg0_value, arg1_value, arg2_value);
7241 return ir_lval_wrap(irb, scope, field_parent_ptr, lval, result_loc);
7242 }
7243 case BuiltinFnIdByteOffsetOf:
7244 {
7245 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7246 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7247 if (arg0_value == irb->codegen->invalid_inst_src)
7248 return arg0_value;
7249
7250 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7251 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7252 if (arg1_value == irb->codegen->invalid_inst_src)
7253 return arg1_value;
7254
7255 IrInstSrc *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value);
7256 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc);
7257 }
7258 case BuiltinFnIdBitOffsetOf:
7259 {
7260 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7261 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7262 if (arg0_value == irb->codegen->invalid_inst_src)
7263 return arg0_value;
7264
7265 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7266 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7267 if (arg1_value == irb->codegen->invalid_inst_src)
7268 return arg1_value;
7269
7270 IrInstSrc *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value);
7271 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc);
7272 }
7273 case BuiltinFnIdCall: {
7274 // Cast the options parameter to the options type
7275 ZigType *options_type = get_builtin_type(irb->codegen, "CallOptions");
7276 IrInstSrc *options_type_inst = ir_build_const_type(irb, scope, node, options_type);
7277 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, options_type_inst, no_result_loc());
7278
7279 AstNode *options_node = node->data.fn_call_expr.params.at(0);
7280 IrInstSrc *options_inner = ir_gen_node_extra(irb, options_node, scope,
7281 LValNone, &result_loc_cast->base);
7282 if (options_inner == irb->codegen->invalid_inst_src)
7283 return options_inner;
7284 IrInstSrc *options = ir_build_implicit_cast(irb, scope, options_node, options_inner, result_loc_cast);
7285
7286 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1);
7287 AstNode *args_node = node->data.fn_call_expr.params.at(2);
7288 if (args_node->type == NodeTypeContainerInitExpr) {
7289 if (args_node->data.container_init_expr.kind == ContainerInitKindArray ||
7290 args_node->data.container_init_expr.entries.length == 0)
7291 {
7292 return ir_gen_fn_call_with_args(irb, scope, node,
7293 fn_ref_node, CallModifierNone, options,
7294 args_node->data.container_init_expr.entries.items,
7295 args_node->data.container_init_expr.entries.length,
7296 lval, result_loc);
7297 } else {
7298 exec_add_error_node(irb->codegen, irb->exec, args_node,
7299 buf_sprintf("TODO: @call with anon struct literal"));
7300 return irb->codegen->invalid_inst_src;
7301 }
7302 } else {
7303 IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope);
7304 if (fn_ref == irb->codegen->invalid_inst_src)
7305 return fn_ref;
7306
7307 IrInstSrc *args = ir_gen_node(irb, args_node, scope);
7308 if (args == irb->codegen->invalid_inst_src)
7309 return args;
7310
7311 IrInstSrc *call = ir_build_call_extra(irb, scope, node, options, fn_ref, args, result_loc);
7312 return ir_lval_wrap(irb, scope, call, lval, result_loc);
7313 }
7314 }
7315 case BuiltinFnIdAsyncCall:
7316 return ir_gen_async_call(irb, scope, nullptr, node, lval, result_loc);
7317 case BuiltinFnIdShlExact:
7318 {
7319 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7320 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7321 if (arg0_value == irb->codegen->invalid_inst_src)
7322 return arg0_value;
7323
7324 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7325 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7326 if (arg1_value == irb->codegen->invalid_inst_src)
7327 return arg1_value;
7328
7329 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true);
7330 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
7331 }
7332 case BuiltinFnIdShrExact:
7333 {
7334 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7335 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7336 if (arg0_value == irb->codegen->invalid_inst_src)
7337 return arg0_value;
7338
7339 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7340 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7341 if (arg1_value == irb->codegen->invalid_inst_src)
7342 return arg1_value;
7343
7344 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true);
7345 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc);
7346 }
7347 case BuiltinFnIdSetEvalBranchQuota:
7348 {
7349 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7350 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7351 if (arg0_value == irb->codegen->invalid_inst_src)
7352 return arg0_value;
7353
7354 IrInstSrc *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value);
7355 return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval, result_loc);
7356 }
7357 case BuiltinFnIdAlignCast:
7358 {
7359 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7360 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7361 if (arg0_value == irb->codegen->invalid_inst_src)
7362 return arg0_value;
7363
7364 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7365 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7366 if (arg1_value == irb->codegen->invalid_inst_src)
7367 return arg1_value;
7368
7369 IrInstSrc *align_cast = ir_build_align_cast_src(irb, scope, node, arg0_value, arg1_value);
7370 return ir_lval_wrap(irb, scope, align_cast, lval, result_loc);
7371 }
7372 case BuiltinFnIdThis:
7373 {
7374 IrInstSrc *this_inst = ir_gen_this(irb, scope, node);
7375 return ir_lval_wrap(irb, scope, this_inst, lval, result_loc);
7376 }
7377 case BuiltinFnIdSetAlignStack:
7378 {
7379 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7380 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7381 if (arg0_value == irb->codegen->invalid_inst_src)
7382 return arg0_value;
7383
7384 IrInstSrc *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value);
7385 return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc);
7386 }
7387 case BuiltinFnIdExport:
7388 {
7389 // Cast the options parameter to the options type
7390 ZigType *options_type = get_builtin_type(irb->codegen, "ExportOptions");
7391 IrInstSrc *options_type_inst = ir_build_const_type(irb, scope, node, options_type);
7392 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, options_type_inst, no_result_loc());
7393
7394 AstNode *target_node = node->data.fn_call_expr.params.at(0);
7395 IrInstSrc *target_value = ir_gen_node(irb, target_node, scope);
7396 if (target_value == irb->codegen->invalid_inst_src)
7397 return target_value;
7398
7399 AstNode *options_node = node->data.fn_call_expr.params.at(1);
7400 IrInstSrc *options_value = ir_gen_node_extra(irb, options_node,
7401 scope, LValNone, &result_loc_cast->base);
7402 if (options_value == irb->codegen->invalid_inst_src)
7403 return options_value;
7404
7405 IrInstSrc *casted_options_value = ir_build_implicit_cast(
7406 irb, scope, options_node, options_value, result_loc_cast);
7407
7408 IrInstSrc *ir_export = ir_build_export(irb, scope, node, target_value, casted_options_value);
7409 return ir_lval_wrap(irb, scope, ir_export, lval, result_loc);
7410 }
7411 case BuiltinFnIdExtern:
7412 {
7413 // Cast the options parameter to the options type
7414 ZigType *options_type = get_builtin_type(irb->codegen, "ExternOptions");
7415 IrInstSrc *options_type_inst = ir_build_const_type(irb, scope, node, options_type);
7416 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, options_type_inst, no_result_loc());
7417
7418 AstNode *type_node = node->data.fn_call_expr.params.at(0);
7419 IrInstSrc *type_value = ir_gen_node(irb, type_node, scope);
7420 if (type_value == irb->codegen->invalid_inst_src)
7421 return type_value;
7422
7423 AstNode *options_node = node->data.fn_call_expr.params.at(1);
7424 IrInstSrc *options_value = ir_gen_node_extra(irb, options_node,
7425 scope, LValNone, &result_loc_cast->base);
7426 if (options_value == irb->codegen->invalid_inst_src)
7427 return options_value;
7428
7429 IrInstSrc *casted_options_value = ir_build_implicit_cast(
7430 irb, scope, options_node, options_value, result_loc_cast);
7431
7432 IrInstSrc *ir_extern = ir_build_extern(irb, scope, node, type_value, casted_options_value);
7433 return ir_lval_wrap(irb, scope, ir_extern, lval, result_loc);
7434 }
7435 case BuiltinFnIdErrorReturnTrace:
7436 {
7437 IrInstSrc *error_return_trace = ir_build_error_return_trace_src(irb, scope, node,
7438 IrInstErrorReturnTraceNull);
7439 return ir_lval_wrap(irb, scope, error_return_trace, lval, result_loc);
7440 }
7441 case BuiltinFnIdAtomicRmw:
7442 {
7443 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7444 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7445 if (arg0_value == irb->codegen->invalid_inst_src)
7446 return arg0_value;
7447
7448 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7449 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7450 if (arg1_value == irb->codegen->invalid_inst_src)
7451 return arg1_value;
7452
7453 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
7454 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope);
7455 if (arg2_value == irb->codegen->invalid_inst_src)
7456 return arg2_value;
7457
7458 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
7459 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope);
7460 if (arg3_value == irb->codegen->invalid_inst_src)
7461 return arg3_value;
7462
7463 AstNode *arg4_node = node->data.fn_call_expr.params.at(4);
7464 IrInstSrc *arg4_value = ir_gen_node(irb, arg4_node, scope);
7465 if (arg4_value == irb->codegen->invalid_inst_src)
7466 return arg4_value;
7467
7468 IrInstSrc *inst = ir_build_atomic_rmw_src(irb, scope, node,
7469 arg0_value, arg1_value, arg2_value, arg3_value, arg4_value);
7470 return ir_lval_wrap(irb, scope, inst, lval, result_loc);
7471 }
7472 case BuiltinFnIdAtomicLoad:
7473 {
7474 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7475 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7476 if (arg0_value == irb->codegen->invalid_inst_src)
7477 return arg0_value;
7478
7479 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7480 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7481 if (arg1_value == irb->codegen->invalid_inst_src)
7482 return arg1_value;
7483
7484 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
7485 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope);
7486 if (arg2_value == irb->codegen->invalid_inst_src)
7487 return arg2_value;
7488
7489 IrInstSrc *inst = ir_build_atomic_load_src(irb, scope, node, arg0_value, arg1_value, arg2_value);
7490 return ir_lval_wrap(irb, scope, inst, lval, result_loc);
7491 }
7492 case BuiltinFnIdAtomicStore:
7493 {
7494 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7495 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7496 if (arg0_value == irb->codegen->invalid_inst_src)
7497 return arg0_value;
7498
7499 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7500 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7501 if (arg1_value == irb->codegen->invalid_inst_src)
7502 return arg1_value;
7503
7504 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
7505 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope);
7506 if (arg2_value == irb->codegen->invalid_inst_src)
7507 return arg2_value;
7508
7509 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
7510 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope);
7511 if (arg3_value == irb->codegen->invalid_inst_src)
7512 return arg3_value;
7513
7514 IrInstSrc *inst = ir_build_atomic_store_src(irb, scope, node, arg0_value, arg1_value,
7515 arg2_value, arg3_value);
7516 return ir_lval_wrap(irb, scope, inst, lval, result_loc);
7517 }
7518 case BuiltinFnIdIntToEnum:
7519 {
7520 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7521 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7522 if (arg0_value == irb->codegen->invalid_inst_src)
7523 return arg0_value;
7524
7525 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7526 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7527 if (arg1_value == irb->codegen->invalid_inst_src)
7528 return arg1_value;
7529
7530 IrInstSrc *result = ir_build_int_to_enum_src(irb, scope, node, arg0_value, arg1_value);
7531 return ir_lval_wrap(irb, scope, result, lval, result_loc);
7532 }
7533 case BuiltinFnIdEnumToInt:
7534 {
7535 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7536 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7537 if (arg0_value == irb->codegen->invalid_inst_src)
7538 return arg0_value;
7539
7540 IrInstSrc *result = ir_build_enum_to_int(irb, scope, node, arg0_value);
7541 return ir_lval_wrap(irb, scope, result, lval, result_loc);
7542 }
7543 case BuiltinFnIdCtz:
7544 case BuiltinFnIdPopCount:
7545 case BuiltinFnIdClz:
7546 case BuiltinFnIdBswap:
7547 case BuiltinFnIdBitReverse:
7548 {
7549 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7550 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7551 if (arg0_value == irb->codegen->invalid_inst_src)
7552 return arg0_value;
7553
7554 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7555 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7556 if (arg1_value == irb->codegen->invalid_inst_src)
7557 return arg1_value;
7558
7559 IrInstSrc *result;
7560 switch (builtin_fn->id) {
7561 case BuiltinFnIdCtz:
7562 result = ir_build_ctz(irb, scope, node, arg0_value, arg1_value);
7563 break;
7564 case BuiltinFnIdPopCount:
7565 result = ir_build_pop_count(irb, scope, node, arg0_value, arg1_value);
7566 break;
7567 case BuiltinFnIdClz:
7568 result = ir_build_clz(irb, scope, node, arg0_value, arg1_value);
7569 break;
7570 case BuiltinFnIdBswap:
7571 result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value);
7572 break;
7573 case BuiltinFnIdBitReverse:
7574 result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value);
7575 break;
7576 default:
7577 zig_unreachable();
7578 }
7579 return ir_lval_wrap(irb, scope, result, lval, result_loc);
7580 }
7581 case BuiltinFnIdHasDecl:
7582 {
7583 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7584 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7585 if (arg0_value == irb->codegen->invalid_inst_src)
7586 return arg0_value;
7587
7588 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7589 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7590 if (arg1_value == irb->codegen->invalid_inst_src)
7591 return arg1_value;
7592
7593 IrInstSrc *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value);
7594 return ir_lval_wrap(irb, scope, has_decl, lval, result_loc);
7595 }
7596 case BuiltinFnIdUnionInit:
7597 {
7598 AstNode *union_type_node = node->data.fn_call_expr.params.at(0);
7599 IrInstSrc *union_type_inst = ir_gen_node(irb, union_type_node, scope);
7600 if (union_type_inst == irb->codegen->invalid_inst_src)
7601 return union_type_inst;
7602
7603 AstNode *name_node = node->data.fn_call_expr.params.at(1);
7604 IrInstSrc *name_inst = ir_gen_node(irb, name_node, scope);
7605 if (name_inst == irb->codegen->invalid_inst_src)
7606 return name_inst;
7607
7608 AstNode *init_node = node->data.fn_call_expr.params.at(2);
7609
7610 return ir_gen_union_init_expr(irb, scope, node, union_type_inst, name_inst, init_node,
7611 lval, result_loc);
7612 }
7613 case BuiltinFnIdSrc:
7614 {
7615 IrInstSrc *src_inst = ir_build_src(irb, scope, node);
7616 return ir_lval_wrap(irb, scope, src_inst, lval, result_loc);
7617 }
7618 }
7619 zig_unreachable();
7620}
7621
7622static ScopeNoSuspend *get_scope_nosuspend(Scope *scope) {
7623 while (scope) {
7624 if (scope->id == ScopeIdNoSuspend)
7625 return (ScopeNoSuspend *)scope;
7626 if (scope->id == ScopeIdFnDef)
7627 return nullptr;
7628
7629 scope = scope->parent;
7630 }
7631 return nullptr;
7632}
7633
7634static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
7635 ResultLoc *result_loc)
7636{
7637 assert(node->type == NodeTypeFnCallExpr);
7638
7639 if (node->data.fn_call_expr.modifier == CallModifierBuiltin)
7640 return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc);
7641
7642 bool is_nosuspend = get_scope_nosuspend(scope) != nullptr;
7643 CallModifier modifier = node->data.fn_call_expr.modifier;
7644 if (is_nosuspend && modifier != CallModifierAsync) {
7645 modifier = CallModifierNoSuspend;
7646 }
7647
7648 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
7649 return ir_gen_fn_call_with_args(irb, scope, node, fn_ref_node, modifier,
7650 nullptr, node->data.fn_call_expr.params.items, node->data.fn_call_expr.params.length, lval, result_loc);
7651}
7652
7653static IrInstSrc *ir_gen_if_bool_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
7654 ResultLoc *result_loc)
7655{
7656 assert(node->type == NodeTypeIfBoolExpr);
7657
7658 IrInstSrc *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope);
7659 if (condition == irb->codegen->invalid_inst_src)
7660 return irb->codegen->invalid_inst_src;
7661
7662 IrInstSrc *is_comptime;
7663 if (ir_should_inline(irb->exec, scope)) {
7664 is_comptime = ir_build_const_bool(irb, scope, node, true);
7665 } else {
7666 is_comptime = ir_build_test_comptime(irb, scope, node, condition);
7667 }
7668
7669 AstNode *then_node = node->data.if_bool_expr.then_block;
7670 AstNode *else_node = node->data.if_bool_expr.else_node;
7671
7672 IrBasicBlockSrc *then_block = ir_create_basic_block(irb, scope, "Then");
7673 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "Else");
7674 IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "EndIf");
7675
7676 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, condition,
7677 then_block, else_block, is_comptime);
7678 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block,
7679 result_loc, is_comptime);
7680
7681 ir_set_cursor_at_end_and_append_block(irb, then_block);
7682
7683 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
7684 IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval,
7685 &peer_parent->peers.at(0)->base);
7686 if (then_expr_result == irb->codegen->invalid_inst_src)
7687 return irb->codegen->invalid_inst_src;
7688 IrBasicBlockSrc *after_then_block = irb->current_basic_block;
7689 if (!instr_is_unreachable(then_expr_result))
7690 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
7691
7692 ir_set_cursor_at_end_and_append_block(irb, else_block);
7693 IrInstSrc *else_expr_result;
7694 if (else_node) {
7695 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base);
7696 if (else_expr_result == irb->codegen->invalid_inst_src)
7697 return irb->codegen->invalid_inst_src;
7698 } else {
7699 else_expr_result = ir_build_const_void(irb, scope, node);
7700 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base);
7701 }
7702 IrBasicBlockSrc *after_else_block = irb->current_basic_block;
7703 if (!instr_is_unreachable(else_expr_result))
7704 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
7705
7706 ir_set_cursor_at_end_and_append_block(irb, endif_block);
7707 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
7708 incoming_values[0] = then_expr_result;
7709 incoming_values[1] = else_expr_result;
7710 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
7711 incoming_blocks[0] = after_then_block;
7712 incoming_blocks[1] = after_else_block;
7713
7714 IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
7715 return ir_expr_wrap(irb, scope, phi, result_loc);
7716}
7717
7718static IrInstSrc *ir_gen_prefix_op_id_lval(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) {
7719 assert(node->type == NodeTypePrefixOpExpr);
7720 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
7721
7722 IrInstSrc *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr);
7723 if (value == irb->codegen->invalid_inst_src)
7724 return value;
7725
7726 return ir_build_un_op(irb, scope, node, op_id, value);
7727}
7728
7729static IrInstSrc *ir_gen_prefix_op_id(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrUnOp op_id) {
7730 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone);
7731}
7732
7733static IrInstSrc *ir_expr_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *inst, ResultLoc *result_loc) {
7734 if (inst == irb->codegen->invalid_inst_src) return inst;
7735 ir_build_end_expr(irb, scope, inst->base.source_node, inst, result_loc);
7736 return inst;
7737}
7738
7739static IrInstSrc *ir_lval_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *value, LVal lval,
7740 ResultLoc *result_loc)
7741{
7742 // This logic must be kept in sync with
7743 // [STMT_EXPR_TEST_THING] <--- (search this token)
7744 if (value == irb->codegen->invalid_inst_src ||
7745 instr_is_unreachable(value) ||
7746 value->base.source_node->type == NodeTypeDefer ||
7747 value->id == IrInstSrcIdDeclVar)
7748 {
7749 return value;
7750 }
7751
7752 assert(lval != LValAssign);
7753 if (lval == LValPtr) {
7754 // We needed a pointer to a value, but we got a value. So we create
7755 // an instruction which just makes a pointer of it.
7756 return ir_build_ref_src(irb, scope, value->base.source_node, value);
7757 } else if (result_loc != nullptr) {
7758 return ir_expr_wrap(irb, scope, value, result_loc);
7759 } else {
7760 return value;
7761 }
7762
7763}
7764
7765static PtrLen star_token_to_ptr_len(TokenId token_id) {
7766 switch (token_id) {
7767 case TokenIdStar:
7768 case TokenIdStarStar:
7769 return PtrLenSingle;
7770 case TokenIdLBracket:
7771 return PtrLenUnknown;
7772 case TokenIdSymbol:
7773 return PtrLenC;
7774 default:
7775 zig_unreachable();
7776 }
7777}
7778
7779static IrInstSrc *ir_gen_pointer_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
7780 assert(node->type == NodeTypePointerType);
7781
7782 PtrLen ptr_len = star_token_to_ptr_len(node->data.pointer_type.star_token->id);
7783
7784 bool is_const = node->data.pointer_type.is_const;
7785 bool is_volatile = node->data.pointer_type.is_volatile;
7786 bool is_allow_zero = node->data.pointer_type.allow_zero_token != nullptr;
7787 AstNode *sentinel_expr = node->data.pointer_type.sentinel;
7788 AstNode *expr_node = node->data.pointer_type.op_expr;
7789 AstNode *align_expr = node->data.pointer_type.align_expr;
7790
7791 IrInstSrc *sentinel;
7792 if (sentinel_expr != nullptr) {
7793 sentinel = ir_gen_node(irb, sentinel_expr, scope);
7794 if (sentinel == irb->codegen->invalid_inst_src)
7795 return sentinel;
7796 } else {
7797 sentinel = nullptr;
7798 }
7799
7800 IrInstSrc *align_value;
7801 if (align_expr != nullptr) {
7802 align_value = ir_gen_node(irb, align_expr, scope);
7803 if (align_value == irb->codegen->invalid_inst_src)
7804 return align_value;
7805 } else {
7806 align_value = nullptr;
7807 }
7808
7809 IrInstSrc *child_type = ir_gen_node(irb, expr_node, scope);
7810 if (child_type == irb->codegen->invalid_inst_src)
7811 return child_type;
7812
7813 uint32_t bit_offset_start = 0;
7814 if (node->data.pointer_type.bit_offset_start != nullptr) {
7815 if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_start, 32, false)) {
7816 Buf *val_buf = buf_alloc();
7817 bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_start, 10);
7818 exec_add_error_node(irb->codegen, irb->exec, node,
7819 buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf)));
7820 return irb->codegen->invalid_inst_src;
7821 }
7822 bit_offset_start = bigint_as_u32(node->data.pointer_type.bit_offset_start);
7823 }
7824
7825 uint32_t host_int_bytes = 0;
7826 if (node->data.pointer_type.host_int_bytes != nullptr) {
7827 if (!bigint_fits_in_bits(node->data.pointer_type.host_int_bytes, 32, false)) {
7828 Buf *val_buf = buf_alloc();
7829 bigint_append_buf(val_buf, node->data.pointer_type.host_int_bytes, 10);
7830 exec_add_error_node(irb->codegen, irb->exec, node,
7831 buf_sprintf("value %s too large for u32 byte count", buf_ptr(val_buf)));
7832 return irb->codegen->invalid_inst_src;
7833 }
7834 host_int_bytes = bigint_as_u32(node->data.pointer_type.host_int_bytes);
7835 }
7836
7837 if (host_int_bytes != 0 && bit_offset_start >= host_int_bytes * 8) {
7838 exec_add_error_node(irb->codegen, irb->exec, node,
7839 buf_sprintf("bit offset starts after end of host integer"));
7840 return irb->codegen->invalid_inst_src;
7841 }
7842
7843 return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile,
7844 ptr_len, sentinel, align_value, bit_offset_start, host_int_bytes, is_allow_zero);
7845}
7846
7847static IrInstSrc *ir_gen_catch_unreachable(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
7848 AstNode *expr_node, LVal lval, ResultLoc *result_loc)
7849{
7850 IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
7851 if (err_union_ptr == irb->codegen->invalid_inst_src)
7852 return irb->codegen->invalid_inst_src;
7853
7854 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, scope, source_node, err_union_ptr, true, false);
7855 if (payload_ptr == irb->codegen->invalid_inst_src)
7856 return irb->codegen->invalid_inst_src;
7857
7858 if (lval == LValPtr)
7859 return payload_ptr;
7860
7861 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, source_node, payload_ptr);
7862 return ir_expr_wrap(irb, scope, load_ptr, result_loc);
7863}
7864
7865static IrInstSrc *ir_gen_bool_not(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
7866 assert(node->type == NodeTypePrefixOpExpr);
7867 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
7868
7869 IrInstSrc *value = ir_gen_node(irb, expr_node, scope);
7870 if (value == irb->codegen->invalid_inst_src)
7871 return irb->codegen->invalid_inst_src;
7872
7873 return ir_build_bool_not(irb, scope, node, value);
7874}
7875
7876static IrInstSrc *ir_gen_prefix_op_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
7877 ResultLoc *result_loc)
7878{
7879 assert(node->type == NodeTypePrefixOpExpr);
7880
7881 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op;
7882
7883 switch (prefix_op) {
7884 case PrefixOpInvalid:
7885 zig_unreachable();
7886 case PrefixOpBoolNot:
7887 return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval, result_loc);
7888 case PrefixOpBinNot:
7889 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval, result_loc);
7890 case PrefixOpNegation:
7891 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval, result_loc);
7892 case PrefixOpNegationWrap:
7893 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval, result_loc);
7894 case PrefixOpOptional:
7895 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval, result_loc);
7896 case PrefixOpAddrOf: {
7897 AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
7898 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr), lval, result_loc);
7899 }
7900 }
7901 zig_unreachable();
7902}
7903
7904static IrInstSrc *ir_gen_union_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
7905 IrInstSrc *union_type, IrInstSrc *field_name, AstNode *expr_node,
7906 LVal lval, ResultLoc *parent_result_loc)
7907{
7908 IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, source_node, parent_result_loc, union_type);
7909 IrInstSrc *field_ptr = ir_build_field_ptr_instruction(irb, scope, source_node, container_ptr,
7910 field_name, true);
7911
7912 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
7913 result_loc_inst->base.id = ResultLocIdInstruction;
7914 result_loc_inst->base.source_instruction = field_ptr;
7915 ir_ref_instruction(field_ptr, irb->current_basic_block);
7916 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);
7917
7918 IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone,
7919 &result_loc_inst->base);
7920 if (expr_value == irb->codegen->invalid_inst_src)
7921 return expr_value;
7922
7923 IrInstSrc *init_union = ir_build_union_init_named_field(irb, scope, source_node, union_type,
7924 field_name, field_ptr, container_ptr);
7925
7926 return ir_lval_wrap(irb, scope, init_union, lval, parent_result_loc);
7927}
7928
7929static IrInstSrc *ir_gen_container_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
7930 ResultLoc *parent_result_loc)
7931{
7932 assert(node->type == NodeTypeContainerInitExpr);
7933
7934 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
7935 ContainerInitKind kind = container_init_expr->kind;
7936
7937 ResultLocCast *result_loc_cast = nullptr;
7938 ResultLoc *child_result_loc;
7939 AstNode *init_array_type_source_node;
7940 if (container_init_expr->type != nullptr) {
7941 IrInstSrc *container_type;
7942 if (container_init_expr->type->type == NodeTypeInferredArrayType) {
7943 if (kind == ContainerInitKindStruct) {
7944 add_node_error(irb->codegen, container_init_expr->type,
7945 buf_sprintf("initializing array with struct syntax"));
7946 return irb->codegen->invalid_inst_src;
7947 }
7948 IrInstSrc *sentinel;
7949 if (container_init_expr->type->data.inferred_array_type.sentinel != nullptr) {
7950 sentinel = ir_gen_node(irb, container_init_expr->type->data.inferred_array_type.sentinel, scope);
7951 if (sentinel == irb->codegen->invalid_inst_src)
7952 return sentinel;
7953 } else {
7954 sentinel = nullptr;
7955 }
7956
7957 IrInstSrc *elem_type = ir_gen_node(irb,
7958 container_init_expr->type->data.inferred_array_type.child_type, scope);
7959 if (elem_type == irb->codegen->invalid_inst_src)
7960 return elem_type;
7961 size_t item_count = container_init_expr->entries.length;
7962 IrInstSrc *item_count_inst = ir_build_const_usize(irb, scope, node, item_count);
7963 container_type = ir_build_array_type(irb, scope, node, item_count_inst, sentinel, elem_type);
7964 } else {
7965 container_type = ir_gen_node(irb, container_init_expr->type, scope);
7966 if (container_type == irb->codegen->invalid_inst_src)
7967 return container_type;
7968 }
7969
7970 result_loc_cast = ir_build_cast_result_loc(irb, container_type, parent_result_loc);
7971 child_result_loc = &result_loc_cast->base;
7972 init_array_type_source_node = container_type->base.source_node;
7973 } else {
7974 child_result_loc = parent_result_loc;
7975 if (parent_result_loc->source_instruction != nullptr) {
7976 init_array_type_source_node = parent_result_loc->source_instruction->base.source_node;
7977 } else {
7978 init_array_type_source_node = node;
7979 }
7980 }
7981
7982 switch (kind) {
7983 case ContainerInitKindStruct: {
7984 IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc,
7985 nullptr);
7986
7987 size_t field_count = container_init_expr->entries.length;
7988 IrInstSrcContainerInitFieldsField *fields = heap::c_allocator.allocate<IrInstSrcContainerInitFieldsField>(field_count);
7989 for (size_t i = 0; i < field_count; i += 1) {
7990 AstNode *entry_node = container_init_expr->entries.at(i);
7991 assert(entry_node->type == NodeTypeStructValueField);
7992
7993 Buf *name = entry_node->data.struct_val_field.name;
7994 AstNode *expr_node = entry_node->data.struct_val_field.expr;
7995
7996 IrInstSrc *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true);
7997 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
7998 result_loc_inst->base.id = ResultLocIdInstruction;
7999 result_loc_inst->base.source_instruction = field_ptr;
8000 result_loc_inst->base.allow_write_through_const = true;
8001 ir_ref_instruction(field_ptr, irb->current_basic_block);
8002 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);
8003
8004 IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone,
8005 &result_loc_inst->base);
8006 if (expr_value == irb->codegen->invalid_inst_src)
8007 return expr_value;
8008
8009 fields[i].name = name;
8010 fields[i].source_node = entry_node;
8011 fields[i].result_loc = field_ptr;
8012 }
8013 IrInstSrc *result = ir_build_container_init_fields(irb, scope, node, field_count,
8014 fields, container_ptr);
8015
8016 if (result_loc_cast != nullptr) {
8017 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast);
8018 }
8019 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc);
8020 }
8021 case ContainerInitKindArray: {
8022 size_t item_count = container_init_expr->entries.length;
8023
8024 IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc,
8025 nullptr);
8026
8027 IrInstSrc **result_locs = heap::c_allocator.allocate<IrInstSrc *>(item_count);
8028 for (size_t i = 0; i < item_count; i += 1) {
8029 AstNode *expr_node = container_init_expr->entries.at(i);
8030
8031 IrInstSrc *elem_index = ir_build_const_usize(irb, scope, expr_node, i);
8032 IrInstSrc *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr,
8033 elem_index, false, PtrLenSingle, init_array_type_source_node);
8034 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
8035 result_loc_inst->base.id = ResultLocIdInstruction;
8036 result_loc_inst->base.source_instruction = elem_ptr;
8037 result_loc_inst->base.allow_write_through_const = true;
8038 ir_ref_instruction(elem_ptr, irb->current_basic_block);
8039 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);
8040
8041 IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone,
8042 &result_loc_inst->base);
8043 if (expr_value == irb->codegen->invalid_inst_src)
8044 return expr_value;
8045
8046 result_locs[i] = elem_ptr;
8047 }
8048 IrInstSrc *result = ir_build_container_init_list(irb, scope, node, item_count,
8049 result_locs, container_ptr, init_array_type_source_node);
8050 if (result_loc_cast != nullptr) {
8051 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast);
8052 }
8053 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc);
8054 }
8055 }
8056 zig_unreachable();
8057}
8058
8059static ResultLocVar *ir_build_var_result_loc(IrBuilderSrc *irb, IrInstSrc *alloca, ZigVar *var) {
8060 ResultLocVar *result_loc_var = heap::c_allocator.create<ResultLocVar>();
8061 result_loc_var->base.id = ResultLocIdVar;
8062 result_loc_var->base.source_instruction = alloca;
8063 result_loc_var->base.allow_write_through_const = true;
8064 result_loc_var->var = var;
8065
8066 ir_build_reset_result(irb, alloca->base.scope, alloca->base.source_node, &result_loc_var->base);
8067
8068 return result_loc_var;
8069}
8070
8071static ResultLocCast *ir_build_cast_result_loc(IrBuilderSrc *irb, IrInstSrc *dest_type,
8072 ResultLoc *parent_result_loc)
8073{
8074 ResultLocCast *result_loc_cast = heap::c_allocator.create<ResultLocCast>();
8075 result_loc_cast->base.id = ResultLocIdCast;
8076 result_loc_cast->base.source_instruction = dest_type;
8077 result_loc_cast->base.allow_write_through_const = parent_result_loc->allow_write_through_const;
8078 ir_ref_instruction(dest_type, irb->current_basic_block);
8079 result_loc_cast->parent = parent_result_loc;
8080
8081 ir_build_reset_result(irb, dest_type->base.scope, dest_type->base.source_node, &result_loc_cast->base);
8082
8083 return result_loc_cast;
8084}
8085
8086static void build_decl_var_and_init(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var,
8087 IrInstSrc *init, const char *name_hint, IrInstSrc *is_comptime)
8088{
8089 IrInstSrc *alloca = ir_build_alloca_src(irb, scope, source_node, nullptr, name_hint, is_comptime);
8090 ResultLocVar *var_result_loc = ir_build_var_result_loc(irb, alloca, var);
8091 ir_build_end_expr(irb, scope, source_node, init, &var_result_loc->base);
8092 ir_build_var_decl_src(irb, scope, source_node, var, nullptr, alloca);
8093}
8094
8095static IrInstSrc *ir_gen_var_decl(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
8096 assert(node->type == NodeTypeVariableDeclaration);
8097
8098 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration;
8099
8100 if (buf_eql_str(variable_declaration->symbol, "_")) {
8101 add_node_error(irb->codegen, node, buf_sprintf("`_` is not a declarable symbol"));
8102 return irb->codegen->invalid_inst_src;
8103 }
8104
8105 // Used for the type expr and the align expr
8106 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope);
8107
8108 IrInstSrc *type_instruction;
8109 if (variable_declaration->type != nullptr) {
8110 type_instruction = ir_gen_node(irb, variable_declaration->type, comptime_scope);
8111 if (type_instruction == irb->codegen->invalid_inst_src)
8112 return type_instruction;
8113 } else {
8114 type_instruction = nullptr;
8115 }
8116
8117 bool is_shadowable = false;
8118 bool is_const = variable_declaration->is_const;
8119 bool is_extern = variable_declaration->is_extern;
8120
8121 bool is_comptime_scalar = ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime;
8122 IrInstSrc *is_comptime = ir_build_const_bool(irb, scope, node, is_comptime_scalar);
8123 ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol,
8124 is_const, is_const, is_shadowable, is_comptime);
8125 // we detect IrInstSrcDeclVar in gen_block to make sure the next node
8126 // is inside var->child_scope
8127
8128 if (!is_extern && !variable_declaration->expr) {
8129 var->var_type = irb->codegen->builtin_types.entry_invalid;
8130 add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized"));
8131 return irb->codegen->invalid_inst_src;
8132 }
8133
8134 IrInstSrc *align_value = nullptr;
8135 if (variable_declaration->align_expr != nullptr) {
8136 align_value = ir_gen_node(irb, variable_declaration->align_expr, comptime_scope);
8137 if (align_value == irb->codegen->invalid_inst_src)
8138 return align_value;
8139 }
8140
8141 if (variable_declaration->section_expr != nullptr) {
8142 add_node_error(irb->codegen, variable_declaration->section_expr,
8143 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol)));
8144 }
8145
8146 // Parser should ensure that this never happens
8147 assert(variable_declaration->threadlocal_tok == nullptr);
8148
8149 IrInstSrc *alloca = ir_build_alloca_src(irb, scope, node, align_value,
8150 buf_ptr(variable_declaration->symbol), is_comptime);
8151
8152 // Create a result location for the initialization expression.
8153 ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var);
8154 ResultLoc *init_result_loc;
8155 ResultLocCast *result_loc_cast;
8156 if (type_instruction != nullptr) {
8157 result_loc_cast = ir_build_cast_result_loc(irb, type_instruction, &result_loc_var->base);
8158 init_result_loc = &result_loc_cast->base;
8159 } else {
8160 result_loc_cast = nullptr;
8161 init_result_loc = &result_loc_var->base;
8162 }
8163
8164 Scope *init_scope = is_comptime_scalar ?
8165 create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope;
8166
8167 // Temporarily set the name of the IrExecutableSrc to the VariableDeclaration
8168 // so that the struct or enum from the init expression inherits the name.
8169 Buf *old_exec_name = irb->exec->name;
8170 irb->exec->name = variable_declaration->symbol;
8171 IrInstSrc *init_value = ir_gen_node_extra(irb, variable_declaration->expr, init_scope,
8172 LValNone, init_result_loc);
8173 irb->exec->name = old_exec_name;
8174
8175 if (init_value == irb->codegen->invalid_inst_src)
8176 return irb->codegen->invalid_inst_src;
8177
8178 if (result_loc_cast != nullptr) {
8179 IrInstSrc *implicit_cast = ir_build_implicit_cast(irb, scope, init_value->base.source_node,
8180 init_value, result_loc_cast);
8181 ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base);
8182 }
8183
8184 return ir_build_var_decl_src(irb, scope, node, var, align_value, alloca);
8185}
8186
8187static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
8188 ResultLoc *result_loc)
8189{
8190 assert(node->type == NodeTypeWhileExpr);
8191
8192 AstNode *continue_expr_node = node->data.while_expr.continue_expr;
8193 AstNode *else_node = node->data.while_expr.else_node;
8194
8195 IrBasicBlockSrc *cond_block = ir_create_basic_block(irb, scope, "WhileCond");
8196 IrBasicBlockSrc *body_block = ir_create_basic_block(irb, scope, "WhileBody");
8197 IrBasicBlockSrc *continue_block = continue_expr_node ?
8198 ir_create_basic_block(irb, scope, "WhileContinue") : cond_block;
8199 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, scope, "WhileEnd");
8200 IrBasicBlockSrc *else_block = else_node ?
8201 ir_create_basic_block(irb, scope, "WhileElse") : end_block;
8202
8203 IrInstSrc *is_comptime = ir_build_const_bool(irb, scope, node,
8204 ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline);
8205 ir_build_br(irb, scope, node, cond_block, is_comptime);
8206
8207 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
8208 Buf *var_symbol = node->data.while_expr.var_symbol;
8209 Buf *err_symbol = node->data.while_expr.err_symbol;
8210 if (err_symbol != nullptr) {
8211 ir_set_cursor_at_end_and_append_block(irb, cond_block);
8212
8213 Scope *payload_scope;
8214 AstNode *symbol_node = node; // TODO make more accurate
8215 ZigVar *payload_var;
8216 if (var_symbol) {
8217 // TODO make it an error to write to payload variable
8218 payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol,
8219 true, false, false, is_comptime);
8220 payload_scope = payload_var->child_scope;
8221 } else {
8222 payload_scope = subexpr_scope;
8223 }
8224 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, payload_scope);
8225 IrInstSrc *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope,
8226 LValPtr, nullptr);
8227 if (err_val_ptr == irb->codegen->invalid_inst_src)
8228 return err_val_ptr;
8229 IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr,
8230 true, false);
8231 IrBasicBlockSrc *after_cond_block = irb->current_basic_block;
8232 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));
8233 IrInstSrc *cond_br_inst;
8234 if (!instr_is_unreachable(is_err)) {
8235 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err,
8236 else_block, body_block, is_comptime);
8237 cond_br_inst->is_gen = true;
8238 } else {
8239 // for the purposes of the source instruction to ir_build_result_peers
8240 cond_br_inst = irb->current_basic_block->instruction_list.last();
8241 }
8242
8243 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc,
8244 is_comptime);
8245
8246 ir_set_cursor_at_end_and_append_block(irb, body_block);
8247 if (var_symbol) {
8248 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, &spill_scope->base, symbol_node,
8249 err_val_ptr, false, false);
8250 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ?
8251 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, symbol_node, payload_ptr);
8252 build_decl_var_and_init(irb, payload_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime);
8253 }
8254
8255 ZigList<IrInstSrc *> incoming_values = {0};
8256 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
8257
8258 if (is_duplicate_label(irb->codegen, payload_scope, node, node->data.while_expr.name))
8259 return irb->codegen->invalid_inst_src;
8260
8261 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope);
8262 loop_scope->break_block = end_block;
8263 loop_scope->continue_block = continue_block;
8264 loop_scope->is_comptime = is_comptime;
8265 loop_scope->incoming_blocks = &incoming_blocks;
8266 loop_scope->incoming_values = &incoming_values;
8267 loop_scope->lval = lval;
8268 loop_scope->peer_parent = peer_parent;
8269 loop_scope->spill_scope = spill_scope;
8270
8271 // Note the body block of the loop is not the place that lval and result_loc are used -
8272 // it's actually in break statements, handled similarly to return statements.
8273 // That is why we set those values in loop_scope above and not in this ir_gen_node call.
8274 IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base);
8275 if (body_result == irb->codegen->invalid_inst_src)
8276 return body_result;
8277
8278 if (loop_scope->name != nullptr && loop_scope->name_used == false) {
8279 add_node_error(irb->codegen, node, buf_sprintf("unused while label"));
8280 }
8281
8282 if (!instr_is_unreachable(body_result)) {
8283 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result));
8284 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime));
8285 }
8286
8287 if (continue_expr_node) {
8288 ir_set_cursor_at_end_and_append_block(irb, continue_block);
8289 IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, payload_scope);
8290 if (expr_result == irb->codegen->invalid_inst_src)
8291 return expr_result;
8292 if (!instr_is_unreachable(expr_result)) {
8293 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, continue_expr_node, expr_result));
8294 ir_mark_gen(ir_build_br(irb, payload_scope, node, cond_block, is_comptime));
8295 }
8296 }
8297
8298 ir_set_cursor_at_end_and_append_block(irb, else_block);
8299 assert(else_node != nullptr);
8300
8301 // TODO make it an error to write to error variable
8302 AstNode *err_symbol_node = else_node; // TODO make more accurate
8303 ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol,
8304 true, false, false, is_comptime);
8305 Scope *err_scope = err_var->child_scope;
8306 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, err_symbol_node, err_val_ptr);
8307 IrInstSrc *err_value = ir_build_load_ptr(irb, err_scope, err_symbol_node, err_ptr);
8308 build_decl_var_and_init(irb, err_scope, err_symbol_node, err_var, err_value, buf_ptr(err_symbol), is_comptime);
8309
8310 if (peer_parent->peers.length != 0) {
8311 peer_parent->peers.last()->next_bb = else_block;
8312 }
8313 ResultLocPeer *peer_result = create_peer_result(peer_parent);
8314 peer_parent->peers.append(peer_result);
8315 IrInstSrc *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_result->base);
8316 if (else_result == irb->codegen->invalid_inst_src)
8317 return else_result;
8318 if (!instr_is_unreachable(else_result))
8319 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime));
8320 IrBasicBlockSrc *after_else_block = irb->current_basic_block;
8321 ir_set_cursor_at_end_and_append_block(irb, end_block);
8322 if (else_result) {
8323 incoming_blocks.append(after_else_block);
8324 incoming_values.append(else_result);
8325 } else {
8326 incoming_blocks.append(after_cond_block);
8327 incoming_values.append(void_else_result);
8328 }
8329 if (peer_parent->peers.length != 0) {
8330 peer_parent->peers.last()->next_bb = end_block;
8331 }
8332
8333 IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length,
8334 incoming_blocks.items, incoming_values.items, peer_parent);
8335 return ir_expr_wrap(irb, scope, phi, result_loc);
8336 } else if (var_symbol != nullptr) {
8337 ir_set_cursor_at_end_and_append_block(irb, cond_block);
8338 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
8339 // TODO make it an error to write to payload variable
8340 AstNode *symbol_node = node; // TODO make more accurate
8341
8342 ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol,
8343 true, false, false, is_comptime);
8344 Scope *child_scope = payload_var->child_scope;
8345 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, child_scope);
8346 IrInstSrc *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope,
8347 LValPtr, nullptr);
8348 if (maybe_val_ptr == irb->codegen->invalid_inst_src)
8349 return maybe_val_ptr;
8350 IrInstSrc *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr);
8351 IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, scope, node->data.while_expr.condition, maybe_val);
8352 IrBasicBlockSrc *after_cond_block = irb->current_basic_block;
8353 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));
8354 IrInstSrc *cond_br_inst;
8355 if (!instr_is_unreachable(is_non_null)) {
8356 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null,
8357 body_block, else_block, is_comptime);
8358 cond_br_inst->is_gen = true;
8359 } else {
8360 // for the purposes of the source instruction to ir_build_result_peers
8361 cond_br_inst = irb->current_basic_block->instruction_list.last();
8362 }
8363
8364 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc,
8365 is_comptime);
8366
8367 ir_set_cursor_at_end_and_append_block(irb, body_block);
8368 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, &spill_scope->base, symbol_node, maybe_val_ptr, false);
8369 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ?
8370 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, symbol_node, payload_ptr);
8371 build_decl_var_and_init(irb, child_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime);
8372
8373 ZigList<IrInstSrc *> incoming_values = {0};
8374 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
8375
8376 if (is_duplicate_label(irb->codegen, child_scope, node, node->data.while_expr.name))
8377 return irb->codegen->invalid_inst_src;
8378
8379 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);
8380 loop_scope->break_block = end_block;
8381 loop_scope->continue_block = continue_block;
8382 loop_scope->is_comptime = is_comptime;
8383 loop_scope->incoming_blocks = &incoming_blocks;
8384 loop_scope->incoming_values = &incoming_values;
8385 loop_scope->lval = lval;
8386 loop_scope->peer_parent = peer_parent;
8387 loop_scope->spill_scope = spill_scope;
8388
8389 // Note the body block of the loop is not the place that lval and result_loc are used -
8390 // it's actually in break statements, handled similarly to return statements.
8391 // That is why we set those values in loop_scope above and not in this ir_gen_node call.
8392 IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base);
8393 if (body_result == irb->codegen->invalid_inst_src)
8394 return body_result;
8395
8396 if (loop_scope->name != nullptr && loop_scope->name_used == false) {
8397 add_node_error(irb->codegen, node, buf_sprintf("unused while label"));
8398 }
8399
8400 if (!instr_is_unreachable(body_result)) {
8401 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result));
8402 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));
8403 }
8404
8405 if (continue_expr_node) {
8406 ir_set_cursor_at_end_and_append_block(irb, continue_block);
8407 IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, child_scope);
8408 if (expr_result == irb->codegen->invalid_inst_src)
8409 return expr_result;
8410 if (!instr_is_unreachable(expr_result)) {
8411 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, continue_expr_node, expr_result));
8412 ir_mark_gen(ir_build_br(irb, child_scope, node, cond_block, is_comptime));
8413 }
8414 }
8415
8416 IrInstSrc *else_result = nullptr;
8417 if (else_node) {
8418 ir_set_cursor_at_end_and_append_block(irb, else_block);
8419
8420 if (peer_parent->peers.length != 0) {
8421 peer_parent->peers.last()->next_bb = else_block;
8422 }
8423 ResultLocPeer *peer_result = create_peer_result(peer_parent);
8424 peer_parent->peers.append(peer_result);
8425 else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_result->base);
8426 if (else_result == irb->codegen->invalid_inst_src)
8427 return else_result;
8428 if (!instr_is_unreachable(else_result))
8429 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime));
8430 }
8431 IrBasicBlockSrc *after_else_block = irb->current_basic_block;
8432 ir_set_cursor_at_end_and_append_block(irb, end_block);
8433 if (else_result) {
8434 incoming_blocks.append(after_else_block);
8435 incoming_values.append(else_result);
8436 } else {
8437 incoming_blocks.append(after_cond_block);
8438 incoming_values.append(void_else_result);
8439 }
8440 if (peer_parent->peers.length != 0) {
8441 peer_parent->peers.last()->next_bb = end_block;
8442 }
8443
8444 IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length,
8445 incoming_blocks.items, incoming_values.items, peer_parent);
8446 return ir_expr_wrap(irb, scope, phi, result_loc);
8447 } else {
8448 ir_set_cursor_at_end_and_append_block(irb, cond_block);
8449 IrInstSrc *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope);
8450 if (cond_val == irb->codegen->invalid_inst_src)
8451 return cond_val;
8452 IrBasicBlockSrc *after_cond_block = irb->current_basic_block;
8453 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));
8454 IrInstSrc *cond_br_inst;
8455 if (!instr_is_unreachable(cond_val)) {
8456 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val,
8457 body_block, else_block, is_comptime);
8458 cond_br_inst->is_gen = true;
8459 } else {
8460 // for the purposes of the source instruction to ir_build_result_peers
8461 cond_br_inst = irb->current_basic_block->instruction_list.last();
8462 }
8463
8464 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc,
8465 is_comptime);
8466 ir_set_cursor_at_end_and_append_block(irb, body_block);
8467
8468 ZigList<IrInstSrc *> incoming_values = {0};
8469 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
8470
8471 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
8472
8473 if (is_duplicate_label(irb->codegen, subexpr_scope, node, node->data.while_expr.name))
8474 return irb->codegen->invalid_inst_src;
8475
8476 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope);
8477 loop_scope->break_block = end_block;
8478 loop_scope->continue_block = continue_block;
8479 loop_scope->is_comptime = is_comptime;
8480 loop_scope->incoming_blocks = &incoming_blocks;
8481 loop_scope->incoming_values = &incoming_values;
8482 loop_scope->lval = lval;
8483 loop_scope->peer_parent = peer_parent;
8484
8485 // Note the body block of the loop is not the place that lval and result_loc are used -
8486 // it's actually in break statements, handled similarly to return statements.
8487 // That is why we set those values in loop_scope above and not in this ir_gen_node call.
8488 IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base);
8489 if (body_result == irb->codegen->invalid_inst_src)
8490 return body_result;
8491
8492 if (loop_scope->name != nullptr && loop_scope->name_used == false) {
8493 add_node_error(irb->codegen, node, buf_sprintf("unused while label"));
8494 }
8495
8496 if (!instr_is_unreachable(body_result)) {
8497 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result));
8498 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime));
8499 }
8500
8501 if (continue_expr_node) {
8502 ir_set_cursor_at_end_and_append_block(irb, continue_block);
8503 IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, subexpr_scope);
8504 if (expr_result == irb->codegen->invalid_inst_src)
8505 return expr_result;
8506 if (!instr_is_unreachable(expr_result)) {
8507 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, continue_expr_node, expr_result));
8508 ir_mark_gen(ir_build_br(irb, scope, node, cond_block, is_comptime));
8509 }
8510 }
8511
8512 IrInstSrc *else_result = nullptr;
8513 if (else_node) {
8514 ir_set_cursor_at_end_and_append_block(irb, else_block);
8515
8516 if (peer_parent->peers.length != 0) {
8517 peer_parent->peers.last()->next_bb = else_block;
8518 }
8519 ResultLocPeer *peer_result = create_peer_result(peer_parent);
8520 peer_parent->peers.append(peer_result);
8521
8522 else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_result->base);
8523 if (else_result == irb->codegen->invalid_inst_src)
8524 return else_result;
8525 if (!instr_is_unreachable(else_result))
8526 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime));
8527 }
8528 IrBasicBlockSrc *after_else_block = irb->current_basic_block;
8529 ir_set_cursor_at_end_and_append_block(irb, end_block);
8530 if (else_result) {
8531 incoming_blocks.append(after_else_block);
8532 incoming_values.append(else_result);
8533 } else {
8534 incoming_blocks.append(after_cond_block);
8535 incoming_values.append(void_else_result);
8536 }
8537 if (peer_parent->peers.length != 0) {
8538 peer_parent->peers.last()->next_bb = end_block;
8539 }
8540
8541 IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length,
8542 incoming_blocks.items, incoming_values.items, peer_parent);
8543 return ir_expr_wrap(irb, scope, phi, result_loc);
8544 }
8545}
8546
8547static IrInstSrc *ir_gen_for_expr(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval,
8548 ResultLoc *result_loc)
8549{
8550 assert(node->type == NodeTypeForExpr);
8551
8552 AstNode *array_node = node->data.for_expr.array_expr;
8553 AstNode *elem_node = node->data.for_expr.elem_node;
8554 AstNode *index_node = node->data.for_expr.index_node;
8555 AstNode *body_node = node->data.for_expr.body;
8556 AstNode *else_node = node->data.for_expr.else_node;
8557
8558 if (!elem_node) {
8559 add_node_error(irb->codegen, node, buf_sprintf("for loop expression missing element parameter"));
8560 return irb->codegen->invalid_inst_src;
8561 }
8562 assert(elem_node->type == NodeTypeSymbol);
8563
8564 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, parent_scope);
8565
8566 IrInstSrc *array_val_ptr = ir_gen_node_extra(irb, array_node, &spill_scope->base, LValPtr, nullptr);
8567 if (array_val_ptr == irb->codegen->invalid_inst_src)
8568 return array_val_ptr;
8569
8570 IrInstSrc *is_comptime = ir_build_const_bool(irb, parent_scope, node,
8571 ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline);
8572
8573 AstNode *index_var_source_node;
8574 ZigVar *index_var;
8575 const char *index_var_name;
8576 if (index_node) {
8577 index_var_source_node = index_node;
8578 Buf *index_var_name_buf = index_node->data.symbol_expr.symbol;
8579 index_var = ir_create_var(irb, index_node, parent_scope, index_var_name_buf, true, false, false, is_comptime);
8580 index_var_name = buf_ptr(index_var_name_buf);
8581 } else {
8582 index_var_source_node = node;
8583 index_var = ir_create_var(irb, node, parent_scope, nullptr, true, false, true, is_comptime);
8584 index_var_name = "i";
8585 }
8586
8587 IrInstSrc *zero = ir_build_const_usize(irb, parent_scope, node, 0);
8588 build_decl_var_and_init(irb, parent_scope, index_var_source_node, index_var, zero, index_var_name, is_comptime);
8589 parent_scope = index_var->child_scope;
8590
8591 IrInstSrc *one = ir_build_const_usize(irb, parent_scope, node, 1);
8592 IrInstSrc *index_ptr = ir_build_var_ptr(irb, parent_scope, node, index_var);
8593
8594
8595 IrBasicBlockSrc *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond");
8596 IrBasicBlockSrc *body_block = ir_create_basic_block(irb, parent_scope, "ForBody");
8597 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd");
8598 IrBasicBlockSrc *else_block = else_node ? ir_create_basic_block(irb, parent_scope, "ForElse") : end_block;
8599 IrBasicBlockSrc *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue");
8600
8601 Buf *len_field_name = buf_create_from_str("len");
8602 IrInstSrc *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name, false);
8603 IrInstSrc *len_val = ir_build_load_ptr(irb, &spill_scope->base, node, len_ref);
8604 ir_build_br(irb, parent_scope, node, cond_block, is_comptime);
8605
8606 ir_set_cursor_at_end_and_append_block(irb, cond_block);
8607 IrInstSrc *index_val = ir_build_load_ptr(irb, &spill_scope->base, node, index_ptr);
8608 IrInstSrc *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
8609 IrBasicBlockSrc *after_cond_block = irb->current_basic_block;
8610 IrInstSrc *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node));
8611 IrInstSrc *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond,
8612 body_block, else_block, is_comptime));
8613
8614 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, is_comptime);
8615
8616 ir_set_cursor_at_end_and_append_block(irb, body_block);
8617 IrInstSrc *elem_ptr = ir_build_elem_ptr(irb, &spill_scope->base, node, array_val_ptr, index_val,
8618 false, PtrLenSingle, nullptr);
8619 // TODO make it an error to write to element variable or i variable.
8620 Buf *elem_var_name = elem_node->data.symbol_expr.symbol;
8621 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime);
8622 Scope *child_scope = elem_var->child_scope;
8623
8624 IrInstSrc *elem_value = node->data.for_expr.elem_is_ptr ?
8625 elem_ptr : ir_build_load_ptr(irb, &spill_scope->base, elem_node, elem_ptr);
8626 build_decl_var_and_init(irb, parent_scope, elem_node, elem_var, elem_value, buf_ptr(elem_var_name), is_comptime);
8627
8628 if (is_duplicate_label(irb->codegen, child_scope, node, node->data.for_expr.name))
8629 return irb->codegen->invalid_inst_src;
8630
8631 ZigList<IrInstSrc *> incoming_values = {0};
8632 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
8633 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);
8634 loop_scope->break_block = end_block;
8635 loop_scope->continue_block = continue_block;
8636 loop_scope->is_comptime = is_comptime;
8637 loop_scope->incoming_blocks = &incoming_blocks;
8638 loop_scope->incoming_values = &incoming_values;
8639 loop_scope->lval = LValNone;
8640 loop_scope->peer_parent = peer_parent;
8641 loop_scope->spill_scope = spill_scope;
8642
8643 // Note the body block of the loop is not the place that lval and result_loc are used -
8644 // it's actually in break statements, handled similarly to return statements.
8645 // That is why we set those values in loop_scope above and not in this ir_gen_node call.
8646 IrInstSrc *body_result = ir_gen_node(irb, body_node, &loop_scope->base);
8647 if (body_result == irb->codegen->invalid_inst_src)
8648 return irb->codegen->invalid_inst_src;
8649
8650 if (loop_scope->name != nullptr && loop_scope->name_used == false) {
8651 add_node_error(irb->codegen, node, buf_sprintf("unused for label"));
8652 }
8653
8654 if (!instr_is_unreachable(body_result)) {
8655 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result));
8656 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));
8657 }
8658
8659 ir_set_cursor_at_end_and_append_block(irb, continue_block);
8660 IrInstSrc *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false);
8661 ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)->allow_write_through_const = true;
8662 ir_build_br(irb, child_scope, node, cond_block, is_comptime);
8663
8664 IrInstSrc *else_result = nullptr;
8665 if (else_node) {
8666 ir_set_cursor_at_end_and_append_block(irb, else_block);
8667
8668 if (peer_parent->peers.length != 0) {
8669 peer_parent->peers.last()->next_bb = else_block;
8670 }
8671 ResultLocPeer *peer_result = create_peer_result(peer_parent);
8672 peer_parent->peers.append(peer_result);
8673 else_result = ir_gen_node_extra(irb, else_node, parent_scope, LValNone, &peer_result->base);
8674 if (else_result == irb->codegen->invalid_inst_src)
8675 return else_result;
8676 if (!instr_is_unreachable(else_result))
8677 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime));
8678 }
8679 IrBasicBlockSrc *after_else_block = irb->current_basic_block;
8680 ir_set_cursor_at_end_and_append_block(irb, end_block);
8681
8682 if (else_result) {
8683 incoming_blocks.append(after_else_block);
8684 incoming_values.append(else_result);
8685 } else {
8686 incoming_blocks.append(after_cond_block);
8687 incoming_values.append(void_else_value);
8688 }
8689 if (peer_parent->peers.length != 0) {
8690 peer_parent->peers.last()->next_bb = end_block;
8691 }
8692
8693 IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length,
8694 incoming_blocks.items, incoming_values.items, peer_parent);
8695 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc);
8696}
8697
8698static IrInstSrc *ir_gen_bool_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
8699 assert(node->type == NodeTypeBoolLiteral);
8700 return ir_build_const_bool(irb, scope, node, node->data.bool_literal.value);
8701}
8702
8703static IrInstSrc *ir_gen_enum_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
8704 assert(node->type == NodeTypeEnumLiteral);
8705 Buf *name = &node->data.enum_literal.identifier->data.str_lit.str;
8706 return ir_build_const_enum_literal(irb, scope, node, name);
8707}
8708
8709static IrInstSrc *ir_gen_string_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
8710 assert(node->type == NodeTypeStringLiteral);
8711
8712 return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf);
8713}
8714
8715static IrInstSrc *ir_gen_array_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
8716 assert(node->type == NodeTypeArrayType);
8717
8718 AstNode *size_node = node->data.array_type.size;
8719 AstNode *child_type_node = node->data.array_type.child_type;
8720 bool is_const = node->data.array_type.is_const;
8721 bool is_volatile = node->data.array_type.is_volatile;
8722 bool is_allow_zero = node->data.array_type.allow_zero_token != nullptr;
8723 AstNode *sentinel_expr = node->data.array_type.sentinel;
8724 AstNode *align_expr = node->data.array_type.align_expr;
8725
8726 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope);
8727
8728 IrInstSrc *sentinel;
8729 if (sentinel_expr != nullptr) {
8730 sentinel = ir_gen_node(irb, sentinel_expr, comptime_scope);
8731 if (sentinel == irb->codegen->invalid_inst_src)
8732 return sentinel;
8733 } else {
8734 sentinel = nullptr;
8735 }
8736
8737 if (size_node) {
8738 if (is_const) {
8739 add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type"));
8740 return irb->codegen->invalid_inst_src;
8741 }
8742 if (is_volatile) {
8743 add_node_error(irb->codegen, node, buf_create_from_str("volatile qualifier invalid on array type"));
8744 return irb->codegen->invalid_inst_src;
8745 }
8746 if (is_allow_zero) {
8747 add_node_error(irb->codegen, node, buf_create_from_str("allowzero qualifier invalid on array type"));
8748 return irb->codegen->invalid_inst_src;
8749 }
8750 if (align_expr != nullptr) {
8751 add_node_error(irb->codegen, node, buf_create_from_str("align qualifier invalid on array type"));
8752 return irb->codegen->invalid_inst_src;
8753 }
8754
8755 IrInstSrc *size_value = ir_gen_node(irb, size_node, comptime_scope);
8756 if (size_value == irb->codegen->invalid_inst_src)
8757 return size_value;
8758
8759 IrInstSrc *child_type = ir_gen_node(irb, child_type_node, comptime_scope);
8760 if (child_type == irb->codegen->invalid_inst_src)
8761 return child_type;
8762
8763 return ir_build_array_type(irb, scope, node, size_value, sentinel, child_type);
8764 } else {
8765 IrInstSrc *align_value;
8766 if (align_expr != nullptr) {
8767 align_value = ir_gen_node(irb, align_expr, comptime_scope);
8768 if (align_value == irb->codegen->invalid_inst_src)
8769 return align_value;
8770 } else {
8771 align_value = nullptr;
8772 }
8773
8774 IrInstSrc *child_type = ir_gen_node(irb, child_type_node, comptime_scope);
8775 if (child_type == irb->codegen->invalid_inst_src)
8776 return child_type;
8777
8778 return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, sentinel,
8779 align_value, is_allow_zero);
8780 }
8781}
8782
8783static IrInstSrc *ir_gen_anyframe_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
8784 assert(node->type == NodeTypeAnyFrameType);
8785
8786 AstNode *payload_type_node = node->data.anyframe_type.payload_type;
8787 IrInstSrc *payload_type_value = nullptr;
8788
8789 if (payload_type_node != nullptr) {
8790 payload_type_value = ir_gen_node(irb, payload_type_node, scope);
8791 if (payload_type_value == irb->codegen->invalid_inst_src)
8792 return payload_type_value;
8793
8794 }
8795
8796 return ir_build_anyframe_type(irb, scope, node, payload_type_value);
8797}
8798
8799static IrInstSrc *ir_gen_undefined_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
8800 assert(node->type == NodeTypeUndefinedLiteral);
8801 return ir_build_const_undefined(irb, scope, node);
8802}
8803
8804static Error parse_asm_template(IrAnalyze *ira, AstNode *source_node, Buf *asm_template,
8805 ZigList<AsmToken> *tok_list)
8806{
8807 // TODO Connect the errors in this function back up to the actual source location
8808 // rather than just the token. https://github.com/ziglang/zig/issues/2080
8809 enum State {
8810 StateStart,
8811 StatePercent,
8812 StateTemplate,
8813 StateVar,
8814 };
8815
8816 assert(tok_list->length == 0);
8817
8818 AsmToken *cur_tok = nullptr;
8819
8820 enum State state = StateStart;
8821
8822 for (size_t i = 0; i < buf_len(asm_template); i += 1) {
8823 uint8_t c = *((uint8_t*)buf_ptr(asm_template) + i);
8824 switch (state) {
8825 case StateStart:
8826 if (c == '%') {
8827 tok_list->add_one();
8828 cur_tok = &tok_list->last();
8829 cur_tok->id = AsmTokenIdPercent;
8830 cur_tok->start = i;
8831 state = StatePercent;
8832 } else {
8833 tok_list->add_one();
8834 cur_tok = &tok_list->last();
8835 cur_tok->id = AsmTokenIdTemplate;
8836 cur_tok->start = i;
8837 state = StateTemplate;
8838 }
8839 break;
8840 case StatePercent:
8841 if (c == '%') {
8842 cur_tok->end = i;
8843 state = StateStart;
8844 } else if (c == '[') {
8845 cur_tok->id = AsmTokenIdVar;
8846 state = StateVar;
8847 } else if (c == '=') {
8848 cur_tok->id = AsmTokenIdUniqueId;
8849 cur_tok->end = i;
8850 state = StateStart;
8851 } else {
8852 add_node_error(ira->codegen, source_node,
8853 buf_create_from_str("expected a '%' or '['"));
8854 return ErrorSemanticAnalyzeFail;
8855 }
8856 break;
8857 case StateTemplate:
8858 if (c == '%') {
8859 cur_tok->end = i;
8860 i -= 1;
8861 cur_tok = nullptr;
8862 state = StateStart;
8863 }
8864 break;
8865 case StateVar:
8866 if (c == ']') {
8867 cur_tok->end = i;
8868 state = StateStart;
8869 } else if ((c >= 'a' && c <= 'z') ||
8870 (c >= '0' && c <= '9') ||
8871 (c == '_'))
8872 {
8873 // do nothing
8874 } else {
8875 add_node_error(ira->codegen, source_node,
8876 buf_sprintf("invalid substitution character: '%c'", c));
8877 return ErrorSemanticAnalyzeFail;
8878 }
8879 break;
8880 }
8881 }
8882
8883 switch (state) {
8884 case StateStart:
8885 break;
8886 case StatePercent:
8887 case StateVar:
8888 add_node_error(ira->codegen, source_node, buf_sprintf("unexpected end of assembly template"));
8889 return ErrorSemanticAnalyzeFail;
8890 case StateTemplate:
8891 cur_tok->end = buf_len(asm_template);
8892 break;
8893 }
8894 return ErrorNone;
8895}
8896
8897static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_template) {
8898 const char *ptr = buf_ptr(src_template) + tok->start + 2;
8899 size_t len = tok->end - tok->start - 2;
8900 size_t result = 0;
8901 for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1, result += 1) {
8902 AsmOutput *asm_output = node->data.asm_expr.output_list.at(i);
8903 if (buf_eql_mem(asm_output->asm_symbolic_name, ptr, len)) {
8904 return result;
8905 }
8906 }
8907 for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1, result += 1) {
8908 AsmInput *asm_input = node->data.asm_expr.input_list.at(i);
8909 if (buf_eql_mem(asm_input->asm_symbolic_name, ptr, len)) {
8910 return result;
8911 }
8912 }
8913 return SIZE_MAX;
8914}
8915
8916static IrInstSrc *ir_gen_asm_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
8917 assert(node->type == NodeTypeAsmExpr);
8918 AstNodeAsmExpr *asm_expr = &node->data.asm_expr;
8919
8920 IrInstSrc *asm_template = ir_gen_node(irb, asm_expr->asm_template, scope);
8921 if (asm_template == irb->codegen->invalid_inst_src)
8922 return irb->codegen->invalid_inst_src;
8923
8924 bool is_volatile = asm_expr->volatile_token != nullptr;
8925 bool in_fn_scope = (scope_fn_entry(scope) != nullptr);
8926
8927 if (!in_fn_scope) {
8928 if (is_volatile) {
8929 add_token_error(irb->codegen, node->owner, asm_expr->volatile_token,
8930 buf_sprintf("volatile is meaningless on global assembly"));
8931 return irb->codegen->invalid_inst_src;
8932 }
8933
8934 if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 ||
8935 asm_expr->clobber_list.length != 0)
8936 {
8937 add_node_error(irb->codegen, node,
8938 buf_sprintf("global assembly cannot have inputs, outputs, or clobbers"));
8939 return irb->codegen->invalid_inst_src;
8940 }
8941
8942 return ir_build_asm_src(irb, scope, node, asm_template, nullptr, nullptr,
8943 nullptr, 0, is_volatile, true);
8944 }
8945
8946 IrInstSrc **input_list = heap::c_allocator.allocate<IrInstSrc *>(asm_expr->input_list.length);
8947 IrInstSrc **output_types = heap::c_allocator.allocate<IrInstSrc *>(asm_expr->output_list.length);
8948 ZigVar **output_vars = heap::c_allocator.allocate<ZigVar *>(asm_expr->output_list.length);
8949 size_t return_count = 0;
8950 if (!is_volatile && asm_expr->output_list.length == 0) {
8951 add_node_error(irb->codegen, node,
8952 buf_sprintf("assembly expression with no output must be marked volatile"));
8953 return irb->codegen->invalid_inst_src;
8954 }
8955 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) {
8956 AsmOutput *asm_output = asm_expr->output_list.at(i);
8957 if (asm_output->return_type) {
8958 return_count += 1;
8959
8960 IrInstSrc *return_type = ir_gen_node(irb, asm_output->return_type, scope);
8961 if (return_type == irb->codegen->invalid_inst_src)
8962 return irb->codegen->invalid_inst_src;
8963 if (return_count > 1) {
8964 add_node_error(irb->codegen, node,
8965 buf_sprintf("inline assembly allows up to one output value"));
8966 return irb->codegen->invalid_inst_src;
8967 }
8968 output_types[i] = return_type;
8969 } else {
8970 Buf *variable_name = asm_output->variable_name;
8971 // TODO there is some duplication here with ir_gen_symbol. I need to do a full audit of how
8972 // inline assembly works. https://github.com/ziglang/zig/issues/215
8973 ZigVar *var = find_variable(irb->codegen, scope, variable_name, nullptr);
8974 if (var) {
8975 output_vars[i] = var;
8976 } else {
8977 add_node_error(irb->codegen, node,
8978 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
8979 return irb->codegen->invalid_inst_src;
8980 }
8981 }
8982
8983 const char modifier = *buf_ptr(asm_output->constraint);
8984 if (modifier != '=') {
8985 add_node_error(irb->codegen, node,
8986 buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported."
8987 " Compiler TODO: see https://github.com/ziglang/zig/issues/215",
8988 buf_ptr(asm_output->asm_symbolic_name), modifier));
8989 return irb->codegen->invalid_inst_src;
8990 }
8991 }
8992 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) {
8993 AsmInput *asm_input = asm_expr->input_list.at(i);
8994 IrInstSrc *input_value = ir_gen_node(irb, asm_input->expr, scope);
8995 if (input_value == irb->codegen->invalid_inst_src)
8996 return irb->codegen->invalid_inst_src;
8997
8998 input_list[i] = input_value;
8999 }
9000
9001 return ir_build_asm_src(irb, scope, node, asm_template, input_list, output_types,
9002 output_vars, return_count, is_volatile, false);
9003}
9004
9005static IrInstSrc *ir_gen_if_optional_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
9006 ResultLoc *result_loc)
9007{
9008 assert(node->type == NodeTypeIfOptional);
9009
9010 Buf *var_symbol = node->data.test_expr.var_symbol;
9011 AstNode *expr_node = node->data.test_expr.target_node;
9012 AstNode *then_node = node->data.test_expr.then_node;
9013 AstNode *else_node = node->data.test_expr.else_node;
9014 bool var_is_ptr = node->data.test_expr.var_is_ptr;
9015
9016 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, expr_node, scope);
9017 spill_scope->spill_harder = true;
9018
9019 IrInstSrc *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, &spill_scope->base, LValPtr, nullptr);
9020 if (maybe_val_ptr == irb->codegen->invalid_inst_src)
9021 return maybe_val_ptr;
9022
9023 IrInstSrc *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr);
9024 IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, scope, node, maybe_val);
9025
9026 IrBasicBlockSrc *then_block = ir_create_basic_block(irb, scope, "OptionalThen");
9027 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "OptionalElse");
9028 IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "OptionalEndIf");
9029
9030 IrInstSrc *is_comptime;
9031 if (ir_should_inline(irb->exec, scope)) {
9032 is_comptime = ir_build_const_bool(irb, scope, node, true);
9033 } else {
9034 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null);
9035 }
9036 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null,
9037 then_block, else_block, is_comptime);
9038
9039 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block,
9040 result_loc, is_comptime);
9041
9042 ir_set_cursor_at_end_and_append_block(irb, then_block);
9043
9044 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, &spill_scope->base, is_comptime);
9045 Scope *var_scope;
9046 if (var_symbol) {
9047 bool is_shadowable = false;
9048 bool is_const = true;
9049 ZigVar *var = ir_create_var(irb, node, subexpr_scope,
9050 var_symbol, is_const, is_const, is_shadowable, is_comptime);
9051
9052 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false);
9053 IrInstSrc *var_value = var_is_ptr ?
9054 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, node, payload_ptr);
9055 build_decl_var_and_init(irb, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), is_comptime);
9056 var_scope = var->child_scope;
9057 } else {
9058 var_scope = subexpr_scope;
9059 }
9060 IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval,
9061 &peer_parent->peers.at(0)->base);
9062 if (then_expr_result == irb->codegen->invalid_inst_src)
9063 return then_expr_result;
9064 IrBasicBlockSrc *after_then_block = irb->current_basic_block;
9065 if (!instr_is_unreachable(then_expr_result))
9066 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
9067
9068 ir_set_cursor_at_end_and_append_block(irb, else_block);
9069 IrInstSrc *else_expr_result;
9070 if (else_node) {
9071 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base);
9072 if (else_expr_result == irb->codegen->invalid_inst_src)
9073 return else_expr_result;
9074 } else {
9075 else_expr_result = ir_build_const_void(irb, scope, node);
9076 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base);
9077 }
9078 IrBasicBlockSrc *after_else_block = irb->current_basic_block;
9079 if (!instr_is_unreachable(else_expr_result))
9080 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
9081
9082 ir_set_cursor_at_end_and_append_block(irb, endif_block);
9083 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
9084 incoming_values[0] = then_expr_result;
9085 incoming_values[1] = else_expr_result;
9086 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
9087 incoming_blocks[0] = after_then_block;
9088 incoming_blocks[1] = after_else_block;
9089
9090 IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
9091 return ir_expr_wrap(irb, scope, phi, result_loc);
9092}
9093
9094static IrInstSrc *ir_gen_if_err_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
9095 ResultLoc *result_loc)
9096{
9097 assert(node->type == NodeTypeIfErrorExpr);
9098
9099 AstNode *target_node = node->data.if_err_expr.target_node;
9100 AstNode *then_node = node->data.if_err_expr.then_node;
9101 AstNode *else_node = node->data.if_err_expr.else_node;
9102 bool var_is_ptr = node->data.if_err_expr.var_is_ptr;
9103 bool var_is_const = true;
9104 Buf *var_symbol = node->data.if_err_expr.var_symbol;
9105 Buf *err_symbol = node->data.if_err_expr.err_symbol;
9106
9107 IrInstSrc *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr);
9108 if (err_val_ptr == irb->codegen->invalid_inst_src)
9109 return err_val_ptr;
9110
9111 IrInstSrc *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr);
9112 IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr, true, false);
9113
9114 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, scope, "TryOk");
9115 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "TryElse");
9116 IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "TryEnd");
9117
9118 bool force_comptime = ir_should_inline(irb->exec, scope);
9119 IrInstSrc *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err);
9120 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime);
9121
9122 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block,
9123 result_loc, is_comptime);
9124
9125 ir_set_cursor_at_end_and_append_block(irb, ok_block);
9126
9127 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
9128 Scope *var_scope;
9129 if (var_symbol) {
9130 bool is_shadowable = false;
9131 IrInstSrc *var_is_comptime = force_comptime ? ir_build_const_bool(irb, subexpr_scope, node, true) : ir_build_test_comptime(irb, subexpr_scope, node, err_val);
9132 ZigVar *var = ir_create_var(irb, node, subexpr_scope,
9133 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime);
9134
9135 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, subexpr_scope, node, err_val_ptr, false, false);
9136 IrInstSrc *var_value = var_is_ptr ?
9137 payload_ptr : ir_build_load_ptr(irb, subexpr_scope, node, payload_ptr);
9138 build_decl_var_and_init(irb, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), var_is_comptime);
9139 var_scope = var->child_scope;
9140 } else {
9141 var_scope = subexpr_scope;
9142 }
9143 IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval,
9144 &peer_parent->peers.at(0)->base);
9145 if (then_expr_result == irb->codegen->invalid_inst_src)
9146 return then_expr_result;
9147 IrBasicBlockSrc *after_then_block = irb->current_basic_block;
9148 if (!instr_is_unreachable(then_expr_result))
9149 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
9150
9151 ir_set_cursor_at_end_and_append_block(irb, else_block);
9152
9153 IrInstSrc *else_expr_result;
9154 if (else_node) {
9155 Scope *err_var_scope;
9156 if (err_symbol) {
9157 bool is_shadowable = false;
9158 bool is_const = true;
9159 ZigVar *var = ir_create_var(irb, node, subexpr_scope,
9160 err_symbol, is_const, is_const, is_shadowable, is_comptime);
9161
9162 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, subexpr_scope, node, err_val_ptr);
9163 IrInstSrc *err_value = ir_build_load_ptr(irb, subexpr_scope, node, err_ptr);
9164 build_decl_var_and_init(irb, subexpr_scope, node, var, err_value, buf_ptr(err_symbol), is_comptime);
9165 err_var_scope = var->child_scope;
9166 } else {
9167 err_var_scope = subexpr_scope;
9168 }
9169 else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base);
9170 if (else_expr_result == irb->codegen->invalid_inst_src)
9171 return else_expr_result;
9172 } else {
9173 else_expr_result = ir_build_const_void(irb, scope, node);
9174 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base);
9175 }
9176 IrBasicBlockSrc *after_else_block = irb->current_basic_block;
9177 if (!instr_is_unreachable(else_expr_result))
9178 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
9179
9180 ir_set_cursor_at_end_and_append_block(irb, endif_block);
9181 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
9182 incoming_values[0] = then_expr_result;
9183 incoming_values[1] = else_expr_result;
9184 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
9185 incoming_blocks[0] = after_then_block;
9186 incoming_blocks[1] = after_else_block;
9187
9188 IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
9189 return ir_expr_wrap(irb, scope, phi, result_loc);
9190}
9191
9192static bool ir_gen_switch_prong_expr(IrBuilderSrc *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node,
9193 IrBasicBlockSrc *end_block, IrInstSrc *is_comptime, IrInstSrc *var_is_comptime,
9194 IrInstSrc *target_value_ptr, IrInstSrc **prong_values, size_t prong_values_len,
9195 ZigList<IrBasicBlockSrc *> *incoming_blocks, ZigList<IrInstSrc *> *incoming_values,
9196 IrInstSrcSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc)
9197{
9198 assert(switch_node->type == NodeTypeSwitchExpr);
9199 assert(prong_node->type == NodeTypeSwitchProng);
9200
9201 AstNode *expr_node = prong_node->data.switch_prong.expr;
9202 AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol;
9203 Scope *child_scope;
9204 if (var_symbol_node) {
9205 assert(var_symbol_node->type == NodeTypeSymbol);
9206 Buf *var_name = var_symbol_node->data.symbol_expr.symbol;
9207 bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr;
9208
9209 bool is_shadowable = false;
9210 bool is_const = true;
9211 ZigVar *var = ir_create_var(irb, var_symbol_node, scope,
9212 var_name, is_const, is_const, is_shadowable, var_is_comptime);
9213 child_scope = var->child_scope;
9214 IrInstSrc *var_value;
9215 if (out_switch_else_var != nullptr) {
9216 IrInstSrcSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node,
9217 target_value_ptr);
9218 *out_switch_else_var = switch_else_var;
9219 IrInstSrc *payload_ptr = &switch_else_var->base;
9220 var_value = var_is_ptr ?
9221 payload_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, payload_ptr);
9222 } else if (prong_values != nullptr) {
9223 IrInstSrc *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr,
9224 prong_values, prong_values_len);
9225 var_value = var_is_ptr ?
9226 payload_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, payload_ptr);
9227 } else {
9228 var_value = var_is_ptr ?
9229 target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr);
9230 }
9231 build_decl_var_and_init(irb, scope, var_symbol_node, var, var_value, buf_ptr(var_name), var_is_comptime);
9232 } else {
9233 child_scope = scope;
9234 }
9235
9236 IrInstSrc *expr_result = ir_gen_node_extra(irb, expr_node, child_scope, lval, result_loc);
9237 if (expr_result == irb->codegen->invalid_inst_src)
9238 return false;
9239 if (!instr_is_unreachable(expr_result))
9240 ir_mark_gen(ir_build_br(irb, scope, switch_node, end_block, is_comptime));
9241 incoming_blocks->append(irb->current_basic_block);
9242 incoming_values->append(expr_result);
9243 return true;
9244}
9245
9246static IrInstSrc *ir_gen_switch_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
9247 ResultLoc *result_loc)
9248{
9249 assert(node->type == NodeTypeSwitchExpr);
9250
9251 AstNode *target_node = node->data.switch_expr.expr;
9252 IrInstSrc *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr);
9253 if (target_value_ptr == irb->codegen->invalid_inst_src)
9254 return target_value_ptr;
9255 IrInstSrc *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr);
9256
9257 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "SwitchElse");
9258 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, scope, "SwitchEnd");
9259
9260 size_t prong_count = node->data.switch_expr.prongs.length;
9261 ZigList<IrInstSrcSwitchBrCase> cases = {0};
9262
9263 IrInstSrc *is_comptime;
9264 IrInstSrc *var_is_comptime;
9265 if (ir_should_inline(irb->exec, scope)) {
9266 is_comptime = ir_build_const_bool(irb, scope, node, true);
9267 var_is_comptime = is_comptime;
9268 } else {
9269 is_comptime = ir_build_test_comptime(irb, scope, node, target_value);
9270 var_is_comptime = ir_build_test_comptime(irb, scope, node, target_value_ptr);
9271 }
9272
9273 ZigList<IrInstSrc *> incoming_values = {0};
9274 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
9275 ZigList<IrInstSrcCheckSwitchProngsRange> check_ranges = {0};
9276
9277 IrInstSrcSwitchElseVar *switch_else_var = nullptr;
9278
9279 ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>();
9280 peer_parent->base.id = ResultLocIdPeerParent;
9281 peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const;
9282 peer_parent->end_bb = end_block;
9283 peer_parent->is_comptime = is_comptime;
9284 peer_parent->parent = result_loc;
9285
9286 ir_build_reset_result(irb, scope, node, &peer_parent->base);
9287
9288 // First do the else and the ranges
9289 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
9290 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope);
9291 AstNode *else_prong = nullptr;
9292 AstNode *underscore_prong = nullptr;
9293 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) {
9294 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);
9295 size_t prong_item_count = prong_node->data.switch_prong.items.length;
9296 if (prong_node->data.switch_prong.any_items_are_range) {
9297 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
9298
9299 IrInstSrc *ok_bit = nullptr;
9300 AstNode *last_item_node = nullptr;
9301 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {
9302 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
9303 last_item_node = item_node;
9304 if (item_node->type == NodeTypeSwitchRange) {
9305 AstNode *start_node = item_node->data.switch_range.start;
9306 AstNode *end_node = item_node->data.switch_range.end;
9307
9308 IrInstSrc *start_value = ir_gen_node(irb, start_node, comptime_scope);
9309 if (start_value == irb->codegen->invalid_inst_src)
9310 return irb->codegen->invalid_inst_src;
9311
9312 IrInstSrc *end_value = ir_gen_node(irb, end_node, comptime_scope);
9313 if (end_value == irb->codegen->invalid_inst_src)
9314 return irb->codegen->invalid_inst_src;
9315
9316 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one();
9317 check_range->start = start_value;
9318 check_range->end = end_value;
9319
9320 IrInstSrc *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq,
9321 target_value, start_value, false);
9322 IrInstSrc *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq,
9323 target_value, end_value, false);
9324 IrInstSrc *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd,
9325 lower_range_ok, upper_range_ok, false);
9326 if (ok_bit) {
9327 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false);
9328 } else {
9329 ok_bit = both_ok;
9330 }
9331 } else {
9332 IrInstSrc *item_value = ir_gen_node(irb, item_node, comptime_scope);
9333 if (item_value == irb->codegen->invalid_inst_src)
9334 return irb->codegen->invalid_inst_src;
9335
9336 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one();
9337 check_range->start = item_value;
9338 check_range->end = item_value;
9339
9340 IrInstSrc *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq,
9341 item_value, target_value, false);
9342 if (ok_bit) {
9343 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false);
9344 } else {
9345 ok_bit = cmp_ok;
9346 }
9347 }
9348 }
9349
9350 IrBasicBlockSrc *range_block_yes = ir_create_basic_block(irb, scope, "SwitchRangeYes");
9351 IrBasicBlockSrc *range_block_no = ir_create_basic_block(irb, scope, "SwitchRangeNo");
9352
9353 assert(ok_bit);
9354 assert(last_item_node);
9355 IrInstSrc *br_inst = ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit,
9356 range_block_yes, range_block_no, is_comptime));
9357 if (peer_parent->base.source_instruction == nullptr) {
9358 peer_parent->base.source_instruction = br_inst;
9359 }
9360
9361 if (peer_parent->peers.length > 0) {
9362 peer_parent->peers.last()->next_bb = range_block_yes;
9363 }
9364 peer_parent->peers.append(this_peer_result_loc);
9365 ir_set_cursor_at_end_and_append_block(irb, range_block_yes);
9366 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,
9367 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0,
9368 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base))
9369 {
9370 return irb->codegen->invalid_inst_src;
9371 }
9372
9373 ir_set_cursor_at_end_and_append_block(irb, range_block_no);
9374 } else {
9375 if (prong_item_count == 0) {
9376 if (else_prong) {
9377 ErrorMsg *msg = add_node_error(irb->codegen, prong_node,
9378 buf_sprintf("multiple else prongs in switch expression"));
9379 add_error_note(irb->codegen, msg, else_prong,
9380 buf_sprintf("previous else prong is here"));
9381 return irb->codegen->invalid_inst_src;
9382 }
9383 else_prong = prong_node;
9384 } else if (prong_item_count == 1 &&
9385 prong_node->data.switch_prong.items.at(0)->type == NodeTypeSymbol &&
9386 buf_eql_str(prong_node->data.switch_prong.items.at(0)->data.symbol_expr.symbol, "_")) {
9387 if (underscore_prong) {
9388 ErrorMsg *msg = add_node_error(irb->codegen, prong_node,
9389 buf_sprintf("multiple '_' prongs in switch expression"));
9390 add_error_note(irb->codegen, msg, underscore_prong,
9391 buf_sprintf("previous '_' prong is here"));
9392 return irb->codegen->invalid_inst_src;
9393 }
9394 underscore_prong = prong_node;
9395 } else {
9396 continue;
9397 }
9398 if (underscore_prong && else_prong) {
9399 ErrorMsg *msg = add_node_error(irb->codegen, prong_node,
9400 buf_sprintf("else and '_' prong in switch expression"));
9401 if (underscore_prong == prong_node)
9402 add_error_note(irb->codegen, msg, else_prong,
9403 buf_sprintf("else prong is here"));
9404 else
9405 add_error_note(irb->codegen, msg, underscore_prong,
9406 buf_sprintf("'_' prong is here"));
9407 return irb->codegen->invalid_inst_src;
9408 }
9409 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
9410
9411 IrBasicBlockSrc *prev_block = irb->current_basic_block;
9412 if (peer_parent->peers.length > 0) {
9413 peer_parent->peers.last()->next_bb = else_block;
9414 }
9415 peer_parent->peers.append(this_peer_result_loc);
9416 ir_set_cursor_at_end_and_append_block(irb, else_block);
9417 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,
9418 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values,
9419 &switch_else_var, LValNone, &this_peer_result_loc->base))
9420 {
9421 return irb->codegen->invalid_inst_src;
9422 }
9423 ir_set_cursor_at_end(irb, prev_block);
9424 }
9425 }
2137 instruction->ordering = ordering;
94262138
9427 // next do the non-else non-ranges
9428 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) {
9429 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);
9430 size_t prong_item_count = prong_node->data.switch_prong.items.length;
9431 if (prong_item_count == 0)
9432 continue;
9433 if (prong_node->data.switch_prong.any_items_are_range)
9434 continue;
9435 if (underscore_prong == prong_node)
9436 continue;
2139 ir_ref_inst_gen(ptr);
94372140
9438 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
2141 return &instruction->base;
2142}
94392143
9440 IrBasicBlockSrc *prong_block = ir_create_basic_block(irb, scope, "SwitchProng");
9441 IrInstSrc **items = heap::c_allocator.allocate<IrInstSrc *>(prong_item_count);
2144static IrInstGen *ir_build_atomic_store_gen(IrAnalyze *ira, IrInst *source_instr,
2145 IrInstGen *ptr, IrInstGen *value, AtomicOrder ordering)
2146{
2147 IrInstGenAtomicStore *instruction = ir_build_inst_void<IrInstGenAtomicStore>(&ira->new_irb,
2148 source_instr->scope, source_instr->source_node);
2149 instruction->ptr = ptr;
2150 instruction->value = value;
2151 instruction->ordering = ordering;
94422152
9443 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {
9444 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
9445 assert(item_node->type != NodeTypeSwitchRange);
2153 ir_ref_inst_gen(ptr);
2154 ir_ref_inst_gen(value);
94462155
9447 IrInstSrc *item_value = ir_gen_node(irb, item_node, comptime_scope);
9448 if (item_value == irb->codegen->invalid_inst_src)
9449 return irb->codegen->invalid_inst_src;
2156 return &instruction->base;
2157}
94502158
9451 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one();
9452 check_range->start = item_value;
9453 check_range->end = item_value;
94542159
9455 IrInstSrcSwitchBrCase *this_case = cases.add_one();
9456 this_case->value = item_value;
9457 this_case->block = prong_block;
2160static IrInstGen *ir_build_vector_to_array(IrAnalyze *ira, IrInst *source_instruction,
2161 ZigType *result_type, IrInstGen *vector, IrInstGen *result_loc)
2162{
2163 IrInstGenVectorToArray *instruction = ir_build_inst_gen<IrInstGenVectorToArray>(&ira->new_irb,
2164 source_instruction->scope, source_instruction->source_node);
2165 instruction->base.value->type = result_type;
2166 instruction->vector = vector;
2167 instruction->result_loc = result_loc;
94582168
9459 items[item_i] = item_value;
9460 }
2169 ir_ref_inst_gen(vector);
2170 ir_ref_inst_gen(result_loc);
94612171
9462 IrBasicBlockSrc *prev_block = irb->current_basic_block;
9463 if (peer_parent->peers.length > 0) {
9464 peer_parent->peers.last()->next_bb = prong_block;
9465 }
9466 peer_parent->peers.append(this_peer_result_loc);
9467 ir_set_cursor_at_end_and_append_block(irb, prong_block);
9468 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,
9469 is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count,
9470 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base))
9471 {
9472 return irb->codegen->invalid_inst_src;
9473 }
2172 return &instruction->base;
2173}
94742174
9475 ir_set_cursor_at_end(irb, prev_block);
2175static IrInstGen *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInst *source_instruction,
2176 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc)
2177{
2178 IrInstGenPtrOfArrayToSlice *instruction = ir_build_inst_gen<IrInstGenPtrOfArrayToSlice>(&ira->new_irb,
2179 source_instruction->scope, source_instruction->source_node);
2180 instruction->base.value->type = result_type;
2181 instruction->operand = operand;
2182 instruction->result_loc = result_loc;
94762183
9477 }
2184 ir_ref_inst_gen(operand);
2185 ir_ref_inst_gen(result_loc);
94782186
9479 IrInstSrc *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value,
9480 check_ranges.items, check_ranges.length, else_prong, underscore_prong != nullptr);
2187 return &instruction->base;
2188}
94812189
9482 IrInstSrc *br_instruction;
9483 if (cases.length == 0) {
9484 br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime);
9485 } else {
9486 IrInstSrcSwitchBr *switch_br = ir_build_switch_br_src(irb, scope, node, target_value, else_block,
9487 cases.length, cases.items, is_comptime, switch_prongs_void);
9488 if (switch_else_var != nullptr) {
9489 switch_else_var->switch_br = switch_br;
9490 }
9491 br_instruction = &switch_br->base;
9492 }
9493 if (peer_parent->base.source_instruction == nullptr) {
9494 peer_parent->base.source_instruction = br_instruction;
9495 }
9496 for (size_t i = 0; i < peer_parent->peers.length; i += 1) {
9497 peer_parent->peers.at(i)->base.source_instruction = peer_parent->base.source_instruction;
9498 }
2190static IrInstGen *ir_build_array_to_vector(IrAnalyze *ira, IrInst *source_instruction,
2191 IrInstGen *array, ZigType *result_type)
2192{
2193 IrInstGenArrayToVector *instruction = ir_build_inst_gen<IrInstGenArrayToVector>(&ira->new_irb,
2194 source_instruction->scope, source_instruction->source_node);
2195 instruction->base.value->type = result_type;
2196 instruction->array = array;
94992197
9500 if (!else_prong && !underscore_prong) {
9501 if (peer_parent->peers.length != 0) {
9502 peer_parent->peers.last()->next_bb = else_block;
9503 }
9504 ir_set_cursor_at_end_and_append_block(irb, else_block);
9505 ir_build_unreachable(irb, scope, node);
9506 } else {
9507 if (peer_parent->peers.length != 0) {
9508 peer_parent->peers.last()->next_bb = end_block;
9509 }
9510 }
2198 ir_ref_inst_gen(array);
95112199
9512 ir_set_cursor_at_end_and_append_block(irb, end_block);
9513 assert(incoming_blocks.length == incoming_values.length);
9514 IrInstSrc *result_instruction;
9515 if (incoming_blocks.length == 0) {
9516 result_instruction = ir_build_const_void(irb, scope, node);
9517 } else {
9518 result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length,
9519 incoming_blocks.items, incoming_values.items, peer_parent);
9520 }
9521 return ir_lval_wrap(irb, scope, result_instruction, lval, result_loc);
2200 return &instruction->base;
95222201}
95232202
9524static IrInstSrc *ir_gen_comptime(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) {
9525 assert(node->type == NodeTypeCompTime);
9526
9527 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope);
9528 // purposefully pass null for result_loc and let EndExpr handle it
9529 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);
9530}
2203static IrInstGen *ir_build_assert_zero(IrAnalyze *ira, IrInst *source_instruction,
2204 IrInstGen *target)
2205{
2206 IrInstGenAssertZero *instruction = ir_build_inst_gen<IrInstGenAssertZero>(&ira->new_irb,
2207 source_instruction->scope, source_instruction->source_node);
2208 instruction->base.value->type = ira->codegen->builtin_types.entry_void;
2209 instruction->target = target;
95312210
9532static IrInstSrc *ir_gen_nosuspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) {
9533 assert(node->type == NodeTypeNoSuspend);
2211 ir_ref_inst_gen(target);
95342212
9535 Scope *child_scope = create_nosuspend_scope(irb->codegen, node, parent_scope);
9536 // purposefully pass null for result_loc and let EndExpr handle it
9537 return ir_gen_node_extra(irb, node->data.nosuspend_expr.expr, child_scope, lval, nullptr);
2213 return &instruction->base;
95382214}
95392215
9540static IrInstSrc *ir_gen_return_from_block(IrBuilderSrc *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) {
9541 IrInstSrc *is_comptime;
9542 if (ir_should_inline(irb->exec, break_scope)) {
9543 is_comptime = ir_build_const_bool(irb, break_scope, node, true);
9544 } else {
9545 is_comptime = block_scope->is_comptime;
9546 }
9547
9548 IrInstSrc *result_value;
9549 if (node->data.break_expr.expr) {
9550 ResultLocPeer *peer_result = create_peer_result(block_scope->peer_parent);
9551 block_scope->peer_parent->peers.append(peer_result);
9552
9553 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, block_scope->lval,
9554 &peer_result->base);
9555 if (result_value == irb->codegen->invalid_inst_src)
9556 return irb->codegen->invalid_inst_src;
9557 } else {
9558 result_value = ir_build_const_void(irb, break_scope, node);
9559 }
2216static IrInstGen *ir_build_assert_non_null(IrAnalyze *ira, IrInst *source_instruction,
2217 IrInstGen *target)
2218{
2219 IrInstGenAssertNonNull *instruction = ir_build_inst_gen<IrInstGenAssertNonNull>(&ira->new_irb,
2220 source_instruction->scope, source_instruction->source_node);
2221 instruction->base.value->type = ira->codegen->builtin_types.entry_void;
2222 instruction->target = target;
95602223
9561 IrBasicBlockSrc *dest_block = block_scope->end_block;
9562 if (!ir_gen_defers_for_block(irb, break_scope, dest_block->scope, nullptr, nullptr))
9563 return irb->codegen->invalid_inst_src;
2224 ir_ref_inst_gen(target);
95642225
9565 block_scope->incoming_blocks->append(irb->current_basic_block);
9566 block_scope->incoming_values->append(result_value);
9567 return ir_build_br(irb, break_scope, node, dest_block, is_comptime);
2226 return &instruction->base;
95682227}
95692228
9570static IrInstSrc *ir_gen_break(IrBuilderSrc *irb, Scope *break_scope, AstNode *node) {
9571 assert(node->type == NodeTypeBreak);
2229static IrInstGenAlloca *ir_build_alloca_gen(IrAnalyze *ira, IrInst *source_instruction,
2230 uint32_t align, const char *name_hint)
2231{
2232 IrInstGenAlloca *instruction = ir_create_inst_gen<IrInstGenAlloca>(&ira->new_irb,
2233 source_instruction->scope, source_instruction->source_node);
2234 instruction->align = align;
2235 instruction->name_hint = name_hint;
95722236
9573 // Search up the scope. We'll find one of these things first:
9574 // * function definition scope or global scope => error, break outside loop
9575 // * defer expression scope => error, cannot break out of defer expression
9576 // * loop scope => OK
9577 // * (if it's a labeled break) labeled block => OK
2237 return instruction;
2238}
95782239
9579 Scope *search_scope = break_scope;
9580 ScopeLoop *loop_scope;
9581 for (;;) {
9582 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) {
9583 if (node->data.break_expr.name != nullptr) {
9584 add_node_error(irb->codegen, node, buf_sprintf("label not found: '%s'", buf_ptr(node->data.break_expr.name)));
9585 return irb->codegen->invalid_inst_src;
9586 } else {
9587 add_node_error(irb->codegen, node, buf_sprintf("break expression outside loop"));
9588 return irb->codegen->invalid_inst_src;
9589 }
9590 } else if (search_scope->id == ScopeIdDeferExpr) {
9591 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of defer expression"));
9592 return irb->codegen->invalid_inst_src;
9593 } else if (search_scope->id == ScopeIdLoop) {
9594 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope;
9595 if (node->data.break_expr.name == nullptr ||
9596 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name)))
9597 {
9598 this_loop_scope->name_used = true;
9599 loop_scope = this_loop_scope;
9600 break;
9601 }
9602 } else if (search_scope->id == ScopeIdBlock) {
9603 ScopeBlock *this_block_scope = (ScopeBlock *)search_scope;
9604 if (node->data.break_expr.name != nullptr &&
9605 (this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name)))
9606 {
9607 assert(this_block_scope->end_block != nullptr);
9608 this_block_scope->name_used = true;
9609 return ir_gen_return_from_block(irb, break_scope, node, this_block_scope);
9610 }
9611 } else if (search_scope->id == ScopeIdSuspend) {
9612 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of suspend block"));
9613 return irb->codegen->invalid_inst_src;
9614 }
9615 search_scope = search_scope->parent;
9616 }
2240static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSuspendBegin *begin) {
2241 IrInstGenSuspendFinish *inst = ir_build_inst_void<IrInstGenSuspendFinish>(&ira->new_irb,
2242 source_instr->scope, source_instr->source_node);
2243 inst->begin = begin;
96172244
9618 IrInstSrc *is_comptime;
9619 if (ir_should_inline(irb->exec, break_scope)) {
9620 is_comptime = ir_build_const_bool(irb, break_scope, node, true);
9621 } else {
9622 is_comptime = loop_scope->is_comptime;
9623 }
2245 ir_ref_inst_gen(&begin->base);
96242246
9625 IrInstSrc *result_value;
9626 if (node->data.break_expr.expr) {
9627 ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent);
9628 loop_scope->peer_parent->peers.append(peer_result);
2247 return &inst->base;
2248}
96292249
9630 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope,
9631 loop_scope->lval, &peer_result->base);
9632 if (result_value == irb->codegen->invalid_inst_src)
9633 return irb->codegen->invalid_inst_src;
9634 } else {
9635 result_value = ir_build_const_void(irb, break_scope, node);
9636 }
2250static IrInstGenAwait *ir_build_await_gen(IrAnalyze *ira, IrInst *source_instruction,
2251 IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc, bool is_nosuspend)
2252{
2253 IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb,
2254 source_instruction->scope, source_instruction->source_node);
2255 instruction->base.value->type = result_type;
2256 instruction->frame = frame;
2257 instruction->result_loc = result_loc;
2258 instruction->is_nosuspend = is_nosuspend;
96372259
9638 IrBasicBlockSrc *dest_block = loop_scope->break_block;
9639 if (!ir_gen_defers_for_block(irb, break_scope, dest_block->scope, nullptr, nullptr))
9640 return irb->codegen->invalid_inst_src;
2260 ir_ref_inst_gen(frame);
2261 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
96412262
9642 loop_scope->incoming_blocks->append(irb->current_basic_block);
9643 loop_scope->incoming_values->append(result_value);
9644 return ir_build_br(irb, break_scope, node, dest_block, is_comptime);
2263 return instruction;
96452264}
96462265
9647static IrInstSrc *ir_gen_continue(IrBuilderSrc *irb, Scope *continue_scope, AstNode *node) {
9648 assert(node->type == NodeTypeContinue);
9649
9650 // Search up the scope. We'll find one of these things first:
9651 // * function definition scope or global scope => error, break outside loop
9652 // * defer expression scope => error, cannot break out of defer expression
9653 // * loop scope => OK
2266static IrInstGen *ir_build_resume_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *frame) {
2267 IrInstGenResume *instruction = ir_build_inst_void<IrInstGenResume>(&ira->new_irb,
2268 source_instr->scope, source_instr->source_node);
2269 instruction->frame = frame;
96542270
9655 ZigList<ScopeRuntime *> runtime_scopes = {};
2271 ir_ref_inst_gen(frame);
96562272
9657 Scope *search_scope = continue_scope;
9658 ScopeLoop *loop_scope;
9659 for (;;) {
9660 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) {
9661 if (node->data.continue_expr.name != nullptr) {
9662 add_node_error(irb->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.continue_expr.name)));
9663 return irb->codegen->invalid_inst_src;
9664 } else {
9665 add_node_error(irb->codegen, node, buf_sprintf("continue expression outside loop"));
9666 return irb->codegen->invalid_inst_src;
9667 }
9668 } else if (search_scope->id == ScopeIdDeferExpr) {
9669 add_node_error(irb->codegen, node, buf_sprintf("cannot continue out of defer expression"));
9670 return irb->codegen->invalid_inst_src;
9671 } else if (search_scope->id == ScopeIdLoop) {
9672 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope;
9673 if (node->data.continue_expr.name == nullptr ||
9674 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name)))
9675 {
9676 this_loop_scope->name_used = true;
9677 loop_scope = this_loop_scope;
9678 break;
9679 }
9680 } else if (search_scope->id == ScopeIdRuntime) {
9681 ScopeRuntime *scope_runtime = (ScopeRuntime *)search_scope;
9682 runtime_scopes.append(scope_runtime);
9683 }
9684 search_scope = search_scope->parent;
9685 }
2273 return &instruction->base;
2274}
96862275
9687 IrInstSrc *is_comptime;
9688 if (ir_should_inline(irb->exec, continue_scope)) {
9689 is_comptime = ir_build_const_bool(irb, continue_scope, node, true);
9690 } else {
9691 is_comptime = loop_scope->is_comptime;
9692 }
2276static IrInstGen *ir_build_spill_begin_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand,
2277 SpillId spill_id)
2278{
2279 IrInstGenSpillBegin *instruction = ir_build_inst_void<IrInstGenSpillBegin>(&ira->new_irb,
2280 source_instr->scope, source_instr->source_node);
2281 instruction->operand = operand;
2282 instruction->spill_id = spill_id;
96932283
9694 for (size_t i = 0; i < runtime_scopes.length; i += 1) {
9695 ScopeRuntime *scope_runtime = runtime_scopes.at(i);
9696 ir_mark_gen(ir_build_check_runtime_scope(irb, continue_scope, node, scope_runtime->is_comptime, is_comptime));
9697 }
9698 runtime_scopes.deinit();
2284 ir_ref_inst_gen(operand);
96992285
9700 IrBasicBlockSrc *dest_block = loop_scope->continue_block;
9701 if (!ir_gen_defers_for_block(irb, continue_scope, dest_block->scope, nullptr, nullptr))
9702 return irb->codegen->invalid_inst_src;
9703 return ir_mark_gen(ir_build_br(irb, continue_scope, node, dest_block, is_comptime));
2286 return &instruction->base;
97042287}
97052288
9706static IrInstSrc *ir_gen_error_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
9707 assert(node->type == NodeTypeErrorType);
9708 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_global_error_set);
9709}
2289static IrInstGen *ir_build_spill_end_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSpillBegin *begin,
2290 ZigType *result_type)
2291{
2292 IrInstGenSpillEnd *instruction = ir_build_inst_gen<IrInstGenSpillEnd>(&ira->new_irb,
2293 source_instr->scope, source_instr->source_node);
2294 instruction->base.value->type = result_type;
2295 instruction->begin = begin;
2296
2297 ir_ref_inst_gen(&begin->base);
97102298
9711static IrInstSrc *ir_gen_defer(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) {
9712 assert(node->type == NodeTypeDefer);
2299 return &instruction->base;
2300}
97132301
9714 ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope);
9715 node->data.defer.child_scope = &defer_child_scope->base;
2302static IrInstGen *ir_build_vector_extract_elem(IrAnalyze *ira, IrInst *source_instruction,
2303 IrInstGen *vector, IrInstGen *index)
2304{
2305 IrInstGenVectorExtractElem *instruction = ir_build_inst_gen<IrInstGenVectorExtractElem>(
2306 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
2307 instruction->base.value->type = vector->value->type->data.vector.elem_type;
2308 instruction->vector = vector;
2309 instruction->index = index;
97162310
9717 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(irb->codegen, node, parent_scope);
9718 node->data.defer.expr_scope = &defer_expr_scope->base;
2311 ir_ref_inst_gen(vector);
2312 ir_ref_inst_gen(index);
97192313
9720 return ir_build_const_void(irb, parent_scope, node);
2314 return &instruction->base;
97212315}
97222316
9723static IrInstSrc *ir_gen_slice(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
9724 assert(node->type == NodeTypeSliceExpr);
9725
9726 AstNodeSliceExpr *slice_expr = &node->data.slice_expr;
9727 AstNode *array_node = slice_expr->array_ref_expr;
9728 AstNode *start_node = slice_expr->start;
9729 AstNode *end_node = slice_expr->end;
9730 AstNode *sentinel_node = slice_expr->sentinel;
2317static IrInstGen *ir_build_wasm_memory_size_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *index) {
2318 IrInstGenWasmMemorySize *instruction = ir_build_inst_gen<IrInstGenWasmMemorySize>(&ira->new_irb,
2319 source_instr->scope, source_instr->source_node);
2320 instruction->base.value->type = ira->codegen->builtin_types.entry_u32;
2321 instruction->index = index;
97312322
9732 IrInstSrc *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr);
9733 if (ptr_value == irb->codegen->invalid_inst_src)
9734 return irb->codegen->invalid_inst_src;
2323 ir_ref_inst_gen(index);
97352324
9736 IrInstSrc *start_value = ir_gen_node(irb, start_node, scope);
9737 if (start_value == irb->codegen->invalid_inst_src)
9738 return irb->codegen->invalid_inst_src;
2325 return &instruction->base;
2326}
97392327
9740 IrInstSrc *end_value;
9741 if (end_node) {
9742 end_value = ir_gen_node(irb, end_node, scope);
9743 if (end_value == irb->codegen->invalid_inst_src)
9744 return irb->codegen->invalid_inst_src;
9745 } else {
9746 end_value = nullptr;
9747 }
2328static IrInstGen *ir_build_wasm_memory_grow_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *index, IrInstGen *delta) {
2329 IrInstGenWasmMemoryGrow *instruction = ir_build_inst_gen<IrInstGenWasmMemoryGrow>(&ira->new_irb,
2330 source_instr->scope, source_instr->source_node);
2331 instruction->base.value->type = ira->codegen->builtin_types.entry_i32;
2332 instruction->index = index;
2333 instruction->delta = delta;
97482334
9749 IrInstSrc *sentinel_value;
9750 if (sentinel_node) {
9751 sentinel_value = ir_gen_node(irb, sentinel_node, scope);
9752 if (sentinel_value == irb->codegen->invalid_inst_src)
9753 return irb->codegen->invalid_inst_src;
9754 } else {
9755 sentinel_value = nullptr;
9756 }
2335 ir_ref_inst_gen(index);
2336 ir_ref_inst_gen(delta);
97572337
9758 IrInstSrc *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value,
9759 sentinel_value, true, result_loc);
9760 return ir_lval_wrap(irb, scope, slice, lval, result_loc);
2338 return &instruction->base;
97612339}
97622340
9763static IrInstSrc *ir_gen_catch(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval,
9764 ResultLoc *result_loc)
2341static Error parse_asm_template(IrAnalyze *ira, AstNode *source_node, Buf *asm_template,
2342 ZigList<AsmToken> *tok_list)
97652343{
9766 assert(node->type == NodeTypeCatchExpr);
2344 // TODO Connect the errors in this function back up to the actual source location
2345 // rather than just the token. https://github.com/ziglang/zig/issues/2080
2346 enum State {
2347 StateStart,
2348 StatePercent,
2349 StateTemplate,
2350 StateVar,
2351 };
2352
2353 assert(tok_list->length == 0);
97672354
9768 AstNode *op1_node = node->data.unwrap_err_expr.op1;
9769 AstNode *op2_node = node->data.unwrap_err_expr.op2;
9770 AstNode *var_node = node->data.unwrap_err_expr.symbol;
2355 AsmToken *cur_tok = nullptr;
2356
2357 enum State state = StateStart;
97712358
9772 if (op2_node->type == NodeTypeUnreachable) {
9773 if (var_node != nullptr) {
9774 assert(var_node->type == NodeTypeSymbol);
9775 Buf *var_name = var_node->data.symbol_expr.symbol;
9776 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name)));
9777 return irb->codegen->invalid_inst_src;
2359 for (size_t i = 0; i < buf_len(asm_template); i += 1) {
2360 uint8_t c = *((uint8_t*)buf_ptr(asm_template) + i);
2361 switch (state) {
2362 case StateStart:
2363 if (c == '%') {
2364 tok_list->add_one();
2365 cur_tok = &tok_list->last();
2366 cur_tok->id = AsmTokenIdPercent;
2367 cur_tok->start = i;
2368 state = StatePercent;
2369 } else {
2370 tok_list->add_one();
2371 cur_tok = &tok_list->last();
2372 cur_tok->id = AsmTokenIdTemplate;
2373 cur_tok->start = i;
2374 state = StateTemplate;
2375 }
2376 break;
2377 case StatePercent:
2378 if (c == '%') {
2379 cur_tok->end = i;
2380 state = StateStart;
2381 } else if (c == '[') {
2382 cur_tok->id = AsmTokenIdVar;
2383 state = StateVar;
2384 } else if (c == '=') {
2385 cur_tok->id = AsmTokenIdUniqueId;
2386 cur_tok->end = i;
2387 state = StateStart;
2388 } else {
2389 add_node_error(ira->codegen, source_node,
2390 buf_create_from_str("expected a '%' or '['"));
2391 return ErrorSemanticAnalyzeFail;
2392 }
2393 break;
2394 case StateTemplate:
2395 if (c == '%') {
2396 cur_tok->end = i;
2397 i -= 1;
2398 cur_tok = nullptr;
2399 state = StateStart;
2400 }
2401 break;
2402 case StateVar:
2403 if (c == ']') {
2404 cur_tok->end = i;
2405 state = StateStart;
2406 } else if ((c >= 'a' && c <= 'z') ||
2407 (c >= '0' && c <= '9') ||
2408 (c == '_'))
2409 {
2410 // do nothing
2411 } else {
2412 add_node_error(ira->codegen, source_node,
2413 buf_sprintf("invalid substitution character: '%c'", c));
2414 return ErrorSemanticAnalyzeFail;
2415 }
2416 break;
97782417 }
9779 return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, lval, result_loc);
9780 }
9781
9782
9783 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, op1_node, parent_scope);
9784 spill_scope->spill_harder = true;
9785
9786 IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, op1_node, &spill_scope->base, LValPtr, nullptr);
9787 if (err_union_ptr == irb->codegen->invalid_inst_src)
9788 return irb->codegen->invalid_inst_src;
9789
9790 IrInstSrc *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr, true, false);
9791
9792 IrInstSrc *is_comptime;
9793 if (ir_should_inline(irb->exec, parent_scope)) {
9794 is_comptime = ir_build_const_bool(irb, parent_scope, node, true);
9795 } else {
9796 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_err);
9797 }
9798
9799 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk");
9800 IrBasicBlockSrc *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError");
9801 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd");
9802 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime);
9803
9804 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, result_loc,
9805 is_comptime);
9806
9807 ir_set_cursor_at_end_and_append_block(irb, err_block);
9808 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, &spill_scope->base, is_comptime);
9809 Scope *err_scope;
9810 if (var_node) {
9811 assert(var_node->type == NodeTypeSymbol);
9812 Buf *var_name = var_node->data.symbol_expr.symbol;
9813 bool is_const = true;
9814 bool is_shadowable = false;
9815 ZigVar *var = ir_create_var(irb, node, subexpr_scope, var_name,
9816 is_const, is_const, is_shadowable, is_comptime);
9817 err_scope = var->child_scope;
9818 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, node, err_union_ptr);
9819 IrInstSrc *err_value = ir_build_load_ptr(irb, err_scope, var_node, err_ptr);
9820 build_decl_var_and_init(irb, err_scope, var_node, var, err_value, buf_ptr(var_name), is_comptime);
9821 } else {
9822 err_scope = subexpr_scope;
9823 }
9824 IrInstSrc *err_result = ir_gen_node_extra(irb, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base);
9825 if (err_result == irb->codegen->invalid_inst_src)
9826 return irb->codegen->invalid_inst_src;
9827 IrBasicBlockSrc *after_err_block = irb->current_basic_block;
9828 if (!instr_is_unreachable(err_result))
9829 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime));
9830
9831 ir_set_cursor_at_end_and_append_block(irb, ok_block);
9832 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(irb, parent_scope, node, err_union_ptr, false, false);
9833 IrInstSrc *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr);
9834 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base);
9835 IrBasicBlockSrc *after_ok_block = irb->current_basic_block;
9836 ir_build_br(irb, parent_scope, node, end_block, is_comptime);
9837
9838 ir_set_cursor_at_end_and_append_block(irb, end_block);
9839 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2);
9840 incoming_values[0] = err_result;
9841 incoming_values[1] = unwrapped_payload;
9842 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2);
9843 incoming_blocks[0] = after_err_block;
9844 incoming_blocks[1] = after_ok_block;
9845 IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent);
9846 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc);
9847}
9848
9849static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) {
9850 if (inner_scope == nullptr || inner_scope == outer_scope) return false;
9851 bool need_comma = render_instance_name_recursive(codegen, name, outer_scope, inner_scope->parent);
9852 if (inner_scope->id != ScopeIdVarDecl)
9853 return need_comma;
9854
9855 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope;
9856 if (need_comma)
9857 buf_append_char(name, ',');
9858 // TODO: const ptr reinterpret here to make the var type agree with the value?
9859 render_const_value(codegen, name, var_scope->var->const_value);
9860 return true;
9861}
9862
9863static Buf *get_anon_type_name(CodeGen *codegen, IrExecutableSrc *exec, const char *kind_name,
9864 Scope *scope, AstNode *source_node, Buf *out_bare_name)
9865{
9866 if (exec != nullptr && exec->name) {
9867 ZigType *import = get_scope_import(scope);
9868 Buf *namespace_name = buf_alloc();
9869 append_namespace_qualification(codegen, namespace_name, import);
9870 buf_append_buf(namespace_name, exec->name);
9871 buf_init_from_buf(out_bare_name, exec->name);
9872 return namespace_name;
9873 } else if (exec != nullptr && exec->name_fn != nullptr) {
9874 Buf *name = buf_alloc();
9875 buf_append_buf(name, &exec->name_fn->symbol_name);
9876 buf_appendf(name, "(");
9877 render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope);
9878 buf_appendf(name, ")");
9879 buf_init_from_buf(out_bare_name, name);
9880 return name;
9881 } else {
9882 ZigType *import = get_scope_import(scope);
9883 Buf *namespace_name = buf_alloc();
9884 append_namespace_qualification(codegen, namespace_name, import);
9885 buf_appendf(namespace_name, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, kind_name,
9886 source_node->line + 1, source_node->column + 1);
9887 buf_init_from_buf(out_bare_name, namespace_name);
9888 return namespace_name;
98892418 }
9890}
9891
9892static IrInstSrc *ir_gen_container_decl(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) {
9893 assert(node->type == NodeTypeContainerDecl);
98942419
9895 ContainerKind kind = node->data.container_decl.kind;
9896 Buf *bare_name = buf_alloc();
9897 Buf *name = get_anon_type_name(irb->codegen, irb->exec, container_string(kind), parent_scope, node, bare_name);
9898
9899 ContainerLayout layout = node->data.container_decl.layout;
9900 ZigType *container_type = get_partial_container_type(irb->codegen, parent_scope,
9901 kind, node, buf_ptr(name), bare_name, layout);
9902 ScopeDecls *child_scope = get_container_scope(container_type);
9903
9904 for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) {
9905 AstNode *child_node = node->data.container_decl.decls.at(i);
9906 scan_decls(irb->codegen, child_scope, child_node);
2420 switch (state) {
2421 case StateStart:
2422 break;
2423 case StatePercent:
2424 case StateVar:
2425 add_node_error(ira->codegen, source_node, buf_sprintf("unexpected end of assembly template"));
2426 return ErrorSemanticAnalyzeFail;
2427 case StateTemplate:
2428 cur_tok->end = buf_len(asm_template);
2429 break;
99072430 }
9908
9909 TldContainer *tld_container = heap::c_allocator.create<TldContainer>();
9910 init_tld(&tld_container->base, TldIdContainer, bare_name, VisibModPub, node, parent_scope);
9911 tld_container->type_entry = container_type;
9912 tld_container->decls_scope = child_scope;
9913 irb->codegen->resolve_queue.append(&tld_container->base);
9914
9915 // Add this to the list to mark as invalid if analyzing this exec fails.
9916 irb->exec->tld_list.append(&tld_container->base);
9917
9918 return ir_build_const_type(irb, parent_scope, node, container_type);
2431 return ErrorNone;
99192432}
99202433
99212434// errors should be populated with set1's values
......@@ -10003,498 +2516,7 @@ static ZigType *make_err_set_with_one_item(CodeGen *g, Scope *parent_scope, AstN
100032516 return err_set_type;
100042517}
100052518
10006static AstNode *ast_field_to_symbol_node(AstNode *err_set_field_node) {
10007 if (err_set_field_node->type == NodeTypeSymbol) {
10008 return err_set_field_node;
10009 } else if (err_set_field_node->type == NodeTypeErrorSetField) {
10010 assert(err_set_field_node->data.err_set_field.field_name->type == NodeTypeSymbol);
10011 return err_set_field_node->data.err_set_field.field_name;
10012 } else {
10013 return err_set_field_node;
10014 }
10015}
10016
10017static IrInstSrc *ir_gen_err_set_decl(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) {
10018 assert(node->type == NodeTypeErrorSetDecl);
10019
10020 uint32_t err_count = node->data.err_set_decl.decls.length;
10021
10022 Buf bare_name = BUF_INIT;
10023 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error", parent_scope, node, &bare_name);
10024 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);
10025 buf_init_from_buf(&err_set_type->name, type_name);
10026 err_set_type->data.error_set.err_count = err_count;
10027 err_set_type->size_in_bits = irb->codegen->builtin_types.entry_global_error_set->size_in_bits;
10028 err_set_type->abi_align = irb->codegen->builtin_types.entry_global_error_set->abi_align;
10029 err_set_type->abi_size = irb->codegen->builtin_types.entry_global_error_set->abi_size;
10030 err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(err_count);
10031
10032 size_t errors_count = irb->codegen->errors_by_index.length + err_count;
10033 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count);
10034
10035 for (uint32_t i = 0; i < err_count; i += 1) {
10036 AstNode *field_node = node->data.err_set_decl.decls.at(i);
10037 AstNode *symbol_node = ast_field_to_symbol_node(field_node);
10038 Buf *err_name = symbol_node->data.symbol_expr.symbol;
10039 ErrorTableEntry *err = heap::c_allocator.create<ErrorTableEntry>();
10040 err->decl_node = field_node;
10041 buf_init_from_buf(&err->name, err_name);
10042
10043 auto existing_entry = irb->codegen->error_table.put_unique(err_name, err);
10044 if (existing_entry) {
10045 err->value = existing_entry->value->value;
10046 } else {
10047 size_t error_value_count = irb->codegen->errors_by_index.length;
10048 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)irb->codegen->err_tag_type->data.integral.bit_count));
10049 err->value = error_value_count;
10050 irb->codegen->errors_by_index.append(err);
10051 }
10052 err_set_type->data.error_set.errors[i] = err;
10053
10054 ErrorTableEntry *prev_err = errors[err->value];
10055 if (prev_err != nullptr) {
10056 ErrorMsg *msg = add_node_error(irb->codegen, ast_field_to_symbol_node(err->decl_node),
10057 buf_sprintf("duplicate error: '%s'", buf_ptr(&err->name)));
10058 add_error_note(irb->codegen, msg, ast_field_to_symbol_node(prev_err->decl_node),
10059 buf_sprintf("other error here"));
10060 return irb->codegen->invalid_inst_src;
10061 }
10062 errors[err->value] = err;
10063 }
10064 heap::c_allocator.deallocate(errors, errors_count);
10065 return ir_build_const_type(irb, parent_scope, node, err_set_type);
10066}
10067
10068static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) {
10069 assert(node->type == NodeTypeFnProto);
10070
10071 size_t param_count = node->data.fn_proto.params.length;
10072 IrInstSrc **param_types = heap::c_allocator.allocate<IrInstSrc*>(param_count);
10073
10074 bool is_var_args = false;
10075 for (size_t i = 0; i < param_count; i += 1) {
10076 AstNode *param_node = node->data.fn_proto.params.at(i);
10077 if (param_node->data.param_decl.is_var_args) {
10078 is_var_args = true;
10079 break;
10080 }
10081 if (param_node->data.param_decl.anytype_token == nullptr) {
10082 AstNode *type_node = param_node->data.param_decl.type;
10083 IrInstSrc *type_value = ir_gen_node(irb, type_node, parent_scope);
10084 if (type_value == irb->codegen->invalid_inst_src)
10085 return irb->codegen->invalid_inst_src;
10086 param_types[i] = type_value;
10087 } else {
10088 param_types[i] = nullptr;
10089 }
10090 }
10091
10092 IrInstSrc *align_value = nullptr;
10093 if (node->data.fn_proto.align_expr != nullptr) {
10094 align_value = ir_gen_node(irb, node->data.fn_proto.align_expr, parent_scope);
10095 if (align_value == irb->codegen->invalid_inst_src)
10096 return irb->codegen->invalid_inst_src;
10097 }
10098
10099 IrInstSrc *callconv_value = nullptr;
10100 if (node->data.fn_proto.callconv_expr != nullptr) {
10101 callconv_value = ir_gen_node(irb, node->data.fn_proto.callconv_expr, parent_scope);
10102 if (callconv_value == irb->codegen->invalid_inst_src)
10103 return irb->codegen->invalid_inst_src;
10104 }
10105
10106 IrInstSrc *return_type;
10107 if (node->data.fn_proto.return_type == nullptr) {
10108 return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void);
10109 } else {
10110 return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope);
10111 if (return_type == irb->codegen->invalid_inst_src)
10112 return irb->codegen->invalid_inst_src;
10113 }
10114
10115 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, callconv_value, return_type, is_var_args);
10116}
10117
10118static IrInstSrc *ir_gen_resume(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
10119 assert(node->type == NodeTypeResume);
10120
10121 IrInstSrc *target_inst = ir_gen_node_extra(irb, node->data.resume_expr.expr, scope, LValPtr, nullptr);
10122 if (target_inst == irb->codegen->invalid_inst_src)
10123 return irb->codegen->invalid_inst_src;
10124
10125 return ir_build_resume_src(irb, scope, node, target_inst);
10126}
10127
10128static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval,
10129 ResultLoc *result_loc)
10130{
10131 assert(node->type == NodeTypeAwaitExpr);
10132
10133 bool is_nosuspend = get_scope_nosuspend(scope) != nullptr;
10134
10135 AstNode *expr_node = node->data.await_expr.expr;
10136 if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) {
10137 AstNode *fn_ref_expr = expr_node->data.fn_call_expr.fn_ref_expr;
10138 Buf *name = fn_ref_expr->data.symbol_expr.symbol;
10139 auto entry = irb->codegen->builtin_fn_table.maybe_get(name);
10140 if (entry != nullptr) {
10141 BuiltinFnEntry *builtin_fn = entry->value;
10142 if (builtin_fn->id == BuiltinFnIdAsyncCall) {
10143 return ir_gen_async_call(irb, scope, node, expr_node, lval, result_loc);
10144 }
10145 }
10146 }
10147
10148 ZigFn *fn_entry = exec_fn_entry(irb->exec);
10149 if (!fn_entry) {
10150 add_node_error(irb->codegen, node, buf_sprintf("await outside function definition"));
10151 return irb->codegen->invalid_inst_src;
10152 }
10153 ScopeSuspend *existing_suspend_scope = get_scope_suspend(scope);
10154 if (existing_suspend_scope) {
10155 if (!existing_suspend_scope->reported_err) {
10156 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot await inside suspend block"));
10157 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("suspend block here"));
10158 existing_suspend_scope->reported_err = true;
10159 }
10160 return irb->codegen->invalid_inst_src;
10161 }
10162
10163 IrInstSrc *target_inst = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
10164 if (target_inst == irb->codegen->invalid_inst_src)
10165 return irb->codegen->invalid_inst_src;
10166
10167 IrInstSrc *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc, is_nosuspend);
10168 return ir_lval_wrap(irb, scope, await_inst, lval, result_loc);
10169}
10170
10171static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) {
10172 assert(node->type == NodeTypeSuspend);
10173
10174 ZigFn *fn_entry = exec_fn_entry(irb->exec);
10175 if (!fn_entry) {
10176 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition"));
10177 return irb->codegen->invalid_inst_src;
10178 }
10179 if (get_scope_nosuspend(parent_scope) != nullptr) {
10180 add_node_error(irb->codegen, node, buf_sprintf("suspend in nosuspend scope"));
10181 return irb->codegen->invalid_inst_src;
10182 }
10183
10184 ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope);
10185 if (existing_suspend_scope) {
10186 if (!existing_suspend_scope->reported_err) {
10187 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside suspend block"));
10188 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here"));
10189 existing_suspend_scope->reported_err = true;
10190 }
10191 return irb->codegen->invalid_inst_src;
10192 }
10193
10194 IrInstSrcSuspendBegin *begin = ir_build_suspend_begin_src(irb, parent_scope, node);
10195 ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope);
10196 Scope *child_scope = &suspend_scope->base;
10197 IrInstSrc *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope);
10198 if (susp_res == irb->codegen->invalid_inst_src)
10199 return irb->codegen->invalid_inst_src;
10200 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res));
10201
10202 return ir_mark_gen(ir_build_suspend_finish_src(irb, parent_scope, node, begin));
10203}
10204
10205static IrInstSrc *ir_gen_node_raw(IrBuilderSrc *irb, AstNode *node, Scope *scope,
10206 LVal lval, ResultLoc *result_loc)
10207{
10208 assert(scope);
10209 switch (node->type) {
10210 case NodeTypeStructValueField:
10211 case NodeTypeParamDecl:
10212 case NodeTypeUsingNamespace:
10213 case NodeTypeSwitchProng:
10214 case NodeTypeSwitchRange:
10215 case NodeTypeStructField:
10216 case NodeTypeErrorSetField:
10217 case NodeTypeFnDef:
10218 case NodeTypeTestDecl:
10219 zig_unreachable();
10220 case NodeTypeBlock:
10221 return ir_gen_block(irb, scope, node, lval, result_loc);
10222 case NodeTypeGroupedExpr:
10223 return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc);
10224 case NodeTypeBinOpExpr:
10225 return ir_gen_bin_op(irb, scope, node, lval, result_loc);
10226 case NodeTypeIntLiteral:
10227 return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval, result_loc);
10228 case NodeTypeFloatLiteral:
10229 return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval, result_loc);
10230 case NodeTypeCharLiteral:
10231 return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval, result_loc);
10232 case NodeTypeSymbol:
10233 return ir_gen_symbol(irb, scope, node, lval, result_loc);
10234 case NodeTypeFnCallExpr:
10235 return ir_gen_fn_call(irb, scope, node, lval, result_loc);
10236 case NodeTypeIfBoolExpr:
10237 return ir_gen_if_bool_expr(irb, scope, node, lval, result_loc);
10238 case NodeTypePrefixOpExpr:
10239 return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc);
10240 case NodeTypeContainerInitExpr:
10241 return ir_gen_container_init_expr(irb, scope, node, lval, result_loc);
10242 case NodeTypeVariableDeclaration:
10243 return ir_gen_var_decl(irb, scope, node);
10244 case NodeTypeWhileExpr:
10245 return ir_gen_while_expr(irb, scope, node, lval, result_loc);
10246 case NodeTypeForExpr:
10247 return ir_gen_for_expr(irb, scope, node, lval, result_loc);
10248 case NodeTypeArrayAccessExpr:
10249 return ir_gen_array_access(irb, scope, node, lval, result_loc);
10250 case NodeTypeReturnExpr:
10251 return ir_gen_return(irb, scope, node, lval, result_loc);
10252 case NodeTypeFieldAccessExpr:
10253 {
10254 IrInstSrc *ptr_instruction = ir_gen_field_access(irb, scope, node);
10255 if (ptr_instruction == irb->codegen->invalid_inst_src)
10256 return ptr_instruction;
10257 if (lval == LValPtr || lval == LValAssign)
10258 return ptr_instruction;
10259
10260 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction);
10261 return ir_expr_wrap(irb, scope, load_ptr, result_loc);
10262 }
10263 case NodeTypePtrDeref: {
10264 AstNode *expr_node = node->data.ptr_deref_expr.target;
10265
10266 LVal child_lval = lval;
10267 if (child_lval == LValAssign)
10268 child_lval = LValPtr;
10269
10270 IrInstSrc *value = ir_gen_node_extra(irb, expr_node, scope, child_lval, nullptr);
10271 if (value == irb->codegen->invalid_inst_src)
10272 return value;
10273
10274 // We essentially just converted any lvalue from &(x.*) to (&x).*;
10275 // this inhibits checking that x is a pointer later, so we directly
10276 // record whether the pointer check is needed
10277 IrInstSrc *un_op = ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval, result_loc);
10278 return ir_expr_wrap(irb, scope, un_op, result_loc);
10279 }
10280 case NodeTypeUnwrapOptional: {
10281 AstNode *expr_node = node->data.unwrap_optional.expr;
10282
10283 IrInstSrc *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
10284 if (maybe_ptr == irb->codegen->invalid_inst_src)
10285 return irb->codegen->invalid_inst_src;
10286
10287 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true );
10288 if (lval == LValPtr || lval == LValAssign)
10289 return unwrapped_ptr;
10290
10291 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, unwrapped_ptr);
10292 return ir_expr_wrap(irb, scope, load_ptr, result_loc);
10293 }
10294 case NodeTypeBoolLiteral:
10295 return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval, result_loc);
10296 case NodeTypeArrayType:
10297 return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc);
10298 case NodeTypePointerType:
10299 return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc);
10300 case NodeTypeAnyFrameType:
10301 return ir_lval_wrap(irb, scope, ir_gen_anyframe_type(irb, scope, node), lval, result_loc);
10302 case NodeTypeStringLiteral:
10303 return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc);
10304 case NodeTypeUndefinedLiteral:
10305 return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval, result_loc);
10306 case NodeTypeAsmExpr:
10307 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval, result_loc);
10308 case NodeTypeNullLiteral:
10309 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval, result_loc);
10310 case NodeTypeIfErrorExpr:
10311 return ir_gen_if_err_expr(irb, scope, node, lval, result_loc);
10312 case NodeTypeIfOptional:
10313 return ir_gen_if_optional_expr(irb, scope, node, lval, result_loc);
10314 case NodeTypeSwitchExpr:
10315 return ir_gen_switch_expr(irb, scope, node, lval, result_loc);
10316 case NodeTypeCompTime:
10317 return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc);
10318 case NodeTypeNoSuspend:
10319 return ir_expr_wrap(irb, scope, ir_gen_nosuspend(irb, scope, node, lval), result_loc);
10320 case NodeTypeErrorType:
10321 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc);
10322 case NodeTypeBreak:
10323 return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval, result_loc);
10324 case NodeTypeContinue:
10325 return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc);
10326 case NodeTypeUnreachable:
10327 return ir_build_unreachable(irb, scope, node);
10328 case NodeTypeDefer:
10329 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc);
10330 case NodeTypeSliceExpr:
10331 return ir_gen_slice(irb, scope, node, lval, result_loc);
10332 case NodeTypeCatchExpr:
10333 return ir_gen_catch(irb, scope, node, lval, result_loc);
10334 case NodeTypeContainerDecl:
10335 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval, result_loc);
10336 case NodeTypeFnProto:
10337 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval, result_loc);
10338 case NodeTypeErrorSetDecl:
10339 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval, result_loc);
10340 case NodeTypeResume:
10341 return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval, result_loc);
10342 case NodeTypeAwaitExpr:
10343 return ir_gen_await_expr(irb, scope, node, lval, result_loc);
10344 case NodeTypeSuspend:
10345 return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval, result_loc);
10346 case NodeTypeEnumLiteral:
10347 return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval, result_loc);
10348 case NodeTypeInferredArrayType:
10349 add_node_error(irb->codegen, node,
10350 buf_sprintf("inferred array size invalid here"));
10351 return irb->codegen->invalid_inst_src;
10352 case NodeTypeAnyTypeField:
10353 return ir_lval_wrap(irb, scope,
10354 ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_anytype), lval, result_loc);
10355 }
10356 zig_unreachable();
10357}
10358
10359static ResultLoc *no_result_loc(void) {
10360 ResultLocNone *result_loc_none = heap::c_allocator.create<ResultLocNone>();
10361 result_loc_none->base.id = ResultLocIdNone;
10362 return &result_loc_none->base;
10363}
10364
10365static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *scope, LVal lval,
10366 ResultLoc *result_loc)
10367{
10368 if (lval == LValAssign) {
10369 switch (node->type) {
10370 case NodeTypeStructValueField:
10371 case NodeTypeParamDecl:
10372 case NodeTypeUsingNamespace:
10373 case NodeTypeSwitchProng:
10374 case NodeTypeSwitchRange:
10375 case NodeTypeStructField:
10376 case NodeTypeErrorSetField:
10377 case NodeTypeFnDef:
10378 case NodeTypeTestDecl:
10379 zig_unreachable();
10380
10381 // cannot be assigned to
10382 case NodeTypeBlock:
10383 case NodeTypeGroupedExpr:
10384 case NodeTypeBinOpExpr:
10385 case NodeTypeIntLiteral:
10386 case NodeTypeFloatLiteral:
10387 case NodeTypeCharLiteral:
10388 case NodeTypeIfBoolExpr:
10389 case NodeTypeContainerInitExpr:
10390 case NodeTypeVariableDeclaration:
10391 case NodeTypeWhileExpr:
10392 case NodeTypeForExpr:
10393 case NodeTypeReturnExpr:
10394 case NodeTypeBoolLiteral:
10395 case NodeTypeArrayType:
10396 case NodeTypePointerType:
10397 case NodeTypeAnyFrameType:
10398 case NodeTypeStringLiteral:
10399 case NodeTypeUndefinedLiteral:
10400 case NodeTypeAsmExpr:
10401 case NodeTypeNullLiteral:
10402 case NodeTypeIfErrorExpr:
10403 case NodeTypeIfOptional:
10404 case NodeTypeSwitchExpr:
10405 case NodeTypeCompTime:
10406 case NodeTypeNoSuspend:
10407 case NodeTypeErrorType:
10408 case NodeTypeBreak:
10409 case NodeTypeContinue:
10410 case NodeTypeUnreachable:
10411 case NodeTypeDefer:
10412 case NodeTypeSliceExpr:
10413 case NodeTypeCatchExpr:
10414 case NodeTypeContainerDecl:
10415 case NodeTypeFnProto:
10416 case NodeTypeErrorSetDecl:
10417 case NodeTypeResume:
10418 case NodeTypeAwaitExpr:
10419 case NodeTypeSuspend:
10420 case NodeTypeEnumLiteral:
10421 case NodeTypeInferredArrayType:
10422 case NodeTypeAnyTypeField:
10423 case NodeTypePrefixOpExpr:
10424 add_node_error(irb->codegen, node,
10425 buf_sprintf("invalid left-hand side to assignment"));
10426 return irb->codegen->invalid_inst_src;
10427
10428 // @field can be assigned to
10429 case NodeTypeFnCallExpr:
10430 if (node->data.fn_call_expr.modifier == CallModifierBuiltin) {
10431 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
10432 Buf *name = fn_ref_expr->data.symbol_expr.symbol;
10433 auto entry = irb->codegen->builtin_fn_table.maybe_get(name);
10434
10435 if (!entry) {
10436 add_node_error(irb->codegen, node,
10437 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name)));
10438 return irb->codegen->invalid_inst_src;
10439 }
10440
10441 if (entry->value->id == BuiltinFnIdField) {
10442 break;
10443 }
10444 }
10445 add_node_error(irb->codegen, node,
10446 buf_sprintf("invalid left-hand side to assignment"));
10447 return irb->codegen->invalid_inst_src;
10448
10449
10450 // can be assigned to
10451 case NodeTypeUnwrapOptional:
10452 case NodeTypePtrDeref:
10453 case NodeTypeFieldAccessExpr:
10454 case NodeTypeArrayAccessExpr:
10455 case NodeTypeSymbol:
10456 break;
10457 }
10458 }
10459 if (result_loc == nullptr) {
10460 // Create a result location indicating there is none - but if one gets created
10461 // it will be properly distributed.
10462 result_loc = no_result_loc();
10463 ir_build_reset_result(irb, scope, node, result_loc);
10464 }
10465 Scope *child_scope;
10466 if (irb->exec->is_inline ||
10467 (irb->exec->fn_entry != nullptr && irb->exec->fn_entry->child_scope == scope))
10468 {
10469 child_scope = scope;
10470 } else {
10471 child_scope = &create_expr_scope(irb->codegen, node, scope)->base;
10472 }
10473 IrInstSrc *result = ir_gen_node_raw(irb, node, child_scope, lval, result_loc);
10474 if (result == irb->codegen->invalid_inst_src) {
10475 if (irb->exec->first_err_trace_msg == nullptr) {
10476 irb->exec->first_err_trace_msg = irb->codegen->trace_err;
10477 }
10478 }
10479 return result;
10480}
10481
10482static IrInstSrc *ir_gen_node(IrBuilderSrc *irb, AstNode *node, Scope *scope) {
10483 return ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
10484}
10485
10486static void invalidate_exec(IrExecutableSrc *exec, ErrorMsg *msg) {
10487 if (exec->first_err_trace_msg != nullptr)
10488 return;
10489
10490 exec->first_err_trace_msg = msg;
10491
10492 for (size_t i = 0; i < exec->tld_list.length; i += 1) {
10493 exec->tld_list.items[i]->resolution = TldResolutionInvalid;
10494 }
10495}
10496
10497static void invalidate_exec_gen(IrExecutableGen *exec, ErrorMsg *msg) {
2519static void invalidate_exec_gen(Stage1Air *exec, ErrorMsg *msg) {
104982520 if (exec->first_err_trace_msg != nullptr)
104992521 return;
105002522
......@@ -10509,79 +2531,7 @@ static void invalidate_exec_gen(IrExecutableGen *exec, ErrorMsg *msg) {
105092531}
105102532
105112533
10512bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutableSrc *ir_executable) {
10513 assert(node->owner);
10514
10515 IrBuilderSrc ir_builder = {0};
10516 IrBuilderSrc *irb = &ir_builder;
10517
10518 irb->codegen = codegen;
10519 irb->exec = ir_executable;
10520 irb->main_block_node = node;
10521
10522 IrBasicBlockSrc *entry_block = ir_create_basic_block(irb, scope, "Entry");
10523 ir_set_cursor_at_end_and_append_block(irb, entry_block);
10524 // Entry block gets a reference because we enter it to begin.
10525 ir_ref_bb(irb->current_basic_block);
10526
10527 IrInstSrc *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr);
10528
10529 if (result == irb->codegen->invalid_inst_src)
10530 return false;
10531
10532 if (irb->exec->first_err_trace_msg != nullptr) {
10533 codegen->trace_err = irb->exec->first_err_trace_msg;
10534 return false;
10535 }
10536
10537 if (!instr_is_unreachable(result)) {
10538 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->base.source_node, result, nullptr));
10539 // no need for save_err_ret_addr because this cannot return error
10540 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
10541 result_loc_ret->base.id = ResultLocIdReturn;
10542 ir_build_reset_result(irb, scope, node, &result_loc_ret->base);
10543 ir_mark_gen(ir_build_end_expr(irb, scope, node, result, &result_loc_ret->base));
10544 ir_mark_gen(ir_build_return_src(irb, scope, result->base.source_node, result));
10545 }
10546
10547 return true;
10548}
10549
10550bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) {
10551 assert(fn_entry);
10552
10553 IrExecutableSrc *ir_executable = fn_entry->ir_executable;
10554 AstNode *body_node = fn_entry->body_node;
10555
10556 assert(fn_entry->child_scope);
10557
10558 return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable);
10559}
10560
10561static void ir_add_call_stack_errors_gen(CodeGen *codegen, IrExecutableGen *exec, ErrorMsg *err_msg, int limit) {
10562 if (!exec || !exec->source_node || limit < 0) return;
10563 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here"));
10564
10565 ir_add_call_stack_errors_gen(codegen, exec->parent_exec, err_msg, limit - 1);
10566}
10567
10568static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutableSrc *exec, ErrorMsg *err_msg, int limit) {
10569 if (!exec || !exec->source_node || limit < 0) return;
10570 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here"));
10571
10572 ir_add_call_stack_errors_gen(codegen, exec->parent_exec, err_msg, limit - 1);
10573}
10574
10575static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutableSrc *exec, AstNode *source_node, Buf *msg) {
10576 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);
10577 invalidate_exec(exec, err_msg);
10578 if (exec->parent_exec) {
10579 ir_add_call_stack_errors(codegen, exec, err_msg, 10);
10580 }
10581 return err_msg;
10582}
10583
10584static ErrorMsg *exec_add_error_node_gen(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, Buf *msg) {
2534static ErrorMsg *exec_add_error_node_gen(CodeGen *codegen, Stage1Air *exec, AstNode *source_node, Buf *msg) {
105852535 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);
105862536 invalidate_exec_gen(exec, err_msg);
105872537 if (exec->parent_exec) {
......@@ -10605,11 +2555,6 @@ static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInst *source_instruction, Buf *m
106052555 return ir_add_error_node(ira, source_instruction->source_node, msg);
106062556}
106072557
10608static void ir_assert_impl(bool ok, IrInst *source_instruction, char const *file, unsigned int line) {
10609 if (ok) return;
10610 src_assert_impl(ok, source_instruction->source_node, file, line);
10611}
10612
106132558static void ir_assert_gen_impl(bool ok, IrInstGen *source_instruction, char const *file, unsigned int line) {
106142559 if (ok) return;
106152560 src_assert_impl(ok, source_instruction->base.source_node, file, line);
......@@ -10660,7 +2605,7 @@ ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_va
106602605 return val;
106612606}
106622607
10663static Error ir_exec_scan_for_side_effects(CodeGen *codegen, IrExecutableGen *exec) {
2608static Error ir_exec_scan_for_side_effects(CodeGen *codegen, Stage1Air *exec) {
106642609 IrBasicBlockGen *bb = exec->basic_block_list.at(0);
106652610 for (size_t i = 0; i < bb->instruction_list.length; i += 1) {
106662611 IrInstGen *instruction = bb->instruction_list.at(i);
......@@ -10690,7 +2635,7 @@ static Error ir_exec_scan_for_side_effects(CodeGen *codegen, IrExecutableGen *ex
106902635}
106912636
106922637static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInst* source_instruction) {
10693 if (ir_should_inline(ira->old_irb.exec, source_instruction->scope)) {
2638 if (ir_should_inline(ira->zir, source_instruction->scope)) {
106942639 ir_add_error(ira, source_instruction, buf_sprintf("unable to evaluate constant expression"));
106952640 return false;
106962641 }
......@@ -12315,7 +4260,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
123154260 continue;
123164261 }
123174262 bool allow_infer = cur_type->data.error_set.infer_fn != nullptr &&
12318 cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
4263 cur_type->data.error_set.infer_fn == ira->fn;
123194264 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) {
123204265 return ira->codegen->builtin_types.entry_invalid;
123214266 }
......@@ -12383,7 +4328,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
123834328 }
123844329 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;
123854330 bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr &&
12386 cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
4331 cur_err_set_type->data.error_set.infer_fn == ira->fn;
123874332 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) {
123884333 return ira->codegen->builtin_types.entry_invalid;
123894334 }
......@@ -12438,7 +4383,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
124384383
124394384 if (cur_type->id == ZigTypeIdErrorSet) {
124404385 bool allow_infer = cur_type->data.error_set.infer_fn != nullptr &&
12441 cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
4386 cur_type->data.error_set.infer_fn == ira->fn;
124424387 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) {
124434388 return ira->codegen->builtin_types.entry_invalid;
124444389 }
......@@ -12457,7 +4402,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
124574402 if (prev_type->id == ZigTypeIdErrorUnion) {
124584403 err_set_type = prev_type->data.error_union.err_set_type;
124594404 allow_infer = err_set_type->data.error_set.infer_fn != nullptr &&
12460 err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
4405 err_set_type->data.error_set.infer_fn == ira->fn;
124614406 } else {
124624407 err_set_type = cur_type;
124634408 }
......@@ -12521,9 +4466,9 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
125214466 continue;
125224467
125234468 bool allow_infer_prev = prev_err_set_type->data.error_set.infer_fn != nullptr &&
12524 prev_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
4469 prev_err_set_type->data.error_set.infer_fn == ira->fn;
125254470 bool allow_infer_cur = cur_err_set_type->data.error_set.infer_fn != nullptr &&
12526 cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
4471 cur_err_set_type->data.error_set.infer_fn == ira->fn;
125274472
125284473 if (!allow_infer_prev && !resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->base.source_node)) {
125294474 return ira->codegen->builtin_types.entry_invalid;
......@@ -12707,7 +4652,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
127074652 if (err_set_type != nullptr) {
127084653 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type;
127094654 bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr &&
12710 cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry;
4655 cur_err_set_type->data.error_set.infer_fn == ira->fn;
127114656 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) {
127124657 return ira->codegen->builtin_types.entry_invalid;
127134658 }
......@@ -13316,7 +5261,7 @@ static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* sourc
133165261 return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, array_ptr, result_loc_inst);
133175262}
133185263
13319static IrBasicBlockGen *ir_get_new_bb(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrInst *ref_old_instruction) {
5264static IrBasicBlockGen *ir_get_new_bb(IrAnalyze *ira, Stage1ZirBasicBlock *old_bb, IrInst *ref_old_instruction) {
133205265 assert(old_bb);
133215266
133225267 if (old_bb->child) {
......@@ -13331,7 +5276,7 @@ static IrBasicBlockGen *ir_get_new_bb(IrAnalyze *ira, IrBasicBlockSrc *old_bb, I
133315276 return new_bb;
133325277}
133335278
13334static IrBasicBlockGen *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrInst *ref_old_instruction) {
5279static IrBasicBlockGen *ir_get_new_bb_runtime(IrAnalyze *ira, Stage1ZirBasicBlock *old_bb, IrInst *ref_old_instruction) {
133355280 assert(ref_old_instruction != nullptr);
133365281 IrBasicBlockGen *new_bb = ir_get_new_bb(ira, old_bb, ref_old_instruction);
133375282 if (new_bb->must_be_comptime_source_instr) {
......@@ -13344,36 +5289,36 @@ static IrBasicBlockGen *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlockSrc *o
133445289 return new_bb;
133455290}
133465291
13347static void ir_start_bb(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrBasicBlockSrc *const_predecessor_bb) {
5292static void ir_start_bb(IrAnalyze *ira, Stage1ZirBasicBlock *old_bb, Stage1ZirBasicBlock *const_predecessor_bb) {
133485293 ir_assert(!old_bb->suspended, (old_bb->instruction_list.length != 0) ? &old_bb->instruction_list.at(0)->base : nullptr);
133495294 ira->instruction_index = 0;
13350 ira->old_irb.current_basic_block = old_bb;
5295 ira->zir_current_basic_block = old_bb;
133515296 ira->const_predecessor_bb = const_predecessor_bb;
133525297 ira->old_bb_index = old_bb->index;
133535298}
133545299
13355static IrInstGen *ira_suspend(IrAnalyze *ira, IrInst *old_instruction, IrBasicBlockSrc *next_bb,
5300static IrInstGen *ira_suspend(IrAnalyze *ira, IrInst *old_instruction, Stage1ZirBasicBlock *next_bb,
133565301 IrSuspendPosition *suspend_pos)
133575302{
133585303 if (ira->codegen->verbose_ir) {
133595304 fprintf(stderr, "suspend %s_%" PRIu32 " %s_%" PRIu32 " #%" PRIu32 " (%zu,%zu)\n",
13360 ira->old_irb.current_basic_block->name_hint,
13361 ira->old_irb.current_basic_block->debug_id,
13362 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint,
13363 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id,
13364 ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->base.debug_id,
5305 ira->zir_current_basic_block->name_hint,
5306 ira->zir_current_basic_block->debug_id,
5307 ira->zir->basic_block_list.at(ira->old_bb_index)->name_hint,
5308 ira->zir->basic_block_list.at(ira->old_bb_index)->debug_id,
5309 ira->zir_current_basic_block->instruction_list.at(ira->instruction_index)->base.debug_id,
133655310 ira->old_bb_index, ira->instruction_index);
133665311 }
133675312 suspend_pos->basic_block_index = ira->old_bb_index;
133685313 suspend_pos->instruction_index = ira->instruction_index;
133695314
13370 ira->old_irb.current_basic_block->suspended = true;
5315 ira->zir_current_basic_block->suspended = true;
133715316
133725317 // null next_bb means that the caller plans to call ira_resume before returning
133735318 if (next_bb != nullptr) {
133745319 ira->old_bb_index = next_bb->index;
13375 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);
13376 assert(ira->old_irb.current_basic_block == next_bb);
5320 ira->zir_current_basic_block = ira->zir->basic_block_list.at(ira->old_bb_index);
5321 assert(ira->zir_current_basic_block == next_bb);
133775322 ira->instruction_index = 0;
133785323 ira->const_predecessor_bb = nullptr;
133795324 next_bb->child = ir_get_new_bb_runtime(ira, next_bb, old_instruction);
......@@ -13388,19 +5333,19 @@ static IrInstGen *ira_resume(IrAnalyze *ira) {
133885333 fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index);
133895334 }
133905335 ira->old_bb_index = pos.basic_block_index;
13391 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);
13392 assert(ira->old_irb.current_basic_block->in_resume_stack);
13393 ira->old_irb.current_basic_block->in_resume_stack = false;
13394 ira->old_irb.current_basic_block->suspended = false;
5336 ira->zir_current_basic_block = ira->zir->basic_block_list.at(ira->old_bb_index);
5337 assert(ira->zir_current_basic_block->in_resume_stack);
5338 ira->zir_current_basic_block->in_resume_stack = false;
5339 ira->zir_current_basic_block->suspended = false;
133955340 ira->instruction_index = pos.instruction_index;
13396 assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length);
5341 assert(pos.instruction_index < ira->zir_current_basic_block->instruction_list.length);
133975342 if (ira->codegen->verbose_ir) {
13398 fprintf(stderr, "%s_%" PRIu32 " #%" PRIu32 "\n", ira->old_irb.current_basic_block->name_hint,
13399 ira->old_irb.current_basic_block->debug_id,
13400 ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->base.debug_id);
5343 fprintf(stderr, "%s_%" PRIu32 " #%" PRIu32 "\n", ira->zir_current_basic_block->name_hint,
5344 ira->zir_current_basic_block->debug_id,
5345 ira->zir_current_basic_block->instruction_list.at(pos.instruction_index)->base.debug_id);
134015346 }
134025347 ira->const_predecessor_bb = nullptr;
13403 ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->child;
5348 ira->new_irb.current_basic_block = ira->zir_current_basic_block->child;
134045349 assert(ira->new_irb.current_basic_block != nullptr);
134055350 return ira->codegen->unreach_instruction;
134065351}
......@@ -13410,8 +5355,8 @@ static void ir_start_next_bb(IrAnalyze *ira) {
134105355
134115356 bool need_repeat = true;
134125357 for (;;) {
13413 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) {
13414 IrBasicBlockSrc *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);
5358 while (ira->old_bb_index < ira->zir->basic_block_list.length) {
5359 Stage1ZirBasicBlock *old_bb = ira->zir->basic_block_list.at(ira->old_bb_index);
134155360 if (old_bb->child == nullptr && old_bb->suspend_instruction_ref == nullptr) {
134165361 ira->old_bb_index += 1;
134175362 continue;
......@@ -13463,8 +5408,8 @@ static void ir_finish_bb(IrAnalyze *ira) {
134635408 }
134645409 }
134655410 ira->instruction_index += 1;
13466 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) {
13467 IrInstSrc *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);
5411 while (ira->instruction_index < ira->zir_current_basic_block->instruction_list.length) {
5412 IrInstSrc *next_instruction = ira->zir_current_basic_block->instruction_list.at(ira->instruction_index);
134685413 if (!next_instruction->is_gen) {
134695414 ir_add_error(ira, &next_instruction->base, buf_sprintf("unreachable code"));
134705415 break;
......@@ -13484,8 +5429,8 @@ static IrInstGen *ir_unreach_error(IrAnalyze *ira) {
134845429}
134855430
134865431static bool ir_emit_backward_branch(IrAnalyze *ira, IrInst* source_instruction) {
13487 size_t *bbc = ira->new_irb.exec->backward_branch_count;
13488 size_t *quota = ira->new_irb.exec->backward_branch_quota;
5432 size_t *bbc = ira->backward_branch_count;
5433 size_t *quota = ira->backward_branch_quota;
134895434
134905435 // If we're already over quota, we've already given an error message for this.
134915436 if (*bbc > *quota) {
......@@ -13502,14 +5447,14 @@ static bool ir_emit_backward_branch(IrAnalyze *ira, IrInst* source_instruction)
135025447 return true;
135035448}
135045449
13505static IrInstGen *ir_inline_bb(IrAnalyze *ira, IrInst* source_instruction, IrBasicBlockSrc *old_bb) {
13506 if (old_bb->debug_id <= ira->old_irb.current_basic_block->debug_id) {
5450static IrInstGen *ir_inline_bb(IrAnalyze *ira, IrInst* source_instruction, Stage1ZirBasicBlock *old_bb) {
5451 if (old_bb->debug_id <= ira->zir_current_basic_block->debug_id) {
135075452 if (!ir_emit_backward_branch(ira, source_instruction))
135085453 return ir_unreach_error(ira);
135095454 }
135105455
13511 old_bb->child = ira->old_irb.current_basic_block->child;
13512 ir_start_bb(ira, old_bb, ira->old_irb.current_basic_block);
5456 old_bb->child = ira->zir_current_basic_block->child;
5457 ir_start_bb(ira, old_bb, ira->zir_current_basic_block);
135135458 return ira->codegen->unreach_instruction;
135145459}
135155460
......@@ -13591,7 +5536,7 @@ static IrInstGen *ir_get_const_ptr(IrAnalyze *ira, IrInst *instruction,
135915536 return const_instr;
135925537}
135935538
13594static Error ir_resolve_const_val(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node,
5539static Error ir_resolve_const_val(CodeGen *codegen, Stage1Air *exec, AstNode *source_node,
135955540 ZigValue *val, UndefAllowed undef_allowed)
135965541{
135975542 Error err;
......@@ -13638,7 +5583,7 @@ static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed
136385583Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
136395584 ZigValue *return_ptr, size_t *backward_branch_count, size_t *backward_branch_quota,
136405585 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
13641 IrExecutableGen *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef_allowed)
5586 Stage1Air *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef_allowed)
136425587{
136435588 Error err;
136445589
......@@ -13647,43 +5592,38 @@ Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
136475592 if (type_is_invalid(return_ptr->type))
136485593 return ErrorSemanticAnalyzeFail;
136495594
13650 IrExecutableSrc *ir_executable = heap::c_allocator.create<IrExecutableSrc>();
13651 ir_executable->source_node = source_node;
13652 ir_executable->parent_exec = parent_exec;
13653 ir_executable->name = exec_name;
13654 ir_executable->is_inline = true;
13655 ir_executable->fn_entry = fn_entry;
13656 ir_executable->c_import_buf = c_import_buf;
13657 ir_executable->begin_scope = scope;
5595 Stage1Zir *stage1_zir = heap::c_allocator.create<Stage1Zir>();
5596 stage1_zir->name = exec_name;
5597 stage1_zir->is_inline = true;
5598 stage1_zir->begin_scope = scope;
5599
5600 bool in_c_import_scope = c_import_buf != nullptr;
136585601
13659 if (!ir_gen(codegen, node, scope, ir_executable))
5602 if (!stage1_astgen(codegen, node, scope, stage1_zir, fn_entry, in_c_import_scope))
136605603 return ErrorSemanticAnalyzeFail;
136615604
13662 if (ir_executable->first_err_trace_msg != nullptr) {
13663 codegen->trace_err = ir_executable->first_err_trace_msg;
5605 if (stage1_zir->first_err_trace_msg != nullptr) {
5606 codegen->trace_err = stage1_zir->first_err_trace_msg;
136645607 return ErrorSemanticAnalyzeFail;
136655608 }
136665609
136675610 if (codegen->verbose_ir) {
13668 fprintf(stderr, "\nSource: ");
13669 ast_render(stderr, node, 4);
136705611 fprintf(stderr, "\n{ // (IR)\n");
13671 ir_print_src(codegen, stderr, ir_executable, 2);
5612 ir_print_src(codegen, stderr, stage1_zir, 2);
136725613 fprintf(stderr, "}\n");
136735614 }
13674 IrExecutableGen *analyzed_executable = heap::c_allocator.create<IrExecutableGen>();
5615 Stage1Air *analyzed_executable = heap::c_allocator.create<Stage1Air>();
136755616 analyzed_executable->source_node = source_node;
136765617 analyzed_executable->parent_exec = parent_exec;
13677 analyzed_executable->source_exec = ir_executable;
5618 analyzed_executable->source_exec = stage1_zir;
136785619 analyzed_executable->name = exec_name;
136795620 analyzed_executable->is_inline = true;
13680 analyzed_executable->fn_entry = fn_entry;
136815621 analyzed_executable->c_import_buf = c_import_buf;
13682 analyzed_executable->backward_branch_count = backward_branch_count;
13683 analyzed_executable->backward_branch_quota = backward_branch_quota;
136845622 analyzed_executable->begin_scope = scope;
13685 ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable,
13686 return_ptr->type->data.pointer.child_type, expected_type_source_node, return_ptr);
5623 ZigType *result_type = ir_analyze(codegen, stage1_zir, analyzed_executable,
5624 backward_branch_count, backward_branch_quota,
5625 return_ptr->type->data.pointer.child_type, expected_type_source_node, return_ptr,
5626 fn_entry);
136875627 if (type_is_invalid(result_type)) {
136885628 return ErrorSemanticAnalyzeFail;
136895629 }
......@@ -13724,7 +5664,7 @@ static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstGen *err_value) {
137245664 return const_val->data.x_err_set;
137255665}
137265666
13727static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node,
5667static ZigType *ir_resolve_const_type(CodeGen *codegen, Stage1Air *exec, AstNode *source_node,
137285668 ZigValue *val)
137295669{
137305670 Error err;
......@@ -14976,7 +6916,7 @@ static IrInstGen *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInst* sou
149766916 size_t instr_field_count = actual_type->data.structure.src_field_count;
149776917 assert(array_len == instr_field_count);
149786918
14979 bool need_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope)
6919 bool need_comptime = ir_should_inline(ira->zir, source_instr->scope)
149806920 || type_requires_comptime(ira->codegen, wanted_type) == ReqCompTimeYes;
149816921 bool is_comptime = true;
149826922
......@@ -15066,7 +7006,7 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* so
150667006 size_t actual_field_count = wanted_type->data.structure.src_field_count;
150677007 size_t instr_field_count = actual_type->data.structure.src_field_count;
150687008
15069 bool need_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope)
7009 bool need_comptime = ir_should_inline(ira->zir, source_instr->scope)
150707010 || type_requires_comptime(ira->codegen, wanted_type) == ReqCompTimeYes;
150717011 bool is_comptime = true;
150727012
......@@ -16132,7 +8072,7 @@ static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst* source_instruction, IrIns
161328072 return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst);
161338073}
161348074
16135static bool ir_resolve_const_align(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node,
8075static bool ir_resolve_const_align(CodeGen *codegen, Stage1Air *exec, AstNode *source_node,
161368076 ZigValue *const_val, uint32_t *out)
161378077{
161388078 Error err;
......@@ -19085,7 +11025,7 @@ static IrInstGen *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstSrcDeclV
1908511025 return ira->codegen->invalid_inst_gen;
1908611026 }
1908711027
19088 ZigFn *fn_entry = ira->new_irb.exec->fn_entry;
11028 ZigFn *fn_entry = ira->fn;
1908911029 if (fn_entry)
1909011030 fn_entry->variable_list.append(var);
1909111031
......@@ -19481,9 +11421,9 @@ static IrInstGen *ir_analyze_instruction_extern(IrAnalyze *ira, IrInstSrcExtern
1948111421 is_thread_local, expr_type);
1948211422}
1948311423
19484static bool exec_has_err_ret_trace(CodeGen *g, IrExecutableSrc *exec) {
19485 ZigFn *fn_entry = exec_fn_entry(exec);
19486 return fn_entry != nullptr && fn_entry->calls_or_awaits_errorable_fn && g->have_err_ret_tracing;
11424static bool ira_has_err_ret_trace(IrAnalyze *ira) {
11425 ZigFn *fn = ira->fn;
11426 return fn != nullptr && fn->calls_or_awaits_errorable_fn && ira->codegen->have_err_ret_tracing;
1948711427}
1948811428
1948911429static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira,
......@@ -19492,7 +11432,7 @@ static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira,
1949211432 ZigType *ptr_to_stack_trace_type = get_pointer_to_type(ira->codegen, get_stack_trace_type(ira->codegen), false);
1949311433 if (instruction->optional == IrInstErrorReturnTraceNull) {
1949411434 ZigType *optional_type = get_optional_type(ira->codegen, ptr_to_stack_trace_type);
19495 if (!exec_has_err_ret_trace(ira->codegen, ira->old_irb.exec)) {
11435 if (!ira_has_err_ret_trace(ira)) {
1949611436 IrInstGen *result = ir_const(ira, &instruction->base.base, optional_type);
1949711437 ZigValue *out_val = result->value;
1949811438 assert(get_src_ptr_type(optional_type) != nullptr);
......@@ -19564,7 +11504,7 @@ static IrInstGen *ir_analyze_alloca(IrAnalyze *ira, IrInst *source_inst, ZigType
1956411504 PtrLenSingle, align, 0, 0, false);
1956511505
1956611506 if (!force_comptime) {
19567 ZigFn *fn_entry = ira->new_irb.exec->fn_entry;
11507 ZigFn *fn_entry = ira->fn;
1956811508 if (fn_entry != nullptr) {
1956911509 fn_entry->alloca_gen_list.append(result);
1957011510 }
......@@ -19663,7 +11603,7 @@ static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_sourc
1966311603 alloca_gen->base.value->type = get_pointer_to_type_extra(ira->codegen, value_type, false, false,
1966411604 PtrLenSingle, 0, 0, 0, false);
1966511605 set_up_result_loc_for_inferred_comptime(ira, &alloca_gen->base);
19666 ZigFn *fn_entry = ira->new_irb.exec->fn_entry;
11606 ZigFn *fn_entry = ira->fn;
1966711607 if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) {
1966811608 fn_entry->alloca_gen_list.append(alloca_gen);
1966911609 }
......@@ -20191,7 +12131,7 @@ static IrInstGen *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstSr
2019112131 if (result_loc != nullptr)
2019212132 return result_loc;
2019312133
20194 ZigFn *fn = ira->new_irb.exec->fn_entry;
12134 ZigFn *fn = ira->fn;
2019512135 if (fn != nullptr && fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync &&
2019612136 instruction->result_loc->id == ResultLocIdReturn)
2019712137 {
......@@ -20319,7 +12259,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node
2031912259 assert(param_decl_node->type == NodeTypeParamDecl);
2032012260
2032112261 IrInstGen *casted_arg;
20322 if (param_decl_node->data.param_decl.anytype_token == nullptr) {
12262 if (param_decl_node->data.param_decl.anytype_token == 0) {
2032312263 AstNode *param_type_node = param_decl_node->data.param_decl.type;
2032412264 ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node);
2032512265 if (type_is_invalid(param_type))
......@@ -20362,7 +12302,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
2036212302 casted_arg = arg;
2036312303 param_info_type = arg->value->type;
2036412304 } else {
20365 if (param_decl_node->data.param_decl.anytype_token == nullptr) {
12305 if (param_decl_node->data.param_decl.anytype_token == 0) {
2036612306 AstNode *param_type_node = param_decl_node->data.param_decl.type;
2036712307 ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node);
2036812308 if (type_is_invalid(param_type))
......@@ -20813,7 +12753,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
2081312753 create_result_ptr(ira->codegen, return_type, &result, &result_ptr);
2081412754
2081512755 if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr,
20816 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota,
12756 ira->backward_branch_count, ira->backward_branch_quota,
2081712757 fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node,
2081812758 UndefOk)))
2081912759 {
......@@ -20909,7 +12849,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
2090912849 }
2091012850 }
2091112851
20912 ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry;
12852 ZigFn *parent_fn_entry = ira->fn;
2091312853 assert(parent_fn_entry);
2091412854 for (size_t call_i = 0; call_i < args_len; call_i += 1) {
2091512855 IrInstGen *arg = args_ptr[call_i];
......@@ -20930,7 +12870,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
2093012870 create_result_ptr(ira->codegen, get_align_amt_type(ira->codegen), &align_result, &result_ptr);
2093112871 if ((err = ir_eval_const_value(ira->codegen, impl_fn->child_scope,
2093212872 fn_proto_node->data.fn_proto.align_expr, result_ptr,
20933 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota,
12873 ira->backward_branch_count, ira->backward_branch_quota,
2093412874 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec,
2093512875 nullptr, UndefBad)))
2093612876 {
......@@ -20994,12 +12934,9 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
2099412934 if (type_is_invalid(impl_fn->type_entry))
2099512935 return ira->codegen->invalid_inst_gen;
2099612936
20997 impl_fn->ir_executable->source_node = source_instr->source_node;
20998 impl_fn->ir_executable->parent_exec = ira->new_irb.exec;
2099912937 impl_fn->analyzed_executable.source_node = source_instr->source_node;
2100012938 impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec;
21001 impl_fn->analyzed_executable.backward_branch_quota = ira->new_irb.exec->backward_branch_quota;
21002 impl_fn->analyzed_executable.is_generic_instantiation = true;
12939 impl_fn->branch_quota = *ira->backward_branch_quota;
2100312940
2100412941 ira->codegen->fn_defs.append(impl_fn);
2100512942 }
......@@ -21079,7 +13016,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
2107913016 return ir_finish_anal(ira, &new_call_instruction->base);
2108013017 }
2108113018
21082 ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry;
13019 ZigFn *parent_fn_entry = ira->fn;
2108313020 assert(fn_type_id->return_type != nullptr);
2108413021 assert(parent_fn_entry != nullptr);
2108513022 if (fn_type_can_fail(fn_type_id)) {
......@@ -21275,7 +13212,7 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr,
2127513212 return ira->codegen->invalid_inst_gen;
2127613213 CallModifier modifier = (CallModifier)bigint_as_u32(&modifier_val->data.x_enum_tag);
2127713214
21278 if (ir_should_inline(ira->old_irb.exec, source_instr->scope)) {
13215 if (ir_should_inline(ira->zir, source_instr->scope)) {
2127913216 switch (modifier) {
2128013217 case CallModifierBuiltin:
2128113218 zig_unreachable();
......@@ -21364,7 +13301,7 @@ static IrInstGen *ir_analyze_async_call_extra(IrAnalyze *ira, IrInst* source_ins
2136413301 if (type_is_invalid(fn_ref->value->type))
2136513302 return ira->codegen->invalid_inst_gen;
2136613303
21367 if (ir_should_inline(ira->old_irb.exec, source_instr->scope)) {
13304 if (ir_should_inline(ira->zir, source_instr->scope)) {
2136813305 ir_add_error(ira, source_instr, buf_sprintf("TODO: comptime @asyncCall"));
2136913306 return ira->codegen->invalid_inst_gen;
2137013307 }
......@@ -21477,7 +13414,7 @@ static IrInstGen *ir_analyze_instruction_call(IrAnalyze *ira, IrInstSrcCall *cal
2147713414 return ira->codegen->invalid_inst_gen;
2147813415
2147913416 bool is_comptime = (call_instruction->modifier == CallModifierCompileTime) ||
21480 ir_should_inline(ira->old_irb.exec, call_instruction->base.base.scope);
13417 ir_should_inline(ira->zir, call_instruction->base.base.scope);
2148113418 CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier;
2148213419
2148313420 if (is_comptime || instr_is_comptime(fn_ref)) {
......@@ -21839,20 +13776,20 @@ static IrInstGen *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstSrcUnOp *in
2183913776}
2184013777
2184113778static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) {
21842 IrBasicBlockSrc *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index);
13779 Stage1ZirBasicBlock *old_bb = ira->zir->basic_block_list.at(pos.basic_block_index);
2184313780 if (old_bb->in_resume_stack) return;
2184413781 ira->resume_stack.append(pos);
2184513782 old_bb->in_resume_stack = true;
2184613783}
2184713784
21848static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlockSrc *old_bb) {
13785static void ir_push_resume_block(IrAnalyze *ira, Stage1ZirBasicBlock *old_bb) {
2184913786 if (ira->resume_stack.length != 0) {
2185013787 ir_push_resume(ira, {old_bb->index, 0});
2185113788 }
2185213789}
2185313790
2185413791static IrInstGen *ir_analyze_instruction_br(IrAnalyze *ira, IrInstSrcBr *br_instruction) {
21855 IrBasicBlockSrc *old_dest_block = br_instruction->dest_block;
13792 Stage1ZirBasicBlock *old_dest_block = br_instruction->dest_block;
2185613793
2185713794 bool is_comptime;
2185813795 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime))
......@@ -21890,7 +13827,7 @@ static IrInstGen *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstSrcCondBr
2189013827 if (!ir_resolve_bool(ira, casted_condition, &cond_is_true))
2189113828 return ir_unreach_error(ira);
2189213829
21893 IrBasicBlockSrc *old_dest_block = cond_is_true ?
13830 Stage1ZirBasicBlock *old_dest_block = cond_is_true ?
2189413831 cond_br_instruction->then_block : cond_br_instruction->else_block;
2189513832
2189613833 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr))
......@@ -21926,7 +13863,7 @@ static IrInstGen *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstSrcCondBr
2192613863static IrInstGen *ir_analyze_instruction_unreachable(IrAnalyze *ira,
2192713864 IrInstSrcUnreachable *unreachable_instruction)
2192813865{
21929 if (ir_should_inline(ira->old_irb.exec, unreachable_instruction->base.base.scope)) {
13866 if (ir_should_inline(ira->zir, unreachable_instruction->base.base.scope)) {
2193013867 ir_add_error(ira, &unreachable_instruction->base.base, buf_sprintf("reached unreachable code"));
2193113868 return ir_unreach_error(ira);
2193213869 }
......@@ -21940,7 +13877,7 @@ static IrInstGen *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstSrcPhi *phi_i
2194013877
2194113878 if (ira->const_predecessor_bb) {
2194213879 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {
21943 IrBasicBlockSrc *predecessor = phi_instruction->incoming_blocks[i];
13880 Stage1ZirBasicBlock *predecessor = phi_instruction->incoming_blocks[i];
2194413881 if (predecessor != ira->const_predecessor_bb)
2194513882 continue;
2194613883 IrInstGen *value = phi_instruction->incoming_values[i]->child;
......@@ -22040,7 +13977,7 @@ static IrInstGen *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstSrcPhi *phi_i
2204013977 ZigList<IrInstGen*> new_incoming_values = {0};
2204113978
2204213979 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {
22043 IrBasicBlockSrc *predecessor = phi_instruction->incoming_blocks[i];
13980 Stage1ZirBasicBlock *predecessor = phi_instruction->incoming_blocks[i];
2204413981 if (predecessor->ref_count == 0)
2204513982 continue;
2204613983
......@@ -23593,6 +15530,25 @@ static IrInstGen *ir_analyze_instruction_slice_type(IrAnalyze *ira, IrInstSrcSli
2359315530 return result;
2359415531}
2359515532
15533static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_template) {
15534 const char *ptr = buf_ptr(src_template) + tok->start + 2;
15535 size_t len = tok->end - tok->start - 2;
15536 size_t result = 0;
15537 for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1, result += 1) {
15538 AsmOutput *asm_output = node->data.asm_expr.output_list.at(i);
15539 if (buf_eql_mem(asm_output->asm_symbolic_name, ptr, len)) {
15540 return result;
15541 }
15542 }
15543 for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1, result += 1) {
15544 AsmInput *asm_input = node->data.asm_expr.input_list.at(i);
15545 if (buf_eql_mem(asm_input->asm_symbolic_name, ptr, len)) {
15546 return result;
15547 }
15548 }
15549 return SIZE_MAX;
15550}
15551
2359615552static IrInstGen *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstSrcAsm *asm_instruction) {
2359715553 Error err;
2359815554
......@@ -24040,7 +15996,7 @@ static IrInstGen *ir_analyze_instruction_switch_br(IrAnalyze *ira,
2404015996 if (!target_val)
2404115997 return ir_unreach_error(ira);
2404215998
24043 IrBasicBlockSrc *old_dest_block = switch_br_instruction->else_block;
15999 Stage1ZirBasicBlock *old_dest_block = switch_br_instruction->else_block;
2404416000 for (size_t i = 0; i < case_count; i += 1) {
2404516001 IrInstSrcSwitchBrCase *old_case = &switch_br_instruction->cases[i];
2404616002 IrInstGen *case_value = old_case->value->child;
......@@ -24522,7 +16478,7 @@ static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instructi
2452216478 }
2452316479 }
2452416480
24525 bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instruction->scope)
16481 bool is_comptime = ir_should_inline(ira->zir, source_instruction->scope)
2452616482 || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes;
2452716483
2452816484 IrInstGen *result = ir_get_deref(ira, source_instruction, result_loc, nullptr);
......@@ -24575,7 +16531,7 @@ static IrInstGen *ir_analyze_container_init_fields(IrAnalyze *ira, IrInst *sourc
2457516531 AstNode **field_assign_nodes = heap::c_allocator.allocate<AstNode *>(actual_field_count);
2457616532 ZigList<IrInstGen *> const_ptrs = {};
2457716533
24578 bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope)
16534 bool is_comptime = ir_should_inline(ira->zir, source_instr->scope)
2457916535 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes;
2458016536
2458116537
......@@ -24762,7 +16718,7 @@ static IrInstGen *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
2476216718 case ReqCompTimeInvalid:
2476316719 return ira->codegen->invalid_inst_gen;
2476416720 case ReqCompTimeNo:
24765 is_comptime = ir_should_inline(ira->old_irb.exec, instruction->base.base.scope);
16721 is_comptime = ir_should_inline(ira->zir, instruction->base.base.scope);
2476616722 break;
2476716723 case ReqCompTimeYes:
2476816724 is_comptime = true;
......@@ -26534,7 +18490,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
2653418490
2653518491 Buf *bare_name = buf_alloc();
2653618492 Buf *full_name = get_anon_type_name(ira->codegen,
26537 ira->old_irb.exec, "opaque", source_instr->scope, source_instr->source_node, bare_name);
18493 ira->zir, "opaque", source_instr->scope, source_instr->source_node, bare_name);
2653818494 return get_opaque_type(ira->codegen,
2653918495 source_instr->scope, source_instr->source_node, buf_ptr(full_name), bare_name);
2654018496 }
......@@ -26581,7 +18537,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
2658118537 assert(is_slice(slice->type));
2658218538 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);
2658318539 Buf bare_name = BUF_INIT;
26584 buf_init_from_buf(&err_set_type->name, get_anon_type_name(ira->codegen, ira->old_irb.exec, "error", source_instr->scope, source_instr->source_node, &bare_name));
18540 buf_init_from_buf(&err_set_type->name, get_anon_type_name(ira->codegen, ira->zir, "error", source_instr->scope, source_instr->source_node, &bare_name));
2658518541 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits;
2658618542 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align;
2658718543 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size;
......@@ -26660,7 +18616,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
2666018616
2666118617 ZigType *entry = new_type_table_entry(ZigTypeIdStruct);
2666218618 buf_init_from_buf(&entry->name,
26663 get_anon_type_name(ira->codegen, ira->old_irb.exec, "struct", source_instr->scope, source_instr->source_node, &entry->name));
18619 get_anon_type_name(ira->codegen, ira->zir, "struct", source_instr->scope, source_instr->source_node, &entry->name));
2666418620 entry->data.structure.decl_node = source_instr->source_node;
2666518621 entry->data.structure.fields = alloc_type_struct_fields(fields_len);
2666618622 entry->data.structure.fields_by_name.init(fields_len);
......@@ -26770,7 +18726,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
2677018726
2677118727 ZigType *entry = new_type_table_entry(ZigTypeIdEnum);
2677218728 buf_init_from_buf(&entry->name,
26773 get_anon_type_name(ira->codegen, ira->old_irb.exec, "enum", source_instr->scope, source_instr->source_node, &entry->name));
18729 get_anon_type_name(ira->codegen, ira->zir, "enum", source_instr->scope, source_instr->source_node, &entry->name));
2677418730 entry->data.enumeration.decl_node = source_instr->source_node;
2677518731 entry->data.enumeration.tag_int_type = tag_type;
2677618732 entry->data.enumeration.decls_scope = create_decls_scope(
......@@ -26852,7 +18808,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
2685218808
2685318809 ZigType *entry = new_type_table_entry(ZigTypeIdUnion);
2685418810 buf_init_from_buf(&entry->name,
26855 get_anon_type_name(ira->codegen, ira->old_irb.exec, "union", source_instr->scope, source_instr->source_node, &entry->name));
18811 get_anon_type_name(ira->codegen, ira->zir, "union", source_instr->scope, source_instr->source_node, &entry->name));
2685618812 entry->data.unionation.decl_node = source_instr->source_node;
2685718813 entry->data.unionation.fields = heap::c_allocator.allocate<TypeUnionField>(fields_len);
2685818814 entry->data.unionation.fields_by_name.init(fields_len);
......@@ -27022,8 +18978,8 @@ static IrInstGen *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira,
2702218978 if (!ir_resolve_unsigned(ira, instruction->new_quota->child, ira->codegen->builtin_types.entry_u32, &new_quota))
2702318979 return ira->codegen->invalid_inst_gen;
2702418980
27025 if (new_quota > *ira->new_irb.exec->backward_branch_quota) {
27026 *ira->new_irb.exec->backward_branch_quota = new_quota;
18981 if (new_quota > *ira->backward_branch_quota) {
18982 *ira->backward_branch_quota = new_quota;
2702718983 }
2702818984
2702918985 return ir_const_void(ira, &instruction->base.base);
......@@ -27057,7 +19013,7 @@ static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImpo
2705719013 ZigValue *result_ptr;
2705819014 create_result_ptr(ira->codegen, void_type, &cimport_result, &result_ptr);
2705919015 if ((err = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, result_ptr,
27060 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr,
19016 ira->backward_branch_count, ira->backward_branch_quota, nullptr,
2706119017 &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, UndefBad)))
2706219018 {
2706319019 return ira->codegen->invalid_inst_gen;
......@@ -27066,8 +19022,10 @@ static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImpo
2706619022 return ira->codegen->invalid_inst_gen;
2706719023
2706819024 ZigPackage *cur_scope_pkg = scope_package(instruction->base.base.scope);
27069 Buf *namespace_name = buf_sprintf("%s.cimport:%" ZIG_PRI_usize ":%" ZIG_PRI_usize,
27070 buf_ptr(&cur_scope_pkg->pkg_path), node->line + 1, node->column + 1);
19025 RootStruct *root_struct = node->owner->data.structure.root_struct;
19026 TokenLoc tok_loc = root_struct->token_locs[node->main_token];
19027 Buf *namespace_name = buf_sprintf("%s.cimport:%" PRIu32 ":%" PRIu32,
19028 buf_ptr(&cur_scope_pkg->pkg_path), tok_loc.line + 1, tok_loc.column + 1);
2707119029
2707219030 ZigPackage *cimport_pkg = new_anonymous_package();
2707319031 cimport_pkg->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package);
......@@ -27095,12 +19053,14 @@ static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImpo
2709519053 }
2709619054 for (size_t i = 0; i < errors_len; i += 1) {
2709719055 Stage2ErrorMsg *clang_err = &errors_ptr[i];
27098 // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null
19056 // Clang can emit "too many errors, stopping now", in which case
19057 // `source` and `filename_ptr` are null
2709919058 if (clang_err->source && clang_err->filename_ptr) {
2710019059 ErrorMsg *err_msg = err_msg_create_with_offset(
2710119060 clang_err->filename_ptr ?
27102 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),
27103 clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
19061 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) :
19062 buf_alloc(),
19063 clang_err->offset, clang_err->source,
2710419064 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
2710519065 err_msg_add_note(parent_err_msg, err_msg);
2710619066 }
......@@ -27225,7 +19185,7 @@ static IrInstGen *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstSrcEmb
2722519185 }
2722619186
2722719187 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
27228 init_const_str_lit(ira->codegen, result->value, file_contents);
19188 init_const_str_lit(ira->codegen, result->value, file_contents, true);
2722919189 return result;
2723019190}
2723119191
......@@ -29108,7 +21068,7 @@ static IrInstGen *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstSrc
2910821068}
2910921069
2911021070static IrInstGen *ir_analyze_instruction_frame_handle(IrAnalyze *ira, IrInstSrcFrameHandle *instruction) {
29111 ZigFn *fn = ira->new_irb.exec->fn_entry;
21071 ZigFn *fn = ira->fn;
2911221072 ir_assert(fn != nullptr, &instruction->base.base);
2911321073
2911421074 if (fn->inferred_async_node == nullptr) {
......@@ -30043,7 +22003,7 @@ static IrInstGen *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstSrcPanic *i
3004322003 if (type_is_invalid(msg->value->type))
3004422004 return ir_unreach_error(ira);
3004522005
30046 if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope)) {
22006 if (ir_should_inline(ira->zir, instruction->base.base.scope)) {
3004722007 ir_add_error(ira, &instruction->base.base, buf_sprintf("encountered @panic at compile-time"));
3004822008 return ir_unreach_error(ira);
3004922009 }
......@@ -30971,7 +22931,7 @@ static IrInstGen *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstS
3097122931 return ira->codegen->invalid_inst_gen;
3097222932 }
3097322933
30974 ZigFn *fn_entry = ira->new_irb.exec->fn_entry;
22934 ZigFn *fn_entry = ira->fn;
3097522935 if (fn_entry == nullptr) {
3097622936 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack outside function"));
3097722937 return ira->codegen->invalid_inst_gen;
......@@ -31851,6 +23811,22 @@ static IrInstGen *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstSrcHasDe
3185123811 return ir_const_bool(ira, &instruction->base.base, true);
3185223812}
3185323813
23814static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode *node, Buf *var_name) {
23815 ScopeDecls *scope_decls = nullptr;
23816 while (scope != nullptr) {
23817 if (scope->id == ScopeIdDecls) {
23818 scope_decls = reinterpret_cast<ScopeDecls *>(scope);
23819 }
23820 scope = scope->parent;
23821 }
23822 TldVar *tld_var = heap::c_allocator.create<TldVar>();
23823 init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base);
23824 tld_var->base.resolution = TldResolutionInvalid;
23825 tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false,
23826 g->invalid_inst_gen->value, &tld_var->base, g->builtin_types.entry_invalid);
23827 scope_decls->decl_table.put(var_name, &tld_var->base);
23828}
23829
3185423830static IrInstGen *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, IrInstSrcUndeclaredIdent *instruction) {
3185523831 // put a variable of same name with invalid type in global scope
3185623832 // so that future references to this same name will find a variable with an invalid type
......@@ -31975,7 +23951,7 @@ static IrInstGen *ir_analyze_instruction_suspend_finish(IrAnalyze *ira, IrInstSr
3197523951 ir_assert(begin_base->id == IrInstGenIdSuspendBegin, &instruction->base.base);
3197623952 IrInstGenSuspendBegin *begin = reinterpret_cast<IrInstGenSuspendBegin *>(begin_base);
3197723953
31978 ZigFn *fn_entry = ira->new_irb.exec->fn_entry;
23954 ZigFn *fn_entry = ira->fn;
3197923955 ir_assert(fn_entry != nullptr, &instruction->base.base);
3198023956
3198123957 if (fn_entry->inferred_async_node == nullptr) {
......@@ -32042,7 +24018,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
3204224018
3204324019 ZigType *result_type = frame->value->type->data.any_frame.result_type;
3204424020
32045 ZigFn *fn_entry = ira->new_irb.exec->fn_entry;
24021 ZigFn *fn_entry = ira->fn;
3204624022 ir_assert(fn_entry != nullptr, &instruction->base.base);
3204724023
3204824024 // If it's not @Frame(func) then it's definitely a suspend point
......@@ -32100,7 +24076,7 @@ static IrInstGen *ir_analyze_instruction_resume(IrAnalyze *ira, IrInstSrcResume
3210024076}
3210124077
3210224078static IrInstGen *ir_analyze_instruction_spill_begin(IrAnalyze *ira, IrInstSrcSpillBegin *instruction) {
32103 if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope))
24079 if (ir_should_inline(ira->zir, instruction->base.base.scope))
3210424080 return ir_const_void(ira, &instruction->base.base);
3210524081
3210624082 IrInstGen *operand = instruction->operand->child;
......@@ -32126,7 +24102,7 @@ static IrInstGen *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstSrcSpil
3212624102 if (type_is_invalid(operand->value->type))
3212724103 return ira->codegen->invalid_inst_gen;
3212824104
32129 if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope) ||
24105 if (ir_should_inline(ira->zir, instruction->base.base.scope) ||
3213024106 !type_has_bits(ira->codegen, operand->value->type) ||
3213124107 instr_is_comptime(operand))
3213224108 {
......@@ -32169,7 +24145,8 @@ static IrInstGen *ir_analyze_instruction_src(IrAnalyze *ira, IrInstSrcSrc *instr
3216924145 fields[0]->special = ConstValSpecialStatic;
3217024146
3217124147 ZigType *import = instruction->base.base.source_node->owner;
32172 Buf *path = import->data.structure.root_struct->path;
24148 RootStruct *root_struct = import->data.structure.root_struct;
24149 Buf *path = root_struct->path;
3217324150 ZigValue *file_name = create_const_str_lit(ira->codegen, path)->data.x_ptr.data.ref.pointee;
3217424151 init_const_slice(ira->codegen, fields[0], file_name, 0, buf_len(path), true);
3217524152 fields[0]->type = u8_slice;
......@@ -32182,17 +24159,20 @@ static IrInstGen *ir_analyze_instruction_src(IrAnalyze *ira, IrInstSrcSrc *instr
3218224159 init_const_slice(ira->codegen, fields[1], fn_name, 0, buf_len(&fn_entry->symbol_name), true);
3218324160 fields[1]->type = u8_slice;
3218424161
24162
24163 TokenLoc tok_loc = root_struct->token_locs[instruction->base.base.source_node->main_token];
24164
3218524165 // line: u32
3218624166 ensure_field_index(source_location_type, "line", 2);
3218724167 fields[2]->special = ConstValSpecialStatic;
3218824168 fields[2]->type = ira->codegen->builtin_types.entry_u32;
32189 bigint_init_unsigned(&fields[2]->data.x_bigint, instruction->base.base.source_node->line + 1);
24169 bigint_init_unsigned(&fields[2]->data.x_bigint, tok_loc.line + 1);
3219024170
3219124171 // column: u32
3219224172 ensure_field_index(source_location_type, "column", 3);
3219324173 fields[3]->special = ConstValSpecialStatic;
3219424174 fields[3]->type = ira->codegen->builtin_types.entry_u32;
32195 bigint_init_unsigned(&fields[3]->data.x_bigint, instruction->base.base.source_node->column + 1);
24175 bigint_init_unsigned(&fields[3]->data.x_bigint, tok_loc.column + 1);
3219624176
3219724177 return ir_const_move(ira, &instruction->base.base, result);
3219824178}
......@@ -32484,29 +24464,31 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc
3248424464 zig_unreachable();
3248524465}
3248624466
32487// This function attempts to evaluate IR code while doing type checking and other analysis.
32488// It emits to a new IrExecutableGen which is partially evaluated IR code.
32489ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen *new_exec,
32490 ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *result_ptr)
24467// This function attempts to evaluate stage1 ZIR code while doing type checking and other analysis.
24468// It emits to a new Stage1Air which is partially evaluated IR code.
24469ZigType *ir_analyze(CodeGen *codegen, Stage1Zir *stage1_zir, Stage1Air *stage1_air,
24470 size_t *backward_branch_count, size_t *backward_branch_quota,
24471 ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *result_ptr, ZigFn *fn)
3249124472{
32492 assert(old_exec->first_err_trace_msg == nullptr);
24473 assert(stage1_zir->first_err_trace_msg == nullptr);
3249324474 assert(expected_type == nullptr || !type_is_invalid(expected_type));
3249424475
3249524476 IrAnalyze *ira = heap::c_allocator.create<IrAnalyze>();
24477 ira->fn = fn;
24478 ira->backward_branch_count = backward_branch_count;
24479 ira->backward_branch_quota = backward_branch_quota;
3249624480 ira->ref_count = 1;
32497 old_exec->analysis = ira;
3249824481 ira->codegen = codegen;
3249924482
3250024483 ira->explicit_return_type = expected_type;
3250124484 ira->explicit_return_type_source_node = expected_type_source_node;
3250224485
32503 ira->old_irb.codegen = codegen;
32504 ira->old_irb.exec = old_exec;
24486 ira->zir = stage1_zir;
3250524487
3250624488 ira->new_irb.codegen = codegen;
32507 ira->new_irb.exec = new_exec;
24489 ira->new_irb.exec = stage1_air;
3250824490
32509 IrBasicBlockSrc *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0);
24491 Stage1ZirBasicBlock *old_entry_bb = ira->zir->basic_block_list.at(0);
3251024492 IrBasicBlockGen *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr);
3251124493 ira->new_irb.current_basic_block = new_entry_bb;
3251224494 ira->old_bb_index = 0;
......@@ -32516,18 +24498,18 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen
3251624498 if (result_ptr != nullptr) {
3251724499 assert(result_ptr->type->id == ZigTypeIdPointer);
3251824500 IrInstGenConst *const_inst = ir_create_inst_noval<IrInstGenConst>(
32519 &ira->new_irb, new_exec->begin_scope, new_exec->source_node);
24501 &ira->new_irb, stage1_air->begin_scope, stage1_air->source_node);
3252024502 const_inst->base.value = result_ptr;
3252124503 ira->return_ptr = &const_inst->base;
3252224504 } else {
32523 assert(new_exec->begin_scope != nullptr);
32524 assert(new_exec->source_node != nullptr);
32525 ira->return_ptr = ir_build_return_ptr(ira, new_exec->begin_scope, new_exec->source_node,
24505 assert(stage1_air->begin_scope != nullptr);
24506 assert(stage1_air->source_node != nullptr);
24507 ira->return_ptr = ir_build_return_ptr(ira, stage1_air->begin_scope, stage1_air->source_node,
3252624508 get_pointer_to_type(codegen, expected_type, false));
3252724509 }
3252824510
32529 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) {
32530 IrInstSrc *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);
24511 while (ira->old_bb_index < ira->zir->basic_block_list.length) {
24512 IrInstSrc *old_instruction = ira->zir_current_basic_block->instruction_list.at(ira->instruction_index);
3253124513
3253224514 if (old_instruction->base.ref_count == 0 && !ir_inst_src_has_side_effects(old_instruction)) {
3253324515 ira->instruction_index += 1;
......@@ -32539,20 +24521,6 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen
3253924521 old_instruction->src();
3254024522 fprintf(stderr, "~ ");
3254124523 ir_print_inst_src(codegen, stderr, old_instruction, 0);
32542 bool want_break = false;
32543 if (ira->break_debug_id == old_instruction->base.debug_id) {
32544 want_break = true;
32545 } else if (old_instruction->base.source_node != nullptr) {
32546 for (size_t i = 0; i < dbg_ir_breakpoints_count; i += 1) {
32547 if (dbg_ir_breakpoints_buf[i].line == old_instruction->base.source_node->line + 1 &&
32548 buf_ends_with_str(old_instruction->base.source_node->owner->data.structure.root_struct->path,
32549 dbg_ir_breakpoints_buf[i].src_file))
32550 {
32551 want_break = true;
32552 }
32553 }
32554 }
32555 if (want_break) BREAKPOINT;
3255624524 }
3255724525 IrInstGen *new_instruction = ir_analyze_instruction_base(ira, old_instruction);
3255824526 if (new_instruction != nullptr) {
......@@ -32564,16 +24532,16 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen
3256424532 fprintf(stderr, "-> (invalid)");
3256524533 }
3256624534
32567 if (new_exec->first_err_trace_msg != nullptr) {
32568 ira->codegen->trace_err = new_exec->first_err_trace_msg;
24535 if (stage1_air->first_err_trace_msg != nullptr) {
24536 ira->codegen->trace_err = stage1_air->first_err_trace_msg;
3256924537 } else {
32570 new_exec->first_err_trace_msg = ira->codegen->trace_err;
24538 stage1_air->first_err_trace_msg = ira->codegen->trace_err;
3257124539 }
32572 if (new_exec->first_err_trace_msg != nullptr &&
24540 if (stage1_air->first_err_trace_msg != nullptr &&
3257324541 !old_instruction->base.source_node->already_traced_this_node)
3257424542 {
3257524543 old_instruction->base.source_node->already_traced_this_node = true;
32576 new_exec->first_err_trace_msg = add_error_note(ira->codegen, new_exec->first_err_trace_msg,
24544 stage1_air->first_err_trace_msg = add_error_note(ira->codegen, stage1_air->first_err_trace_msg,
3257724545 old_instruction->base.source_node, buf_create_from_str("referenced here"));
3257824546 }
3257924547 return ira->codegen->builtin_types.entry_invalid;
......@@ -32599,14 +24567,14 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen
3259924567 }
3260024568
3260124569 ZigType *res_type;
32602 if (new_exec->first_err_trace_msg != nullptr) {
32603 codegen->trace_err = new_exec->first_err_trace_msg;
32604 if (codegen->trace_err != nullptr && new_exec->source_node != nullptr &&
32605 !new_exec->source_node->already_traced_this_node)
24570 if (stage1_air->first_err_trace_msg != nullptr) {
24571 codegen->trace_err = stage1_air->first_err_trace_msg;
24572 if (codegen->trace_err != nullptr && stage1_air->source_node != nullptr &&
24573 !stage1_air->source_node->already_traced_this_node)
3260624574 {
32607 new_exec->source_node->already_traced_this_node = true;
24575 stage1_air->source_node->already_traced_this_node = true;
3260824576 codegen->trace_err = add_error_note(codegen, codegen->trace_err,
32609 new_exec->source_node, buf_create_from_str("referenced here"));
24577 stage1_air->source_node, buf_create_from_str("referenced here"));
3261024578 }
3261124579 res_type = ira->codegen->builtin_types.entry_invalid;
3261224580 } else if (ira->src_implicit_return_type_list.length == 0) {
......@@ -33541,11 +25509,3 @@ void IrAnalyze::dump() {
3354125509 ir_print_basic_block_gen(this->codegen, stderr, this->new_irb.current_basic_block, 1);
3354225510 }
3354325511}
33544
33545void dbg_ir_break(const char *src_file, uint32_t line) {
33546 dbg_ir_breakpoints_buf[dbg_ir_breakpoints_count] = {src_file, line};
33547 dbg_ir_breakpoints_count += 1;
33548}
33549void dbg_ir_clear(void) {
33550 dbg_ir_breakpoints_count = 0;
33551}
src/stage1/ir.hpp+5-11
......@@ -10,31 +10,25 @@
1010
1111#include "all_types.hpp"
1212
13bool ir_gen(CodeGen *g, AstNode *node, Scope *scope, IrExecutableSrc *ir_executable);
14bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry);
15
1613IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn,
1714 ZigType *var_type, const char *name_hint);
1815
1916Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
2017 ZigValue *return_ptr, size_t *backward_branch_count, size_t *backward_branch_quota,
2118 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
22 IrExecutableGen *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef);
19 Stage1Air *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef);
2320
2421Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val);
2522
26ZigType *ir_analyze(CodeGen *g, IrExecutableSrc *old_executable, IrExecutableGen *new_executable,
27 ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *return_ptr);
23ZigType *ir_analyze(CodeGen *codegen, Stage1Zir *stage1_zir, Stage1Air *stage1_air,
24 size_t *backward_branch_count, size_t *backward_branch_quota,
25 ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *result_ptr,
26 ZigFn *fn);
2827
2928bool ir_inst_gen_has_side_effects(IrInstGen *inst);
30bool ir_inst_src_has_side_effects(IrInstSrc *inst);
3129
3230struct IrAnalyze;
3331ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val,
3432 AstNode *source_node);
3533
36// for debugging purposes
37void dbg_ir_break(const char *src_file, uint32_t line);
38void dbg_ir_clear(void);
39
4034#endif
src/stage1/ir_print.cpp+7-6
......@@ -8,6 +8,7 @@
88#include "all_types.hpp"
99#include "analyze.hpp"
1010#include "ir.hpp"
11#include "astgen.hpp"
1112#include "ir_print.hpp"
1213#include "os.hpp"
1314
......@@ -632,7 +633,7 @@ static void ir_print_other_inst_gen(IrPrintGen *irp, IrInstGen *inst) {
632633 }
633634}
634635
635static void ir_print_other_block(IrPrintSrc *irp, IrBasicBlockSrc *bb) {
636static void ir_print_other_block(IrPrintSrc *irp, Stage1ZirBasicBlock *bb) {
636637 if (bb == nullptr) {
637638 fprintf(irp->f, "(null block)");
638639 } else {
......@@ -1005,7 +1006,7 @@ static void ir_print_phi(IrPrintSrc *irp, IrInstSrcPhi *phi_instruction) {
10051006 assert(phi_instruction->incoming_count != 0);
10061007 assert(phi_instruction->incoming_count != SIZE_MAX);
10071008 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {
1008 IrBasicBlockSrc *incoming_block = phi_instruction->incoming_blocks[i];
1009 Stage1ZirBasicBlock *incoming_block = phi_instruction->incoming_blocks[i];
10091010 IrInstSrc *incoming_value = phi_instruction->incoming_values[i];
10101011 if (i != 0)
10111012 fprintf(irp->f, " ");
......@@ -3349,7 +3350,7 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai
33493350 fprintf(irp->f, "\n");
33503351}
33513352
3352static void irp_print_basic_block_src(IrPrintSrc *irp, IrBasicBlockSrc *current_block) {
3353static void irp_print_basic_block_src(IrPrintSrc *irp, Stage1ZirBasicBlock *current_block) {
33533354 fprintf(irp->f, "%s_%" PRIu32 ":\n", current_block->name_hint, current_block->debug_id);
33543355 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
33553356 IrInstSrc *instruction = current_block->instruction_list.at(instr_i);
......@@ -3369,7 +3370,7 @@ static void irp_print_basic_block_gen(IrPrintGen *irp, IrBasicBlockGen *current_
33693370 }
33703371}
33713372
3372void ir_print_basic_block_src(CodeGen *codegen, FILE *f, IrBasicBlockSrc *bb, int indent_size) {
3373void ir_print_basic_block_src(CodeGen *codegen, FILE *f, Stage1ZirBasicBlock *bb, int indent_size) {
33733374 IrPrintSrc ir_print = {};
33743375 ir_print.codegen = codegen;
33753376 ir_print.f = f;
......@@ -3395,7 +3396,7 @@ void ir_print_basic_block_gen(CodeGen *codegen, FILE *f, IrBasicBlockGen *bb, in
33953396 ir_print.printed.deinit();
33963397}
33973398
3398void ir_print_src(CodeGen *codegen, FILE *f, IrExecutableSrc *executable, int indent_size) {
3399void ir_print_src(CodeGen *codegen, FILE *f, Stage1Zir *executable, int indent_size) {
33993400 IrPrintSrc ir_print = {};
34003401 IrPrintSrc *irp = &ir_print;
34013402 irp->codegen = codegen;
......@@ -3408,7 +3409,7 @@ void ir_print_src(CodeGen *codegen, FILE *f, IrExecutableSrc *executable, int in
34083409 }
34093410}
34103411
3411void ir_print_gen(CodeGen *codegen, FILE *f, IrExecutableGen *executable, int indent_size) {
3412void ir_print_gen(CodeGen *codegen, FILE *f, Stage1Air *executable, int indent_size) {
34123413 IrPrintGen ir_print = {};
34133414 IrPrintGen *irp = &ir_print;
34143415 irp->codegen = codegen;
src/stage1/ir_print.hpp+3-3
......@@ -12,11 +12,11 @@
1212
1313#include <stdio.h>
1414
15void ir_print_src(CodeGen *codegen, FILE *f, IrExecutableSrc *executable, int indent_size);
16void ir_print_gen(CodeGen *codegen, FILE *f, IrExecutableGen *executable, int indent_size);
15void ir_print_src(CodeGen *codegen, FILE *f, Stage1Zir *executable, int indent_size);
16void ir_print_gen(CodeGen *codegen, FILE *f, Stage1Air *executable, int indent_size);
1717void ir_print_inst_src(CodeGen *codegen, FILE *f, IrInstSrc *inst, int indent_size);
1818void ir_print_inst_gen(CodeGen *codegen, FILE *f, IrInstGen *inst, int indent_size);
19void ir_print_basic_block_src(CodeGen *codegen, FILE *f, IrBasicBlockSrc *bb, int indent_size);
19void ir_print_basic_block_src(CodeGen *codegen, FILE *f, Stage1ZirBasicBlock *bb, int indent_size);
2020void ir_print_basic_block_gen(CodeGen *codegen, FILE *f, IrBasicBlockGen *bb, int indent_size);
2121
2222const char* ir_inst_src_type_str(IrInstSrcId id);
src/stage1/parser.cpp+921-593
......@@ -16,28 +16,34 @@
1616
1717struct ParseContext {
1818 Buf *buf;
19 size_t current_token;
20 ZigList<Token> *tokens;
19 // Shortcut to `owner->data.structure.root_struct->token_ids`.
20 TokenId *token_ids;
21 // Shortcut to `owner->data.structure.root_struct->token_locs`.
22 TokenLoc *token_locs;
2123 ZigType *owner;
24 TokenIndex current_token;
2225 ErrColor err_color;
26 // Shortcut to `owner->data.structure.root_struct->token_count`.
27 uint32_t token_count;
2328};
2429
2530struct PtrPayload {
26 Token *asterisk;
27 Token *payload;
31 TokenIndex asterisk;
32 TokenIndex payload;
2833};
2934
3035struct PtrIndexPayload {
31 Token *asterisk;
32 Token *payload;
33 Token *index;
36 TokenIndex asterisk;
37 TokenIndex payload;
38 TokenIndex index;
3439};
3540
3641static AstNode *ast_parse_root(ParseContext *pc);
3742static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc);
3843static AstNode *ast_parse_test_decl(ParseContext *pc);
3944static AstNode *ast_parse_top_level_comptime(ParseContext *pc);
40static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, Buf *doc_comments);
45static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod,
46 TokenIndex doc_comments);
4147static AstNode *ast_parse_fn_proto(ParseContext *pc);
4248static AstNode *ast_parse_var_decl(ParseContext *pc);
4349static AstNode *ast_parse_container_field(ParseContext *pc);
......@@ -87,8 +93,8 @@ static AsmOutput *ast_parse_asm_output_item(ParseContext *pc);
8793static AstNode *ast_parse_asm_input(ParseContext *pc);
8894static AsmInput *ast_parse_asm_input_item(ParseContext *pc);
8995static AstNode *ast_parse_asm_clobbers(ParseContext *pc);
90static Token *ast_parse_break_label(ParseContext *pc);
91static Token *ast_parse_block_label(ParseContext *pc);
96static TokenIndex ast_parse_break_label(ParseContext *pc);
97static TokenIndex ast_parse_block_label(ParseContext *pc);
9298static AstNode *ast_parse_field_init(ParseContext *pc);
9399static AstNode *ast_parse_while_continue_expr(ParseContext *pc);
94100static AstNode *ast_parse_link_section(ParseContext *pc);
......@@ -98,7 +104,7 @@ static AstNode *ast_parse_param_type(ParseContext *pc);
98104static AstNode *ast_parse_if_prefix(ParseContext *pc);
99105static AstNode *ast_parse_while_prefix(ParseContext *pc);
100106static AstNode *ast_parse_for_prefix(ParseContext *pc);
101static Token *ast_parse_payload(ParseContext *pc);
107static TokenIndex ast_parse_payload(ParseContext *pc);
102108static Optional<PtrPayload> ast_parse_ptr_payload(ParseContext *pc);
103109static Optional<PtrIndexPayload> ast_parse_ptr_index_payload(ParseContext *pc);
104110static AstNode *ast_parse_switch_prong(ParseContext *pc);
......@@ -120,29 +126,34 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc);
120126static AstNode *ast_parse_container_decl_type(ParseContext *pc);
121127static AstNode *ast_parse_byte_align(ParseContext *pc);
122128
129ATTRIBUTE_NORETURN
130static void ast_error_offset(RootStruct *root_struct, ErrColor err_color,
131 TokenIndex token, size_t bad_index, Buf *msg)
132{
133 assert(token < root_struct->token_count);
134 uint32_t byte_offset = root_struct->token_locs[token].offset;
135 ErrorMsg *err = err_msg_create_with_offset(root_struct->path,
136 byte_offset + bad_index, buf_ptr(root_struct->source_code), msg);
137
138 print_err_msg(err, err_color);
139 exit(EXIT_FAILURE);
140}
141
123142ATTRIBUTE_PRINTF(3, 4)
124143ATTRIBUTE_NORETURN
125static void ast_error(ParseContext *pc, Token *token, const char *format, ...) {
144static void ast_error(ParseContext *pc, TokenIndex token, const char *format, ...) {
126145 va_list ap;
127146 va_start(ap, format);
128147 Buf *msg = buf_vprintf(format, ap);
129148 va_end(ap);
130149
131
132 ErrorMsg *err = err_msg_create_with_line(pc->owner->data.structure.root_struct->path,
133 token->start_line, token->start_column,
134 pc->owner->data.structure.root_struct->source_code,
135 pc->owner->data.structure.root_struct->line_offsets, msg);
136 err->line_start = token->start_line;
137 err->column_start = token->start_column;
138
139 print_err_msg(err, pc->err_color);
140 exit(EXIT_FAILURE);
150 RootStruct *root_struct = pc->owner->data.structure.root_struct;
151 ast_error_offset(root_struct, pc->err_color, token, 0, msg);
141152}
142153
143154ATTRIBUTE_NORETURN
144static void ast_invalid_token_error(ParseContext *pc, Token *token) {
145 ast_error(pc, token, "invalid token: '%s'", token_name(token->id));
155static void ast_invalid_token_error(ParseContext *pc, TokenIndex token) {
156 ast_error(pc, token, "invalid token: '%s'", token_name(pc->token_ids[token]));
146157}
147158
148159static AstNode *ast_create_node_no_line_info(ParseContext *pc, NodeType type) {
......@@ -152,48 +163,44 @@ static AstNode *ast_create_node_no_line_info(ParseContext *pc, NodeType type) {
152163 return node;
153164}
154165
155static AstNode *ast_create_node(ParseContext *pc, NodeType type, Token *first_token) {
166static AstNode *ast_create_node(ParseContext *pc, NodeType type, TokenIndex first_token) {
156167 assert(first_token);
157168 AstNode *node = ast_create_node_no_line_info(pc, type);
158 node->line = first_token->start_line;
159 node->column = first_token->start_column;
169 node->main_token = first_token;
160170 return node;
161171}
162172
163173static AstNode *ast_create_node_copy_line_info(ParseContext *pc, NodeType type, AstNode *from) {
164174 assert(from);
165175 AstNode *node = ast_create_node_no_line_info(pc, type);
166 node->line = from->line;
167 node->column = from->column;
176 node->main_token = from->main_token;
168177 return node;
169178}
170179
171static Token *peek_token_i(ParseContext *pc, size_t i) {
172 return &pc->tokens->at(pc->current_token + i);
173}
174
175static Token *peek_token(ParseContext *pc) {
176 return peek_token_i(pc, 0);
180static TokenIndex peek_token(ParseContext *pc) {
181 return pc->current_token;
177182}
178183
179static Token *eat_token(ParseContext *pc) {
180 Token *res = peek_token(pc);
184static TokenIndex eat_token(ParseContext *pc) {
185 TokenIndex res = peek_token(pc);
181186 pc->current_token += 1;
182187 return res;
183188}
184189
185static Token *eat_token_if(ParseContext *pc, TokenId id) {
186 Token *res = peek_token(pc);
187 if (res->id == id)
190static TokenIndex eat_token_if(ParseContext *pc, TokenId id) {
191 TokenIndex res = peek_token(pc);
192 if (pc->token_ids[res] == id) {
188193 return eat_token(pc);
194 }
189195
190 return nullptr;
196 return 0;
191197}
192198
193static Token *expect_token(ParseContext *pc, TokenId id) {
194 Token *res = eat_token(pc);
195 if (res->id != id)
196 ast_error(pc, res, "expected token '%s', found '%s'", token_name(id), token_name(res->id));
199static TokenIndex expect_token(ParseContext *pc, TokenId id) {
200 TokenIndex res = eat_token(pc);
201 TokenId actual_id = pc->token_ids[res];
202 if (actual_id != id)
203 ast_error(pc, res, "expected token '%s', found '%s'", token_name(id), token_name(actual_id));
197204
198205 return res;
199206}
......@@ -202,23 +209,34 @@ static void put_back_token(ParseContext *pc) {
202209 pc->current_token -= 1;
203210}
204211
205static Buf *token_buf(Token *token) {
206 if (token == nullptr)
212static Buf *token_buf(ParseContext *pc, TokenIndex token) {
213 Error err;
214
215 if (token == 0)
207216 return nullptr;
208 assert(token->id == TokenIdStringLiteral || token->id == TokenIdMultilineStringLiteral || token->id == TokenIdSymbol);
209 return &token->data.str_lit.str;
210}
211217
212static BigInt *token_bigint(Token *token) {
213 assert(token->id == TokenIdIntLiteral);
214 return &token->data.int_lit.bigint;
218 RootStruct *root_struct = pc->owner->data.structure.root_struct;
219 if (root_struct->token_ids[token] == TokenIdIdentifier) {
220 return token_identifier_buf(root_struct, token);
221 } else if (root_struct->token_ids[token] == TokenIdStringLiteral) {
222 assert(root_struct->token_ids[token] == TokenIdStringLiteral);
223 const char *source = buf_ptr(root_struct->source_code);
224 size_t byte_offset = root_struct->token_locs[token].offset;
225 size_t bad_index;
226 Buf *str = buf_alloc();
227 if ((err = source_string_literal_buf(source + byte_offset, str, &bad_index))) {
228 ast_error_offset(root_struct, pc->err_color, token, bad_index,
229 buf_create_from_str("invalid string literal character"));
230 }
231 return str;
232 } else {
233 zig_unreachable();
234 }
215235}
216236
217static AstNode *token_symbol(ParseContext *pc, Token *token) {
218 assert(token->id == TokenIdSymbol);
219 AstNode *res = ast_create_node(pc, NodeTypeSymbol, token);
220 res->data.symbol_expr.symbol = token_buf(token);
221 return res;
237static AstNode *token_identifier(ParseContext *pc, TokenIndex token) {
238 assert(pc->token_ids[token] == TokenIdIdentifier);
239 return ast_create_node(pc, NodeTypeIdentifier, token);
222240}
223241
224242// (Rule SEP)* Rule?
......@@ -231,7 +249,7 @@ static ZigList<T *> ast_parse_list(ParseContext *pc, TokenId sep, T *(*parser)(P
231249 break;
232250
233251 res.append(curr);
234 if (eat_token_if(pc, sep) == nullptr)
252 if (eat_token_if(pc, sep) == 0)
235253 break;
236254 }
237255
......@@ -355,22 +373,22 @@ static AstNode *ast_parse_if_expr_helper(ParseContext *pc, AstNode *(*body_parse
355373 return nullptr;
356374
357375 AstNode *body = ast_expect(pc, body_parser);
358 Token *err_payload = nullptr;
376 TokenIndex err_payload = 0;
359377 AstNode *else_body = nullptr;
360 if (eat_token_if(pc, TokenIdKeywordElse) != nullptr) {
378 if (eat_token_if(pc, TokenIdKeywordElse) != 0) {
361379 err_payload = ast_parse_payload(pc);
362380 else_body = ast_expect(pc, body_parser);
363381 }
364382
365383 assert(res->type == NodeTypeIfOptional);
366 if (err_payload != nullptr) {
384 if (err_payload != 0) {
367385 AstNodeTestExpr old = res->data.test_expr;
368386 res->type = NodeTypeIfErrorExpr;
369387 res->data.if_err_expr.target_node = old.target_node;
370388 res->data.if_err_expr.var_is_ptr = old.var_is_ptr;
371389 res->data.if_err_expr.var_symbol = old.var_symbol;
372390 res->data.if_err_expr.then_node = body;
373 res->data.if_err_expr.err_symbol = token_buf(err_payload);
391 res->data.if_err_expr.err_symbol = token_buf(pc, err_payload);
374392 res->data.if_err_expr.else_node = else_body;
375393 return res;
376394 }
......@@ -395,22 +413,22 @@ static AstNode *ast_parse_loop_expr_helper(
395413 AstNode *(*for_parser)(ParseContext *),
396414 AstNode *(*while_parser)(ParseContext *)
397415) {
398 Token *inline_token = eat_token_if(pc, TokenIdKeywordInline);
416 TokenIndex inline_token = eat_token_if(pc, TokenIdKeywordInline);
399417 AstNode *for_expr = for_parser(pc);
400418 if (for_expr != nullptr) {
401419 assert(for_expr->type == NodeTypeForExpr);
402 for_expr->data.for_expr.is_inline = inline_token != nullptr;
420 for_expr->data.for_expr.is_inline = inline_token != 0;
403421 return for_expr;
404422 }
405423
406424 AstNode *while_expr = while_parser(pc);
407425 if (while_expr != nullptr) {
408426 assert(while_expr->type == NodeTypeWhileExpr);
409 while_expr->data.while_expr.is_inline = inline_token != nullptr;
427 while_expr->data.while_expr.is_inline = inline_token != 0;
410428 return while_expr;
411429 }
412430
413 if (inline_token != nullptr)
431 if (inline_token != 0)
414432 ast_invalid_token_error(pc, peek_token(pc));
415433 return nullptr;
416434}
......@@ -423,7 +441,7 @@ static AstNode *ast_parse_for_expr_helper(ParseContext *pc, AstNode *(*body_pars
423441
424442 AstNode *body = ast_expect(pc, body_parser);
425443 AstNode *else_body = nullptr;
426 if (eat_token_if(pc, TokenIdKeywordElse) != nullptr)
444 if (eat_token_if(pc, TokenIdKeywordElse) != 0)
427445 else_body = ast_expect(pc, body_parser);
428446
429447 assert(res->type == NodeTypeForExpr);
......@@ -439,24 +457,24 @@ static AstNode *ast_parse_while_expr_helper(ParseContext *pc, AstNode *(*body_pa
439457 return nullptr;
440458
441459 AstNode *body = ast_expect(pc, body_parser);
442 Token *err_payload = nullptr;
460 TokenIndex err_payload = 0;
443461 AstNode *else_body = nullptr;
444 if (eat_token_if(pc, TokenIdKeywordElse) != nullptr) {
462 if (eat_token_if(pc, TokenIdKeywordElse) != 0) {
445463 err_payload = ast_parse_payload(pc);
446464 else_body = ast_expect(pc, body_parser);
447465 }
448466
449467 assert(res->type == NodeTypeWhileExpr);
450468 res->data.while_expr.body = body;
451 res->data.while_expr.err_symbol = token_buf(err_payload);
469 res->data.while_expr.err_symbol = token_buf(pc, err_payload);
452470 res->data.while_expr.else_node = else_body;
453471 return res;
454472}
455473
456474template<TokenId id, BinOpType op>
457475AstNode *ast_parse_bin_op_simple(ParseContext *pc) {
458 Token *op_token = eat_token_if(pc, id);
459 if (op_token == nullptr)
476 TokenIndex op_token = eat_token_if(pc, id);
477 if (op_token == 0)
460478 return nullptr;
461479
462480 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
......@@ -464,20 +482,25 @@ AstNode *ast_parse_bin_op_simple(ParseContext *pc) {
464482 return res;
465483}
466484
467AstNode *ast_parse(Buf *buf, ZigList<Token> *tokens, ZigType *owner, ErrColor err_color) {
485AstNode *ast_parse(Buf *buf, ZigType *owner, ErrColor err_color) {
486 RootStruct *root_struct = owner->data.structure.root_struct;
487
468488 ParseContext pc = {};
469489 pc.err_color = err_color;
470490 pc.owner = owner;
471491 pc.buf = buf;
472 pc.tokens = tokens;
492 pc.token_ids = root_struct->token_ids;
493 pc.token_locs = root_struct->token_locs;
494 pc.token_count = root_struct->token_count;
495 pc.current_token = 1; // Skip over the first (invalid) token.
473496 return ast_parse_root(&pc);
474497}
475498
476499// Root <- skip ContainerMembers eof
477500static AstNode *ast_parse_root(ParseContext *pc) {
478 Token *first = peek_token(pc);
501 TokenIndex first = peek_token(pc);
479502 AstNodeContainerDecl members = ast_parse_container_members(pc);
480 if (pc->current_token != pc->tokens->length - 1)
503 if (pc->current_token != pc->token_count - 1)
481504 ast_invalid_token_error(pc, peek_token(pc));
482505
483506 AstNode *node = ast_create_node(pc, NodeTypeContainerDecl, first);
......@@ -486,70 +509,26 @@ static AstNode *ast_parse_root(ParseContext *pc) {
486509 node->data.container_decl.layout = ContainerLayoutAuto;
487510 node->data.container_decl.kind = ContainerKindStruct;
488511 node->data.container_decl.is_root = true;
489 if (buf_len(&members.doc_comments) != 0) {
490 node->data.container_decl.doc_comments = members.doc_comments;
491 }
512 node->data.container_decl.doc_comments = members.doc_comments;
492513
493514 return node;
494515}
495516
496static Token *ast_parse_multiline_string_literal(ParseContext *pc, Buf *buf) {
497 Token *first_str_token = nullptr;
498 Token *str_token = nullptr;
499 while ((str_token = eat_token_if(pc, TokenIdMultilineStringLiteral))) {
500 if (first_str_token == nullptr) {
501 first_str_token = str_token;
502 }
503 if (buf->list.length == 0) {
504 buf_resize(buf, 0);
505 }
506 buf_append_buf(buf, token_buf(str_token));
507
508 // Ignore inline comments
509 size_t cur_token = pc->current_token;
510 while (eat_token_if(pc, TokenIdDocComment));
511
512 // Lookahead to see if there's another multilne string literal,
513 // if not, we have to revert back to before the doc comment
514 if (peek_token(pc)->id != TokenIdMultilineStringLiteral) {
515 pc->current_token = cur_token;
516 } else {
517 buf_append_char(buf, '\n'); // Add a newline between comments
518 }
517static TokenIndex ast_parse_multi_tok(ParseContext *pc, TokenId token_id) {
518 TokenIndex first_token = eat_token_if(pc, token_id);
519 TokenIndex token = first_token;
520 while (token != 0) {
521 token = eat_token_if(pc, token_id);
519522 }
520 return first_str_token;
523 return first_token;
521524}
522525
523static Token *ast_parse_doc_comments(ParseContext *pc, Buf *buf) {
524 Token *first_doc_token = nullptr;
525 Token *doc_token = nullptr;
526 while ((doc_token = eat_token_if(pc, TokenIdDocComment))) {
527 if (first_doc_token == nullptr) {
528 first_doc_token = doc_token;
529 }
530 if (buf->list.length == 0) {
531 buf_resize(buf, 0);
532 }
533 // chops off '///' but leaves '\n'
534 buf_append_mem(buf, buf_ptr(pc->buf) + doc_token->start_pos + 3,
535 doc_token->end_pos - doc_token->start_pos - 3);
536 }
537 return first_doc_token;
526static TokenIndex ast_parse_doc_comments(ParseContext *pc) {
527 return ast_parse_multi_tok(pc, TokenIdDocComment);
538528}
539529
540static void ast_parse_container_doc_comments(ParseContext *pc, Buf *buf) {
541 if (buf_len(buf) != 0 && peek_token(pc)->id == TokenIdContainerDocComment) {
542 buf_append_char(buf, '\n');
543 }
544 Token *doc_token = nullptr;
545 while ((doc_token = eat_token_if(pc, TokenIdContainerDocComment))) {
546 if (buf->list.length == 0) {
547 buf_resize(buf, 0);
548 }
549 // chops off '//!' but leaves '\n'
550 buf_append_mem(buf, buf_ptr(pc->buf) + doc_token->start_pos + 3,
551 doc_token->end_pos - doc_token->start_pos - 3);
552 }
530static TokenIndex ast_parse_container_doc_comments(ParseContext *pc) {
531 return ast_parse_multi_tok(pc, TokenIdContainerDocComment);
553532}
554533
555534enum ContainerFieldState {
......@@ -570,14 +549,11 @@ enum ContainerFieldState {
570549// /
571550static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
572551 AstNodeContainerDecl res = {};
573 Buf tld_doc_comment_buf = BUF_INIT;
574 buf_resize(&tld_doc_comment_buf, 0);
575552 ContainerFieldState field_state = ContainerFieldStateNone;
576 Token *first_token = nullptr;
553 TokenIndex first_token = 0;
554 res.doc_comments = ast_parse_container_doc_comments(pc);
577555 for (;;) {
578 ast_parse_container_doc_comments(pc, &tld_doc_comment_buf);
579
580 Token *peeked_token = peek_token(pc);
556 TokenIndex peeked_token = peek_token(pc);
581557
582558 AstNode *test_decl = ast_parse_test_decl(pc);
583559 if (test_decl != nullptr) {
......@@ -599,15 +575,14 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
599575 continue;
600576 }
601577
602 Buf doc_comment_buf = BUF_INIT;
603 ast_parse_doc_comments(pc, &doc_comment_buf);
578 TokenIndex first_doc_token = ast_parse_doc_comments(pc);
604579
605580 peeked_token = peek_token(pc);
606581
607 Token *visib_token = eat_token_if(pc, TokenIdKeywordPub);
608 VisibMod visib_mod = visib_token != nullptr ? VisibModPub : VisibModPrivate;
582 TokenIndex visib_token = eat_token_if(pc, TokenIdKeywordPub);
583 VisibMod visib_mod = (visib_token != 0) ? VisibModPub : VisibModPrivate;
609584
610 AstNode *top_level_decl = ast_parse_top_level_decl(pc, visib_mod, &doc_comment_buf);
585 AstNode *top_level_decl = ast_parse_top_level_decl(pc, visib_mod, first_doc_token);
611586 if (top_level_decl != nullptr) {
612587 if (field_state == ContainerFieldStateSeen) {
613588 field_state = ContainerFieldStateEnd;
......@@ -617,11 +592,11 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
617592 continue;
618593 }
619594
620 if (visib_token != nullptr) {
595 if (visib_token != 0) {
621596 ast_error(pc, peek_token(pc), "expected function or variable declaration after pub");
622597 }
623598
624 Token *comptime_token = eat_token_if(pc, TokenIdKeywordCompTime);
599 TokenIndex comptime_token = eat_token_if(pc, TokenIdKeywordCompTime);
625600
626601 AstNode *container_field = ast_parse_container_field(pc);
627602 if (container_field != nullptr) {
......@@ -636,10 +611,10 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
636611 }
637612
638613 assert(container_field->type == NodeTypeStructField);
639 container_field->data.struct_field.doc_comments = doc_comment_buf;
614 container_field->data.struct_field.doc_comments = first_doc_token;
640615 container_field->data.struct_field.comptime_token = comptime_token;
641616 res.fields.append(container_field);
642 if (eat_token_if(pc, TokenIdComma) != nullptr) {
617 if (eat_token_if(pc, TokenIdComma) != 0) {
643618 continue;
644619 } else {
645620 break;
......@@ -648,33 +623,32 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
648623
649624 break;
650625 }
651 res.doc_comments = tld_doc_comment_buf;
652626 return res;
653627}
654628
655629// TestDecl <- KEYWORD_test STRINGLITERALSINGLE Block
656630static AstNode *ast_parse_test_decl(ParseContext *pc) {
657 Token *test = eat_token_if(pc, TokenIdKeywordTest);
658 if (test == nullptr)
631 TokenIndex test = eat_token_if(pc, TokenIdKeywordTest);
632 if (test == 0)
659633 return nullptr;
660634
661 Token *name = eat_token_if(pc, TokenIdStringLiteral);
635 TokenIndex name = eat_token_if(pc, TokenIdStringLiteral);
662636 AstNode *block = ast_expect(pc, ast_parse_block);
663637 AstNode *res = ast_create_node(pc, NodeTypeTestDecl, test);
664 res->data.test_decl.name = name ? token_buf(name) : nullptr;
638 res->data.test_decl.name = name ? token_buf(pc, name) : nullptr;
665639 res->data.test_decl.body = block;
666640 return res;
667641}
668642
669643// TopLevelComptime <- KEYWORD_comptime BlockExpr
670644static AstNode *ast_parse_top_level_comptime(ParseContext *pc) {
671 Token *comptime = eat_token_if(pc, TokenIdKeywordCompTime);
672 if (comptime == nullptr)
645 TokenIndex comptime = eat_token_if(pc, TokenIdKeywordCompTime);
646 if (comptime == 0)
673647 return nullptr;
674648
675649 // 1 token lookahead because it could be a comptime struct field
676 Token *lbrace = peek_token(pc);
677 if (lbrace->id != TokenIdLBrace) {
650 TokenIndex lbrace = peek_token(pc);
651 if (pc->token_ids[lbrace] != TokenIdLBrace) {
678652 put_back_token(pc);
679653 return nullptr;
680654 }
......@@ -689,39 +663,40 @@ static AstNode *ast_parse_top_level_comptime(ParseContext *pc) {
689663// <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block)
690664// / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
691665// / KEYWORD_use Expr SEMICOLON
692static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, Buf *doc_comments) {
693 Token *first = eat_token_if(pc, TokenIdKeywordExport);
694 if (first == nullptr)
666static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod,
667 TokenIndex doc_comments)
668{
669 TokenIndex first = eat_token_if(pc, TokenIdKeywordExport);
670 if (first == 0)
695671 first = eat_token_if(pc, TokenIdKeywordExtern);
696 if (first == nullptr)
672 if (first == 0)
697673 first = eat_token_if(pc, TokenIdKeywordInline);
698 if (first == nullptr)
674 if (first == 0)
699675 first = eat_token_if(pc, TokenIdKeywordNoInline);
700 if (first != nullptr) {
701 Token *lib_name = nullptr;
702 if (first->id == TokenIdKeywordExtern)
676 if (first != 0) {
677 TokenIndex lib_name = 0;
678 if (pc->token_ids[first] == TokenIdKeywordExtern)
703679 lib_name = eat_token_if(pc, TokenIdStringLiteral);
704680
705 if (first->id != TokenIdKeywordNoInline && first->id != TokenIdKeywordInline) {
706 Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
681 if (pc->token_ids[first] != TokenIdKeywordNoInline && pc->token_ids[first] != TokenIdKeywordInline) {
682 TokenIndex thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
707683 AstNode *var_decl = ast_parse_var_decl(pc);
708684 if (var_decl != nullptr) {
709685 assert(var_decl->type == NodeTypeVariableDeclaration);
710 if (first->id == TokenIdKeywordExtern && var_decl->data.variable_declaration.expr != nullptr) {
686 if (pc->token_ids[first] == TokenIdKeywordExtern && var_decl->data.variable_declaration.expr != nullptr) {
711687 ast_error(pc, first, "extern variables have no initializers");
712688 }
713 var_decl->line = first->start_line;
714 var_decl->column = first->start_column;
689 var_decl->main_token = first;
715690 var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw;
716691 var_decl->data.variable_declaration.visib_mod = visib_mod;
717 var_decl->data.variable_declaration.doc_comments = *doc_comments;
718 var_decl->data.variable_declaration.is_extern = first->id == TokenIdKeywordExtern;
719 var_decl->data.variable_declaration.is_export = first->id == TokenIdKeywordExport;
720 var_decl->data.variable_declaration.lib_name = token_buf(lib_name);
692 var_decl->data.variable_declaration.doc_comments = doc_comments;
693 var_decl->data.variable_declaration.is_extern = pc->token_ids[first] == TokenIdKeywordExtern;
694 var_decl->data.variable_declaration.is_export = pc->token_ids[first] == TokenIdKeywordExport;
695 var_decl->data.variable_declaration.lib_name = token_buf(pc, lib_name);
721696 return var_decl;
722697 }
723698
724 if (thread_local_kw != nullptr)
699 if (thread_local_kw != 0)
725700 put_back_token(pc);
726701 }
727702
......@@ -732,14 +707,13 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
732707 expect_token(pc, TokenIdSemicolon);
733708
734709 assert(fn_proto->type == NodeTypeFnProto);
735 fn_proto->line = first->start_line;
736 fn_proto->column = first->start_column;
710 fn_proto->main_token = first;
737711 fn_proto->data.fn_proto.visib_mod = visib_mod;
738 fn_proto->data.fn_proto.doc_comments = *doc_comments;
712 fn_proto->data.fn_proto.doc_comments = doc_comments;
739713 if (!fn_proto->data.fn_proto.is_extern)
740 fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern;
741 fn_proto->data.fn_proto.is_export = first->id == TokenIdKeywordExport;
742 switch (first->id) {
714 fn_proto->data.fn_proto.is_extern = pc->token_ids[first] == TokenIdKeywordExtern;
715 fn_proto->data.fn_proto.is_export = pc->token_ids[first] == TokenIdKeywordExport;
716 switch (pc->token_ids[first]) {
743717 case TokenIdKeywordInline:
744718 fn_proto->data.fn_proto.fn_inline = FnInlineAlways;
745719 break;
......@@ -750,7 +724,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
750724 fn_proto->data.fn_proto.fn_inline = FnInlineAuto;
751725 break;
752726 }
753 fn_proto->data.fn_proto.lib_name = token_buf(lib_name);
727 fn_proto->data.fn_proto.lib_name = token_buf(pc, lib_name);
754728
755729 AstNode *res = fn_proto;
756730 if (body != nullptr) {
......@@ -769,17 +743,17 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
769743 ast_invalid_token_error(pc, peek_token(pc));
770744 }
771745
772 Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
746 TokenIndex thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
773747 AstNode *var_decl = ast_parse_var_decl(pc);
774748 if (var_decl != nullptr) {
775749 assert(var_decl->type == NodeTypeVariableDeclaration);
776750 var_decl->data.variable_declaration.visib_mod = visib_mod;
777 var_decl->data.variable_declaration.doc_comments = *doc_comments;
751 var_decl->data.variable_declaration.doc_comments = doc_comments;
778752 var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw;
779753 return var_decl;
780754 }
781755
782 if (thread_local_kw != nullptr)
756 if (thread_local_kw != 0)
783757 put_back_token(pc);
784758
785759 AstNode *fn_proto = ast_parse_fn_proto(pc);
......@@ -790,7 +764,7 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
790764
791765 assert(fn_proto->type == NodeTypeFnProto);
792766 fn_proto->data.fn_proto.visib_mod = visib_mod;
793 fn_proto->data.fn_proto.doc_comments = *doc_comments;
767 fn_proto->data.fn_proto.doc_comments = doc_comments;
794768 AstNode *res = fn_proto;
795769 if (body != nullptr) {
796770 res = ast_create_node_copy_line_info(pc, NodeTypeFnDef, fn_proto);
......@@ -802,8 +776,8 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
802776 return res;
803777 }
804778
805 Token *usingnamespace = eat_token_if(pc, TokenIdKeywordUsingNamespace);
806 if (usingnamespace != nullptr) {
779 TokenIndex usingnamespace = eat_token_if(pc, TokenIdKeywordUsingNamespace);
780 if (usingnamespace != 0) {
807781 AstNode *expr = ast_expect(pc, ast_parse_expr);
808782 expect_token(pc, TokenIdSemicolon);
809783
......@@ -818,12 +792,12 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
818792
819793// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_anytype / TypeExpr)
820794static AstNode *ast_parse_fn_proto(ParseContext *pc) {
821 Token *first = eat_token_if(pc, TokenIdKeywordFn);
822 if (first == nullptr) {
795 TokenIndex first = eat_token_if(pc, TokenIdKeywordFn);
796 if (first == 0) {
823797 return nullptr;
824798 }
825799
826 Token *identifier = eat_token_if(pc, TokenIdSymbol);
800 TokenIndex identifier = eat_token_if(pc, TokenIdIdentifier);
827801 expect_token(pc, TokenIdLParen);
828802 ZigList<AstNode *> params = ast_parse_list(pc, TokenIdComma, ast_parse_param_decl);
829803 expect_token(pc, TokenIdRParen);
......@@ -831,29 +805,29 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
831805 AstNode *align_expr = ast_parse_byte_align(pc);
832806 AstNode *section_expr = ast_parse_link_section(pc);
833807 AstNode *callconv_expr = ast_parse_callconv(pc);
834 Token *exmark = nullptr;
808 TokenIndex exmark = 0;
835809 AstNode *return_type = nullptr;
836810
837811 exmark = eat_token_if(pc, TokenIdBang);
838812 return_type = ast_parse_type_expr(pc);
839813 if (return_type == nullptr) {
840 Token *next = peek_token(pc);
814 TokenIndex next = peek_token(pc);
841815 ast_error(
842816 pc,
843817 next,
844818 "expected return type (use 'void' to return nothing), found: '%s'",
845 token_name(next->id)
819 token_name(pc->token_ids[next])
846820 );
847821 }
848822
849823 AstNode *res = ast_create_node(pc, NodeTypeFnProto, first);
850824 res->data.fn_proto = {};
851 res->data.fn_proto.name = token_buf(identifier);
825 res->data.fn_proto.name = token_buf(pc, identifier);
852826 res->data.fn_proto.params = params;
853827 res->data.fn_proto.align_expr = align_expr;
854828 res->data.fn_proto.section_expr = section_expr;
855829 res->data.fn_proto.callconv_expr = callconv_expr;
856 res->data.fn_proto.auto_err_set = exmark != nullptr;
830 res->data.fn_proto.auto_err_set = exmark != 0;
857831 res->data.fn_proto.return_type = return_type;
858832
859833 for (size_t i = 0; i < params.length; i++) {
......@@ -869,28 +843,28 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
869843
870844// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
871845static AstNode *ast_parse_var_decl(ParseContext *pc) {
872 Token *mut_kw = eat_token_if(pc, TokenIdKeywordConst);
873 if (mut_kw == nullptr)
846 TokenIndex mut_kw = eat_token_if(pc, TokenIdKeywordConst);
847 if (mut_kw == 0)
874848 mut_kw = eat_token_if(pc, TokenIdKeywordVar);
875 if (mut_kw == nullptr)
849 if (mut_kw == 0)
876850 return nullptr;
877851
878 Token *identifier = expect_token(pc, TokenIdSymbol);
852 TokenIndex identifier = expect_token(pc, TokenIdIdentifier);
879853 AstNode *type_expr = nullptr;
880 if (eat_token_if(pc, TokenIdColon) != nullptr)
854 if (eat_token_if(pc, TokenIdColon) != 0)
881855 type_expr = ast_expect(pc, ast_parse_type_expr);
882856
883857 AstNode *align_expr = ast_parse_byte_align(pc);
884858 AstNode *section_expr = ast_parse_link_section(pc);
885859 AstNode *expr = nullptr;
886 if (eat_token_if(pc, TokenIdEq) != nullptr)
860 if (eat_token_if(pc, TokenIdEq) != 0)
887861 expr = ast_expect(pc, ast_parse_expr);
888862
889863 expect_token(pc, TokenIdSemicolon);
890864
891865 AstNode *res = ast_create_node(pc, NodeTypeVariableDeclaration, mut_kw);
892 res->data.variable_declaration.is_const = mut_kw->id == TokenIdKeywordConst;
893 res->data.variable_declaration.symbol = token_buf(identifier);
866 res->data.variable_declaration.is_const = pc->token_ids[mut_kw] == TokenIdKeywordConst;
867 res->data.variable_declaration.symbol = token_buf(pc, identifier);
894868 res->data.variable_declaration.type = type_expr;
895869 res->data.variable_declaration.align_expr = align_expr;
896870 res->data.variable_declaration.section_expr = section_expr;
......@@ -900,14 +874,14 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {
900874
901875// ContainerField <- KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?
902876static AstNode *ast_parse_container_field(ParseContext *pc) {
903 Token *identifier = eat_token_if(pc, TokenIdSymbol);
904 if (identifier == nullptr)
877 TokenIndex identifier = eat_token_if(pc, TokenIdIdentifier);
878 if (identifier == 0)
905879 return nullptr;
906880
907881 AstNode *type_expr = nullptr;
908 if (eat_token_if(pc, TokenIdColon) != nullptr) {
909 Token *anytype_tok = eat_token_if(pc, TokenIdKeywordAnyType);
910 if (anytype_tok != nullptr) {
882 if (eat_token_if(pc, TokenIdColon) != 0) {
883 TokenIndex anytype_tok = eat_token_if(pc, TokenIdKeywordAnyType);
884 if (anytype_tok != 0) {
911885 type_expr = ast_create_node(pc, NodeTypeAnyTypeField, anytype_tok);
912886 } else {
913887 type_expr = ast_expect(pc, ast_parse_type_expr);
......@@ -915,11 +889,11 @@ static AstNode *ast_parse_container_field(ParseContext *pc) {
915889 }
916890 AstNode *align_expr = ast_parse_byte_align(pc);
917891 AstNode *expr = nullptr;
918 if (eat_token_if(pc, TokenIdEq) != nullptr)
892 if (eat_token_if(pc, TokenIdEq) != 0)
919893 expr = ast_expect(pc, ast_parse_expr);
920894
921895 AstNode *res = ast_create_node(pc, NodeTypeStructField, identifier);
922 res->data.struct_field.name = token_buf(identifier);
896 res->data.struct_field.name = token_buf(pc, identifier);
923897 res->data.struct_field.type = type_expr;
924898 res->data.struct_field.value = expr;
925899 res->data.struct_field.align_expr = align_expr;
......@@ -938,52 +912,52 @@ static AstNode *ast_parse_container_field(ParseContext *pc) {
938912// / SwitchExpr
939913// / AssignExpr SEMICOLON
940914static AstNode *ast_parse_statement(ParseContext *pc) {
941 Token *comptime = eat_token_if(pc, TokenIdKeywordCompTime);
915 TokenIndex comptime = eat_token_if(pc, TokenIdKeywordCompTime);
942916 AstNode *var_decl = ast_parse_var_decl(pc);
943917 if (var_decl != nullptr) {
944918 assert(var_decl->type == NodeTypeVariableDeclaration);
945 var_decl->data.variable_declaration.is_comptime = comptime != nullptr;
919 var_decl->data.variable_declaration.is_comptime = comptime != 0;
946920 return var_decl;
947921 }
948922
949 if (comptime != nullptr) {
923 if (comptime != 0) {
950924 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);
951925 AstNode *res = ast_create_node(pc, NodeTypeCompTime, comptime);
952926 res->data.comptime_expr.expr = statement;
953927 return res;
954928 }
955929
956 Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
957 if (nosuspend != nullptr) {
930 TokenIndex nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
931 if (nosuspend != 0) {
958932 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);
959933 AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
960934 res->data.nosuspend_expr.expr = statement;
961935 return res;
962936 }
963937
964 Token *suspend = eat_token_if(pc, TokenIdKeywordSuspend);
965 if (suspend != nullptr) {
938 TokenIndex suspend = eat_token_if(pc, TokenIdKeywordSuspend);
939 if (suspend != 0) {
966940 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);
967941 AstNode *res = ast_create_node(pc, NodeTypeSuspend, suspend);
968942 res->data.suspend.block = statement;
969943 return res;
970944 }
971945
972 Token *defer = eat_token_if(pc, TokenIdKeywordDefer);
973 if (defer == nullptr)
946 TokenIndex defer = eat_token_if(pc, TokenIdKeywordDefer);
947 if (defer == 0)
974948 defer = eat_token_if(pc, TokenIdKeywordErrdefer);
975 if (defer != nullptr) {
976 Token *payload = (defer->id == TokenIdKeywordErrdefer) ?
977 ast_parse_payload(pc) : nullptr;
949 if (defer != 0) {
950 TokenIndex payload = (pc->token_ids[defer] == TokenIdKeywordErrdefer) ?
951 ast_parse_payload(pc) : 0;
978952 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);
979953 AstNode *res = ast_create_node(pc, NodeTypeDefer, defer);
980954
981955 res->data.defer.kind = ReturnKindUnconditional;
982956 res->data.defer.expr = statement;
983 if (defer->id == TokenIdKeywordErrdefer) {
957 if (pc->token_ids[defer] == TokenIdKeywordErrdefer) {
984958 res->data.defer.kind = ReturnKindError;
985 if (payload != nullptr)
986 res->data.defer.err_payload = token_symbol(pc, payload);
959 if (payload != 0)
960 res->data.defer.err_payload = token_identifier(pc, payload);
987961 }
988962 return res;
989963 }
......@@ -1025,13 +999,13 @@ static AstNode *ast_parse_if_statement(ParseContext *pc) {
1025999 }
10261000
10271001 if (body == nullptr) {
1028 Token *tok = eat_token(pc);
1029 ast_error(pc, tok, "expected if body, found '%s'", token_name(tok->id));
1002 TokenIndex tok = eat_token(pc);
1003 ast_error(pc, tok, "expected if body, found '%s'", token_name(pc->token_ids[tok]));
10301004 }
10311005
1032 Token *err_payload = nullptr;
1006 TokenIndex err_payload = 0;
10331007 AstNode *else_body = nullptr;
1034 if (eat_token_if(pc, TokenIdKeywordElse) != nullptr) {
1008 if (eat_token_if(pc, TokenIdKeywordElse) != 0) {
10351009 err_payload = ast_parse_payload(pc);
10361010 else_body = ast_expect(pc, ast_parse_statement);
10371011 }
......@@ -1040,14 +1014,14 @@ static AstNode *ast_parse_if_statement(ParseContext *pc) {
10401014 expect_token(pc, TokenIdSemicolon);
10411015
10421016 assert(res->type == NodeTypeIfOptional);
1043 if (err_payload != nullptr) {
1017 if (err_payload != 0) {
10441018 AstNodeTestExpr old = res->data.test_expr;
10451019 res->type = NodeTypeIfErrorExpr;
10461020 res->data.if_err_expr.target_node = old.target_node;
10471021 res->data.if_err_expr.var_is_ptr = old.var_is_ptr;
10481022 res->data.if_err_expr.var_symbol = old.var_symbol;
10491023 res->data.if_err_expr.then_node = body;
1050 res->data.if_err_expr.err_symbol = token_buf(err_payload);
1024 res->data.if_err_expr.err_symbol = token_buf(pc, err_payload);
10511025 res->data.if_err_expr.else_node = else_body;
10521026 return res;
10531027 }
......@@ -1068,11 +1042,11 @@ static AstNode *ast_parse_if_statement(ParseContext *pc) {
10681042
10691043// LabeledStatement <- BlockLabel? (Block / LoopStatement)
10701044static AstNode *ast_parse_labeled_statement(ParseContext *pc) {
1071 Token *label = ast_parse_block_label(pc);
1045 TokenIndex label = ast_parse_block_label(pc);
10721046 AstNode *block = ast_parse_block(pc);
10731047 if (block != nullptr) {
10741048 assert(block->type == NodeTypeBlock);
1075 block->data.block.name = token_buf(label);
1049 block->data.block.name = token_buf(pc, label);
10761050 return block;
10771051 }
10781052
......@@ -1080,10 +1054,10 @@ static AstNode *ast_parse_labeled_statement(ParseContext *pc) {
10801054 if (loop != nullptr) {
10811055 switch (loop->type) {
10821056 case NodeTypeForExpr:
1083 loop->data.for_expr.name = token_buf(label);
1057 loop->data.for_expr.name = token_buf(pc, label);
10841058 break;
10851059 case NodeTypeWhileExpr:
1086 loop->data.while_expr.name = token_buf(label);
1060 loop->data.while_expr.name = token_buf(pc, label);
10871061 break;
10881062 default:
10891063 zig_unreachable();
......@@ -1091,29 +1065,29 @@ static AstNode *ast_parse_labeled_statement(ParseContext *pc) {
10911065 return loop;
10921066 }
10931067
1094 if (label != nullptr)
1068 if (label != 0)
10951069 ast_invalid_token_error(pc, peek_token(pc));
10961070 return nullptr;
10971071}
10981072
10991073// LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
11001074static AstNode *ast_parse_loop_statement(ParseContext *pc) {
1101 Token *inline_token = eat_token_if(pc, TokenIdKeywordInline);
1075 TokenIndex inline_token = eat_token_if(pc, TokenIdKeywordInline);
11021076 AstNode *for_statement = ast_parse_for_statement(pc);
11031077 if (for_statement != nullptr) {
11041078 assert(for_statement->type == NodeTypeForExpr);
1105 for_statement->data.for_expr.is_inline = inline_token != nullptr;
1079 for_statement->data.for_expr.is_inline = inline_token != 0;
11061080 return for_statement;
11071081 }
11081082
11091083 AstNode *while_statement = ast_parse_while_statement(pc);
11101084 if (while_statement != nullptr) {
11111085 assert(while_statement->type == NodeTypeWhileExpr);
1112 while_statement->data.while_expr.is_inline = inline_token != nullptr;
1086 while_statement->data.while_expr.is_inline = inline_token != 0;
11131087 return while_statement;
11141088 }
11151089
1116 if (inline_token != nullptr)
1090 if (inline_token != 0)
11171091 ast_invalid_token_error(pc, peek_token(pc));
11181092 return nullptr;
11191093}
......@@ -1134,12 +1108,12 @@ static AstNode *ast_parse_for_statement(ParseContext *pc) {
11341108 }
11351109
11361110 if (body == nullptr) {
1137 Token *tok = eat_token(pc);
1138 ast_error(pc, tok, "expected loop body, found '%s'", token_name(tok->id));
1111 TokenIndex tok = eat_token(pc);
1112 ast_error(pc, tok, "expected loop body, found '%s'", token_name(pc->token_ids[tok]));
11391113 }
11401114
11411115 AstNode *else_body = nullptr;
1142 if (eat_token_if(pc, TokenIdKeywordElse) != nullptr) {
1116 if (eat_token_if(pc, TokenIdKeywordElse) != 0) {
11431117 else_body = ast_expect(pc, ast_parse_statement);
11441118 }
11451119
......@@ -1168,13 +1142,13 @@ static AstNode *ast_parse_while_statement(ParseContext *pc) {
11681142 }
11691143
11701144 if (body == nullptr) {
1171 Token *tok = eat_token(pc);
1172 ast_error(pc, tok, "expected loop body, found '%s'", token_name(tok->id));
1145 TokenIndex tok = eat_token(pc);
1146 ast_error(pc, tok, "expected loop body, found '%s'", token_name(pc->token_ids[tok]));
11731147 }
11741148
1175 Token *err_payload = nullptr;
1149 TokenIndex err_payload = 0;
11761150 AstNode *else_body = nullptr;
1177 if (eat_token_if(pc, TokenIdKeywordElse) != nullptr) {
1151 if (eat_token_if(pc, TokenIdKeywordElse) != 0) {
11781152 err_payload = ast_parse_payload(pc);
11791153 else_body = ast_expect(pc, ast_parse_statement);
11801154 }
......@@ -1184,7 +1158,7 @@ static AstNode *ast_parse_while_statement(ParseContext *pc) {
11841158
11851159 assert(res->type == NodeTypeWhileExpr);
11861160 res->data.while_expr.body = body;
1187 res->data.while_expr.err_symbol = token_buf(err_payload);
1161 res->data.while_expr.err_symbol = token_buf(pc, err_payload);
11881162 res->data.while_expr.else_node = else_body;
11891163 return res;
11901164}
......@@ -1209,11 +1183,11 @@ static AstNode *ast_parse_block_expr_statement(ParseContext *pc) {
12091183
12101184// BlockExpr <- BlockLabel? Block
12111185static AstNode *ast_parse_block_expr(ParseContext *pc) {
1212 Token *label = ast_parse_block_label(pc);
1213 if (label != nullptr) {
1186 TokenIndex label = ast_parse_block_label(pc);
1187 if (label != 0) {
12141188 AstNode *res = ast_expect(pc, ast_parse_block);
12151189 assert(res->type == NodeTypeBlock);
1216 res->data.block.name = token_buf(label);
1190 res->data.block.name = token_buf(pc, label);
12171191 return res;
12181192 }
12191193
......@@ -1230,8 +1204,8 @@ static AstNode *ast_parse_expr(ParseContext *pc) {
12301204 return ast_parse_prefix_op_expr(
12311205 pc,
12321206 [](ParseContext *context) {
1233 Token *try_token = eat_token_if(context, TokenIdKeywordTry);
1234 if (try_token != nullptr) {
1207 TokenIndex try_token = eat_token_if(context, TokenIdKeywordTry);
1208 if (try_token != 0) {
12351209 AstNode *res = ast_create_node(context, NodeTypeReturnExpr, try_token);
12361210 res->data.return_expr.kind = ReturnKindError;
12371211 return res;
......@@ -1318,72 +1292,72 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
13181292 if (if_expr != nullptr)
13191293 return if_expr;
13201294
1321 Token *break_token = eat_token_if(pc, TokenIdKeywordBreak);
1322 if (break_token != nullptr) {
1323 Token *label = ast_parse_break_label(pc);
1295 TokenIndex break_token = eat_token_if(pc, TokenIdKeywordBreak);
1296 if (break_token != 0) {
1297 TokenIndex label = ast_parse_break_label(pc);
13241298 AstNode *expr = ast_parse_expr(pc);
13251299
13261300 AstNode *res = ast_create_node(pc, NodeTypeBreak, break_token);
1327 res->data.break_expr.name = token_buf(label);
1301 res->data.break_expr.name = token_buf(pc, label);
13281302 res->data.break_expr.expr = expr;
13291303 return res;
13301304 }
13311305
1332 Token *comptime = eat_token_if(pc, TokenIdKeywordCompTime);
1333 if (comptime != nullptr) {
1306 TokenIndex comptime = eat_token_if(pc, TokenIdKeywordCompTime);
1307 if (comptime != 0) {
13341308 AstNode *expr = ast_expect(pc, ast_parse_expr);
13351309 AstNode *res = ast_create_node(pc, NodeTypeCompTime, comptime);
13361310 res->data.comptime_expr.expr = expr;
13371311 return res;
13381312 }
13391313
1340 Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
1341 if (nosuspend != nullptr) {
1314 TokenIndex nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
1315 if (nosuspend != 0) {
13421316 AstNode *expr = ast_expect(pc, ast_parse_expr);
13431317 AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
13441318 res->data.nosuspend_expr.expr = expr;
13451319 return res;
13461320 }
13471321
1348 Token *continue_token = eat_token_if(pc, TokenIdKeywordContinue);
1349 if (continue_token != nullptr) {
1350 Token *label = ast_parse_break_label(pc);
1322 TokenIndex continue_token = eat_token_if(pc, TokenIdKeywordContinue);
1323 if (continue_token != 0) {
1324 TokenIndex label = ast_parse_break_label(pc);
13511325 AstNode *res = ast_create_node(pc, NodeTypeContinue, continue_token);
1352 res->data.continue_expr.name = token_buf(label);
1326 res->data.continue_expr.name = token_buf(pc, label);
13531327 return res;
13541328 }
13551329
1356 Token *resume = eat_token_if(pc, TokenIdKeywordResume);
1357 if (resume != nullptr) {
1330 TokenIndex resume = eat_token_if(pc, TokenIdKeywordResume);
1331 if (resume != 0) {
13581332 AstNode *expr = ast_expect(pc, ast_parse_expr);
13591333 AstNode *res = ast_create_node(pc, NodeTypeResume, resume);
13601334 res->data.resume_expr.expr = expr;
13611335 return res;
13621336 }
13631337
1364 Token *return_token = eat_token_if(pc, TokenIdKeywordReturn);
1365 if (return_token != nullptr) {
1338 TokenIndex return_token = eat_token_if(pc, TokenIdKeywordReturn);
1339 if (return_token != 0) {
13661340 AstNode *expr = ast_parse_expr(pc);
13671341 AstNode *res = ast_create_node(pc, NodeTypeReturnExpr, return_token);
13681342 res->data.return_expr.expr = expr;
13691343 return res;
13701344 }
13711345
1372 Token *label = ast_parse_block_label(pc);
1346 TokenIndex label = ast_parse_block_label(pc);
13731347 AstNode *loop = ast_parse_loop_expr(pc);
13741348 if (loop != nullptr) {
13751349 switch (loop->type) {
13761350 case NodeTypeForExpr:
1377 loop->data.for_expr.name = token_buf(label);
1351 loop->data.for_expr.name = token_buf(pc, label);
13781352 break;
13791353 case NodeTypeWhileExpr:
1380 loop->data.while_expr.name = token_buf(label);
1354 loop->data.while_expr.name = token_buf(pc, label);
13811355 break;
13821356 default:
13831357 zig_unreachable();
13841358 }
13851359 return loop;
1386 } else if (label != nullptr) {
1360 } else if (label != 0) {
13871361 // Restore the tokens that we eaten by ast_parse_block_label.
13881362 put_back_token(pc);
13891363 put_back_token(pc);
......@@ -1407,8 +1381,8 @@ static AstNode *ast_parse_if_expr(ParseContext *pc) {
14071381
14081382// Block <- LBRACE Statement* RBRACE
14091383static AstNode *ast_parse_block(ParseContext *pc) {
1410 Token *lbrace = eat_token_if(pc, TokenIdLBrace);
1411 if (lbrace == nullptr)
1384 TokenIndex lbrace = eat_token_if(pc, TokenIdLBrace);
1385 if (lbrace == 0)
14121386 return nullptr;
14131387
14141388 ZigList<AstNode *> statements = {};
......@@ -1462,8 +1436,8 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc) {
14621436// / LBRACE Expr (COMMA Expr)* COMMA? RBRACE
14631437// / LBRACE RBRACE
14641438static AstNode *ast_parse_init_list(ParseContext *pc) {
1465 Token *lbrace = eat_token_if(pc, TokenIdLBrace);
1466 if (lbrace == nullptr)
1439 TokenIndex lbrace = eat_token_if(pc, TokenIdLBrace);
1440 if (lbrace == 0)
14671441 return nullptr;
14681442
14691443 AstNode *first = ast_parse_field_init(pc);
......@@ -1472,7 +1446,7 @@ static AstNode *ast_parse_init_list(ParseContext *pc) {
14721446 res->data.container_init_expr.kind = ContainerInitKindStruct;
14731447 res->data.container_init_expr.entries.append(first);
14741448
1475 while (eat_token_if(pc, TokenIdComma) != nullptr) {
1449 while (eat_token_if(pc, TokenIdComma) != 0) {
14761450 AstNode *field_init = ast_parse_field_init(pc);
14771451 if (field_init == nullptr)
14781452 break;
......@@ -1490,7 +1464,7 @@ static AstNode *ast_parse_init_list(ParseContext *pc) {
14901464 if (first != nullptr) {
14911465 res->data.container_init_expr.entries.append(first);
14921466
1493 while (eat_token_if(pc, TokenIdComma) != nullptr) {
1467 while (eat_token_if(pc, TokenIdComma) != 0) {
14941468 AstNode *expr = ast_parse_expr(pc);
14951469 if (expr == nullptr)
14961470 break;
......@@ -1535,7 +1509,7 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {
15351509// <- KEYWORD_async PrimaryTypeExpr SuffixOp* FnCallArguments
15361510// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*
15371511static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
1538 Token *async_token = eat_token_if(pc, TokenIdKeywordAsync);
1512 TokenIndex async_token = eat_token_if(pc, TokenIdKeywordAsync);
15391513 if (async_token) {
15401514 AstNode *child = ast_expect(pc, ast_parse_primary_type_expr);
15411515 while (true) {
......@@ -1652,43 +1626,21 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
16521626// / STRINGLITERAL
16531627// / SwitchExpr
16541628static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
1655 // TODO: This is not in line with the grammar.
1656 // Because the prev stage 1 tokenizer does not parse
1657 // @[a-zA-Z_][a-zA-Z0-9_] as one token, it has to do a
1658 // hack, where it accepts '@' (IDENTIFIER / KEYWORD_export /
1659 // KEYWORD_extern).
1660 // I'd say that it's better if '@' is part of the builtin
1661 // identifier token.
1662 Token *at_sign = eat_token_if(pc, TokenIdAtSign);
1663 if (at_sign != nullptr) {
1664 Buf *name;
1665 Token *token;
1666 if ((token = eat_token_if(pc, TokenIdKeywordExport)) != nullptr) {
1667 name = buf_create_from_str("export");
1668 } else if ((token = eat_token_if(pc, TokenIdKeywordExtern)) != nullptr) {
1669 name = buf_create_from_str("extern");
1670 } else {
1671 token = expect_token(pc, TokenIdSymbol);
1672 name = token_buf(token);
1673 }
1674
1629 TokenIndex builtin_tok = eat_token_if(pc, TokenIdBuiltin);
1630 if (builtin_tok != 0) {
16751631 AstNode *res = ast_expect(pc, ast_parse_fn_call_arguments);
1676 AstNode *name_sym = ast_create_node(pc, NodeTypeSymbol, token);
1677 name_sym->data.symbol_expr.symbol = name;
1632 AstNode *name_sym = ast_create_node(pc, NodeTypeIdentifier, builtin_tok);
16781633
16791634 assert(res->type == NodeTypeFnCallExpr);
1680 res->line = at_sign->start_line;
1681 res->column = at_sign->start_column;
1635 res->main_token = builtin_tok;
16821636 res->data.fn_call_expr.fn_ref_expr = name_sym;
16831637 res->data.fn_call_expr.modifier = CallModifierBuiltin;
16841638 return res;
16851639 }
16861640
1687 Token *char_lit = eat_token_if(pc, TokenIdCharLiteral);
1688 if (char_lit != nullptr) {
1689 AstNode *res = ast_create_node(pc, NodeTypeCharLiteral, char_lit);
1690 res->data.char_literal.value = char_lit->data.char_lit.c;
1691 return res;
1641 TokenIndex char_lit = eat_token_if(pc, TokenIdCharLiteral);
1642 if (char_lit != 0) {
1643 return ast_create_node(pc, NodeTypeCharLiteral, char_lit);
16921644 }
16931645
16941646 AstNode *container_decl = ast_parse_container_decl(pc);
......@@ -1703,12 +1655,9 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
17031655 if (error_set_decl != nullptr)
17041656 return error_set_decl;
17051657
1706 Token *float_lit = eat_token_if(pc, TokenIdFloatLiteral);
1707 if (float_lit != nullptr) {
1708 AstNode *res = ast_create_node(pc, NodeTypeFloatLiteral, float_lit);
1709 res->data.float_literal.bigfloat = &float_lit->data.float_lit.bigfloat;
1710 res->data.float_literal.overflow = float_lit->data.float_lit.overflow;
1711 return res;
1658 TokenIndex float_lit = eat_token_if(pc, TokenIdFloatLiteral);
1659 if (float_lit != 0) {
1660 return ast_create_node(pc, NodeTypeFloatLiteral, float_lit);
17121661 }
17131662
17141663 AstNode *fn_proto = ast_parse_fn_proto(pc);
......@@ -1723,86 +1672,77 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
17231672 if (labeled_type_expr != nullptr)
17241673 return labeled_type_expr;
17251674
1726 Token *identifier = eat_token_if(pc, TokenIdSymbol);
1727 if (identifier != nullptr)
1728 return token_symbol(pc, identifier);
1675 TokenIndex identifier = eat_token_if(pc, TokenIdIdentifier);
1676 if (identifier != 0)
1677 return token_identifier(pc, identifier);
17291678
17301679 AstNode *if_type_expr = ast_parse_if_type_expr(pc);
17311680 if (if_type_expr != nullptr)
17321681 return if_type_expr;
17331682
1734 Token *int_lit = eat_token_if(pc, TokenIdIntLiteral);
1735 if (int_lit != nullptr) {
1736 AstNode *res = ast_create_node(pc, NodeTypeIntLiteral, int_lit);
1737 res->data.int_literal.bigint = &int_lit->data.int_lit.bigint;
1738 return res;
1683 TokenIndex int_lit = eat_token_if(pc, TokenIdIntLiteral);
1684 if (int_lit != 0) {
1685 return ast_create_node(pc, NodeTypeIntLiteral, int_lit);
17391686 }
17401687
1741 Token *comptime = eat_token_if(pc, TokenIdKeywordCompTime);
1742 if (comptime != nullptr) {
1688 TokenIndex comptime = eat_token_if(pc, TokenIdKeywordCompTime);
1689 if (comptime != 0) {
17431690 AstNode *expr = ast_expect(pc, ast_parse_type_expr);
17441691 AstNode *res = ast_create_node(pc, NodeTypeCompTime, comptime);
17451692 res->data.comptime_expr.expr = expr;
17461693 return res;
17471694 }
17481695
1749 Token *error = eat_token_if(pc, TokenIdKeywordError);
1750 if (error != nullptr) {
1751 Token *dot = expect_token(pc, TokenIdDot);
1752 Token *name = expect_token(pc, TokenIdSymbol);
1696 TokenIndex error = eat_token_if(pc, TokenIdKeywordError);
1697 if (error != 0) {
1698 TokenIndex dot = expect_token(pc, TokenIdDot);
1699 TokenIndex name = expect_token(pc, TokenIdIdentifier);
17531700 AstNode *left = ast_create_node(pc, NodeTypeErrorType, error);
17541701 AstNode *res = ast_create_node(pc, NodeTypeFieldAccessExpr, dot);
17551702 res->data.field_access_expr.struct_expr = left;
1756 res->data.field_access_expr.field_name = token_buf(name);
1703 res->data.field_access_expr.field_name = token_buf(pc, name);
17571704 return res;
17581705 }
17591706
1760 Token *false_token = eat_token_if(pc, TokenIdKeywordFalse);
1761 if (false_token != nullptr) {
1707 TokenIndex false_token = eat_token_if(pc, TokenIdKeywordFalse);
1708 if (false_token != 0) {
17621709 AstNode *res = ast_create_node(pc, NodeTypeBoolLiteral, false_token);
17631710 res->data.bool_literal.value = false;
17641711 return res;
17651712 }
17661713
1767 Token *null = eat_token_if(pc, TokenIdKeywordNull);
1768 if (null != nullptr)
1714 TokenIndex null = eat_token_if(pc, TokenIdKeywordNull);
1715 if (null != 0)
17691716 return ast_create_node(pc, NodeTypeNullLiteral, null);
17701717
1771 Token *anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame);
1772 if (anyframe != nullptr)
1718 TokenIndex anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame);
1719 if (anyframe != 0)
17731720 return ast_create_node(pc, NodeTypeAnyFrameType, anyframe);
17741721
1775 Token *true_token = eat_token_if(pc, TokenIdKeywordTrue);
1776 if (true_token != nullptr) {
1722 TokenIndex true_token = eat_token_if(pc, TokenIdKeywordTrue);
1723 if (true_token != 0) {
17771724 AstNode *res = ast_create_node(pc, NodeTypeBoolLiteral, true_token);
17781725 res->data.bool_literal.value = true;
17791726 return res;
17801727 }
17811728
1782 Token *undefined = eat_token_if(pc, TokenIdKeywordUndefined);
1783 if (undefined != nullptr)
1729 TokenIndex undefined = eat_token_if(pc, TokenIdKeywordUndefined);
1730 if (undefined != 0)
17841731 return ast_create_node(pc, NodeTypeUndefinedLiteral, undefined);
17851732
1786 Token *unreachable = eat_token_if(pc, TokenIdKeywordUnreachable);
1787 if (unreachable != nullptr)
1733 TokenIndex unreachable = eat_token_if(pc, TokenIdKeywordUnreachable);
1734 if (unreachable != 0)
17881735 return ast_create_node(pc, NodeTypeUnreachable, unreachable);
17891736
17901737
1791 Buf *string_buf;
1792 Token *string_lit = eat_token_if(pc, TokenIdStringLiteral);
1793 if (string_lit != nullptr) {
1794 string_buf = token_buf(string_lit);
1795 } else {
1796 Buf multiline_string_buf = BUF_INIT;
1797 string_lit = ast_parse_multiline_string_literal(pc, &multiline_string_buf);
1798 if (string_lit != nullptr) {
1799 string_buf = buf_create_from_buf(&multiline_string_buf);
1800 }
1738 TokenIndex string_lit = eat_token_if(pc, TokenIdStringLiteral);
1739 if (string_lit != 0) {
1740 return ast_create_node(pc, NodeTypeStringLiteral, string_lit);
18011741 }
1802 if (string_lit != nullptr) {
1803 AstNode *res = ast_create_node(pc, NodeTypeStringLiteral, string_lit);
1804 res->data.string_literal.buf = string_buf;
1805 return res;
1742
1743 TokenIndex multiline_str_lit = ast_parse_multi_tok(pc, TokenIdMultilineStringLiteralLine);
1744 if (multiline_str_lit != 0) {
1745 return ast_create_node(pc, NodeTypeStringLiteral, multiline_str_lit);
18061746 }
18071747
18081748 AstNode *switch_expr = ast_parse_switch_expr(pc);
......@@ -1814,22 +1754,21 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
18141754
18151755// ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
18161756static AstNode *ast_parse_container_decl(ParseContext *pc) {
1817 Token *layout_token = eat_token_if(pc, TokenIdKeywordExtern);
1818 if (layout_token == nullptr)
1757 TokenIndex layout_token = eat_token_if(pc, TokenIdKeywordExtern);
1758 if (layout_token == 0)
18191759 layout_token = eat_token_if(pc, TokenIdKeywordPacked);
18201760
18211761 AstNode *res = ast_parse_container_decl_auto(pc);
18221762 if (res == nullptr) {
1823 if (layout_token != nullptr)
1763 if (layout_token != 0)
18241764 put_back_token(pc);
18251765 return nullptr;
18261766 }
18271767
18281768 assert(res->type == NodeTypeContainerDecl);
1829 if (layout_token != nullptr) {
1830 res->line = layout_token->start_line;
1831 res->column = layout_token->start_column;
1832 res->data.container_decl.layout = layout_token->id == TokenIdKeywordExtern
1769 if (layout_token != 0) {
1770 res->main_token = layout_token;
1771 res->data.container_decl.layout = pc->token_ids[layout_token] == TokenIdKeywordExtern
18331772 ? ContainerLayoutExtern
18341773 : ContainerLayoutPacked;
18351774 }
......@@ -1838,28 +1777,27 @@ static AstNode *ast_parse_container_decl(ParseContext *pc) {
18381777
18391778// ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE
18401779static AstNode *ast_parse_error_set_decl(ParseContext *pc) {
1841 Token *first = eat_token_if(pc, TokenIdKeywordError);
1842 if (first == nullptr)
1780 TokenIndex first = eat_token_if(pc, TokenIdKeywordError);
1781 if (first == 0)
18431782 return nullptr;
1844 if (eat_token_if(pc, TokenIdLBrace) == nullptr) {
1783 if (eat_token_if(pc, TokenIdLBrace) == 0) {
18451784 put_back_token(pc);
18461785 return nullptr;
18471786 }
18481787
18491788 ZigList<AstNode *> decls = ast_parse_list<AstNode>(pc, TokenIdComma, [](ParseContext *context) {
1850 Buf doc_comment_buf = BUF_INIT;
1851 Token *doc_token = ast_parse_doc_comments(context, &doc_comment_buf);
1852 Token *ident = eat_token_if(context, TokenIdSymbol);
1853 if (ident == nullptr)
1789 TokenIndex doc_token = ast_parse_doc_comments(context);
1790 TokenIndex ident = eat_token_if(context, TokenIdIdentifier);
1791 if (ident == 0)
18541792 return (AstNode*)nullptr;
18551793
1856 AstNode *symbol_node = token_symbol(context, ident);
1857 if (doc_token == nullptr)
1794 AstNode *symbol_node = token_identifier(context, ident);
1795 if (doc_token == 0)
18581796 return symbol_node;
18591797
18601798 AstNode *field_node = ast_create_node(context, NodeTypeErrorSetField, doc_token);
18611799 field_node->data.err_set_field.field_name = symbol_node;
1862 field_node->data.err_set_field.doc_comments = doc_comment_buf;
1800 field_node->data.err_set_field.doc_comments = doc_token;
18631801 return field_node;
18641802 });
18651803 expect_token(pc, TokenIdRBrace);
......@@ -1871,8 +1809,8 @@ static AstNode *ast_parse_error_set_decl(ParseContext *pc) {
18711809
18721810// GroupedExpr <- LPAREN Expr RPAREN
18731811static AstNode *ast_parse_grouped_expr(ParseContext *pc) {
1874 Token *lparen = eat_token_if(pc, TokenIdLParen);
1875 if (lparen == nullptr)
1812 TokenIndex lparen = eat_token_if(pc, TokenIdLParen);
1813 if (lparen == 0)
18761814 return nullptr;
18771815
18781816 AstNode *expr = ast_expect(pc, ast_parse_expr);
......@@ -1892,12 +1830,12 @@ static AstNode *ast_parse_if_type_expr(ParseContext *pc) {
18921830// <- BlockLabel Block
18931831// / BlockLabel? LoopTypeExpr
18941832static AstNode *ast_parse_labeled_type_expr(ParseContext *pc) {
1895 Token *label = ast_parse_block_label(pc);
1896 if (label != nullptr) {
1833 TokenIndex label = ast_parse_block_label(pc);
1834 if (label != 0) {
18971835 AstNode *block = ast_parse_block(pc);
18981836 if (block != nullptr) {
18991837 assert(block->type == NodeTypeBlock);
1900 block->data.block.name = token_buf(label);
1838 block->data.block.name = token_buf(pc, label);
19011839 return block;
19021840 }
19031841 }
......@@ -1906,10 +1844,10 @@ static AstNode *ast_parse_labeled_type_expr(ParseContext *pc) {
19061844 if (loop != nullptr) {
19071845 switch (loop->type) {
19081846 case NodeTypeForExpr:
1909 loop->data.for_expr.name = token_buf(label);
1847 loop->data.for_expr.name = token_buf(pc, label);
19101848 break;
19111849 case NodeTypeWhileExpr:
1912 loop->data.while_expr.name = token_buf(label);
1850 loop->data.while_expr.name = token_buf(pc, label);
19131851 break;
19141852 default:
19151853 zig_unreachable();
......@@ -1917,7 +1855,7 @@ static AstNode *ast_parse_labeled_type_expr(ParseContext *pc) {
19171855 return loop;
19181856 }
19191857
1920 if (label != nullptr) {
1858 if (label != 0) {
19211859 put_back_token(pc);
19221860 put_back_token(pc);
19231861 }
......@@ -1945,8 +1883,8 @@ static AstNode *ast_parse_while_type_expr(ParseContext *pc) {
19451883
19461884// SwitchExpr <- KEYWORD_switch LPAREN Expr RPAREN LBRACE SwitchProngList RBRACE
19471885static AstNode *ast_parse_switch_expr(ParseContext *pc) {
1948 Token *switch_token = eat_token_if(pc, TokenIdKeywordSwitch);
1949 if (switch_token == nullptr)
1886 TokenIndex switch_token = eat_token_if(pc, TokenIdKeywordSwitch);
1887 if (switch_token == 0)
19501888 return nullptr;
19511889
19521890 expect_token(pc, TokenIdLParen);
......@@ -1964,11 +1902,11 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc) {
19641902
19651903// AsmExpr <- KEYWORD_asm KEYWORD_volatile? LPAREN STRINGLITERAL AsmOutput? RPAREN
19661904static AstNode *ast_parse_asm_expr(ParseContext *pc) {
1967 Token *asm_token = eat_token_if(pc, TokenIdKeywordAsm);
1968 if (asm_token == nullptr)
1905 TokenIndex asm_token = eat_token_if(pc, TokenIdKeywordAsm);
1906 if (asm_token == 0)
19691907 return nullptr;
19701908
1971 Token *volatile_token = eat_token_if(pc, TokenIdKeywordVolatile);
1909 TokenIndex volatile_token = eat_token_if(pc, TokenIdKeywordVolatile);
19721910 expect_token(pc, TokenIdLParen);
19731911 AstNode *asm_template = ast_expect(pc, ast_parse_expr);
19741912 AstNode *res = ast_parse_asm_output(pc);
......@@ -1976,25 +1914,21 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc) {
19761914 res = ast_create_node_no_line_info(pc, NodeTypeAsmExpr);
19771915 expect_token(pc, TokenIdRParen);
19781916
1979 res->line = asm_token->start_line;
1980 res->column = asm_token->start_column;
1917 res->main_token = asm_token;
19811918 res->data.asm_expr.volatile_token = volatile_token;
19821919 res->data.asm_expr.asm_template = asm_template;
19831920 return res;
19841921}
19851922
19861923static AstNode *ast_parse_anon_lit(ParseContext *pc) {
1987 Token *period = eat_token_if(pc, TokenIdDot);
1988 if (period == nullptr)
1924 TokenIndex period = eat_token_if(pc, TokenIdDot);
1925 if (period == 0)
19891926 return nullptr;
19901927
19911928 // anon enum literal
1992 Token *identifier = eat_token_if(pc, TokenIdSymbol);
1993 if (identifier != nullptr) {
1994 AstNode *res = ast_create_node(pc, NodeTypeEnumLiteral, period);
1995 res->data.enum_literal.period = period;
1996 res->data.enum_literal.identifier = identifier;
1997 return res;
1929 TokenIndex identifier = eat_token_if(pc, TokenIdIdentifier);
1930 if (identifier != 0) {
1931 return ast_create_node(pc, NodeTypeEnumLiteral, period);
19981932 }
19991933
20001934 // anon container literal
......@@ -2007,7 +1941,7 @@ static AstNode *ast_parse_anon_lit(ParseContext *pc) {
20071941
20081942// AsmOutput <- COLON AsmOutputList AsmInput?
20091943static AstNode *ast_parse_asm_output(ParseContext *pc) {
2010 if (eat_token_if(pc, TokenIdColon) == nullptr)
1944 if (eat_token_if(pc, TokenIdColon) == 0)
20111945 return nullptr;
20121946
20131947 ZigList<AsmOutput *> output_list = ast_parse_list(pc, TokenIdComma, ast_parse_asm_output_item);
......@@ -2021,20 +1955,20 @@ static AstNode *ast_parse_asm_output(ParseContext *pc) {
20211955
20221956// AsmOutputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN (MINUSRARROW TypeExpr / IDENTIFIER) RPAREN
20231957static AsmOutput *ast_parse_asm_output_item(ParseContext *pc) {
2024 if (eat_token_if(pc, TokenIdLBracket) == nullptr)
1958 if (eat_token_if(pc, TokenIdLBracket) == 0)
20251959 return nullptr;
20261960
2027 Token *sym_name = expect_token(pc, TokenIdSymbol);
1961 TokenIndex sym_name = expect_token(pc, TokenIdIdentifier);
20281962 expect_token(pc, TokenIdRBracket);
20291963
2030 Token *str = eat_token_if(pc, TokenIdMultilineStringLiteral);
2031 if (str == nullptr)
1964 TokenIndex str = ast_parse_multi_tok(pc, TokenIdMultilineStringLiteralLine);
1965 if (str == 0)
20321966 str = expect_token(pc, TokenIdStringLiteral);
20331967 expect_token(pc, TokenIdLParen);
20341968
2035 Token *var_name = eat_token_if(pc, TokenIdSymbol);
1969 TokenIndex var_name = eat_token_if(pc, TokenIdIdentifier);
20361970 AstNode *return_type = nullptr;
2037 if (var_name == nullptr) {
1971 if (var_name == 0) {
20381972 expect_token(pc, TokenIdArrow);
20391973 return_type = ast_expect(pc, ast_parse_type_expr);
20401974 }
......@@ -2042,16 +1976,16 @@ static AsmOutput *ast_parse_asm_output_item(ParseContext *pc) {
20421976 expect_token(pc, TokenIdRParen);
20431977
20441978 AsmOutput *res = heap::c_allocator.create<AsmOutput>();
2045 res->asm_symbolic_name = token_buf(sym_name);
2046 res->constraint = token_buf(str);
2047 res->variable_name = token_buf(var_name);
1979 res->asm_symbolic_name = token_buf(pc, sym_name);
1980 res->constraint = token_buf(pc, str);
1981 res->variable_name = token_buf(pc, var_name);
20481982 res->return_type = return_type;
20491983 return res;
20501984}
20511985
20521986// AsmInput <- COLON AsmInputList AsmClobbers?
20531987static AstNode *ast_parse_asm_input(ParseContext *pc) {
2054 if (eat_token_if(pc, TokenIdColon) == nullptr)
1988 if (eat_token_if(pc, TokenIdColon) == 0)
20551989 return nullptr;
20561990
20571991 ZigList<AsmInput *> input_list = ast_parse_list(pc, TokenIdComma, ast_parse_asm_input_item);
......@@ -2065,37 +1999,35 @@ static AstNode *ast_parse_asm_input(ParseContext *pc) {
20651999
20662000// AsmInputItem <- LBRACKET IDENTIFIER RBRACKET STRINGLITERAL LPAREN Expr RPAREN
20672001static AsmInput *ast_parse_asm_input_item(ParseContext *pc) {
2068 if (eat_token_if(pc, TokenIdLBracket) == nullptr)
2002 if (eat_token_if(pc, TokenIdLBracket) == 0)
20692003 return nullptr;
20702004
2071 Token *sym_name = expect_token(pc, TokenIdSymbol);
2005 TokenIndex sym_name = expect_token(pc, TokenIdIdentifier);
20722006 expect_token(pc, TokenIdRBracket);
20732007
2074 Token *constraint = eat_token_if(pc, TokenIdMultilineStringLiteral);
2075 if (constraint == nullptr)
2076 constraint = expect_token(pc, TokenIdStringLiteral);
2008 TokenIndex constraint = expect_token(pc, TokenIdStringLiteral);
20772009 expect_token(pc, TokenIdLParen);
20782010 AstNode *expr = ast_expect(pc, ast_parse_expr);
20792011 expect_token(pc, TokenIdRParen);
20802012
20812013 AsmInput *res = heap::c_allocator.create<AsmInput>();
2082 res->asm_symbolic_name = token_buf(sym_name);
2083 res->constraint = token_buf(constraint);
2014 res->asm_symbolic_name = token_buf(pc, sym_name);
2015 res->constraint = token_buf(pc, constraint);
20842016 res->expr = expr;
20852017 return res;
20862018}
20872019
20882020// AsmClobbers <- COLON StringList
20892021static AstNode *ast_parse_asm_clobbers(ParseContext *pc) {
2090 if (eat_token_if(pc, TokenIdColon) == nullptr)
2022 if (eat_token_if(pc, TokenIdColon) == 0)
20912023 return nullptr;
20922024
20932025 ZigList<Buf *> clobber_list = ast_parse_list<Buf>(pc, TokenIdComma, [](ParseContext *context) {
2094 Token *str = eat_token_if(context, TokenIdStringLiteral);
2095 if (str == nullptr)
2096 str = eat_token_if(context, TokenIdMultilineStringLiteral);
2097 if (str != nullptr)
2098 return token_buf(str);
2026 TokenIndex str = eat_token_if(context, TokenIdStringLiteral);
2027 if (str == 0)
2028 str = ast_parse_multi_tok(context, TokenIdMultilineStringLiteralLine);
2029 if (str != 0)
2030 return token_buf(context, str);
20992031 return (Buf*)nullptr;
21002032 });
21012033
......@@ -2105,24 +2037,24 @@ static AstNode *ast_parse_asm_clobbers(ParseContext *pc) {
21052037}
21062038
21072039// BreakLabel <- COLON IDENTIFIER
2108static Token *ast_parse_break_label(ParseContext *pc) {
2109 if (eat_token_if(pc, TokenIdColon) == nullptr)
2110 return nullptr;
2040static TokenIndex ast_parse_break_label(ParseContext *pc) {
2041 if (eat_token_if(pc, TokenIdColon) == 0)
2042 return 0;
21112043
2112 return expect_token(pc, TokenIdSymbol);
2044 return expect_token(pc, TokenIdIdentifier);
21132045}
21142046
21152047// BlockLabel <- IDENTIFIER COLON
2116static Token *ast_parse_block_label(ParseContext *pc) {
2117 Token *ident = eat_token_if(pc, TokenIdSymbol);
2118 if (ident == nullptr)
2119 return nullptr;
2048static TokenIndex ast_parse_block_label(ParseContext *pc) {
2049 TokenIndex ident = eat_token_if(pc, TokenIdIdentifier);
2050 if (ident == 0)
2051 return 0;
21202052
21212053 // We do 2 token lookahead here, as we don't want to error when
21222054 // parsing identifiers.
2123 if (eat_token_if(pc, TokenIdColon) == nullptr) {
2055 if (eat_token_if(pc, TokenIdColon) == 0) {
21242056 put_back_token(pc);
2125 return nullptr;
2057 return 0;
21262058 }
21272059
21282060 return ident;
......@@ -2130,17 +2062,17 @@ static Token *ast_parse_block_label(ParseContext *pc) {
21302062
21312063// FieldInit <- DOT IDENTIFIER EQUAL Expr
21322064static AstNode *ast_parse_field_init(ParseContext *pc) {
2133 Token *first = eat_token_if(pc, TokenIdDot);
2134 if (first == nullptr)
2065 TokenIndex first = eat_token_if(pc, TokenIdDot);
2066 if (first == 0)
21352067 return nullptr;
21362068
2137 Token *name = eat_token_if(pc, TokenIdSymbol);
2138 if (name == nullptr) {
2069 TokenIndex name = eat_token_if(pc, TokenIdIdentifier);
2070 if (name == 0) {
21392071 // Because of anon literals ".{" is also valid.
21402072 put_back_token(pc);
21412073 return nullptr;
21422074 }
2143 if (eat_token_if(pc, TokenIdEq) == nullptr) {
2075 if (eat_token_if(pc, TokenIdEq) == 0) {
21442076 // Because ".Name" can also be intepreted as an enum literal, we should put back
21452077 // those two tokens again so that the parser can try to parse them as the enum
21462078 // literal later.
......@@ -2151,15 +2083,15 @@ static AstNode *ast_parse_field_init(ParseContext *pc) {
21512083 AstNode *expr = ast_expect(pc, ast_parse_expr);
21522084
21532085 AstNode *res = ast_create_node(pc, NodeTypeStructValueField, first);
2154 res->data.struct_val_field.name = token_buf(name);
2086 res->data.struct_val_field.name = token_buf(pc, name);
21552087 res->data.struct_val_field.expr = expr;
21562088 return res;
21572089}
21582090
21592091// WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN
21602092static AstNode *ast_parse_while_continue_expr(ParseContext *pc) {
2161 Token *first = eat_token_if(pc, TokenIdColon);
2162 if (first == nullptr)
2093 TokenIndex first = eat_token_if(pc, TokenIdColon);
2094 if (first == 0)
21632095 return nullptr;
21642096
21652097 expect_token(pc, TokenIdLParen);
......@@ -2170,8 +2102,8 @@ static AstNode *ast_parse_while_continue_expr(ParseContext *pc) {
21702102
21712103// LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN
21722104static AstNode *ast_parse_link_section(ParseContext *pc) {
2173 Token *first = eat_token_if(pc, TokenIdKeywordLinkSection);
2174 if (first == nullptr)
2105 TokenIndex first = eat_token_if(pc, TokenIdKeywordLinkSection);
2106 if (first == 0)
21752107 return nullptr;
21762108
21772109 expect_token(pc, TokenIdLParen);
......@@ -2182,8 +2114,8 @@ static AstNode *ast_parse_link_section(ParseContext *pc) {
21822114
21832115// CallConv <- KEYWORD_callconv LPAREN Expr RPAREN
21842116static AstNode *ast_parse_callconv(ParseContext *pc) {
2185 Token *first = eat_token_if(pc, TokenIdKeywordCallconv);
2186 if (first == nullptr)
2117 TokenIndex first = eat_token_if(pc, TokenIdKeywordCallconv);
2118 if (first == 0)
21872119 return nullptr;
21882120
21892121 expect_token(pc, TokenIdLParen);
......@@ -2194,28 +2126,27 @@ static AstNode *ast_parse_callconv(ParseContext *pc) {
21942126
21952127// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
21962128static AstNode *ast_parse_param_decl(ParseContext *pc) {
2197 Buf doc_comments = BUF_INIT;
2198 ast_parse_doc_comments(pc, &doc_comments);
2129 TokenIndex first_doc_comment = ast_parse_doc_comments(pc);
21992130
2200 Token *first = eat_token_if(pc, TokenIdKeywordNoAlias);
2201 if (first == nullptr)
2131 TokenIndex first = eat_token_if(pc, TokenIdKeywordNoAlias);
2132 if (first == 0)
22022133 first = eat_token_if(pc, TokenIdKeywordCompTime);
22032134
2204 Token *name = eat_token_if(pc, TokenIdSymbol);
2205 if (name != nullptr) {
2206 if (eat_token_if(pc, TokenIdColon) != nullptr) {
2207 if (first == nullptr)
2135 TokenIndex name = eat_token_if(pc, TokenIdIdentifier);
2136 if (name != 0) {
2137 if (eat_token_if(pc, TokenIdColon) != 0) {
2138 if (first == 0)
22082139 first = name;
22092140 } else {
22102141 // We put back the ident, so it can be parsed as a ParamType
22112142 // later.
22122143 put_back_token(pc);
2213 name = nullptr;
2144 name = 0;
22142145 }
22152146 }
22162147
22172148 AstNode *res;
2218 if (first == nullptr) {
2149 if (first == 0) {
22192150 first = peek_token(pc);
22202151 res = ast_parse_param_type(pc);
22212152 } else {
......@@ -2226,12 +2157,11 @@ static AstNode *ast_parse_param_decl(ParseContext *pc) {
22262157 return nullptr;
22272158
22282159 assert(res->type == NodeTypeParamDecl);
2229 res->line = first->start_line;
2230 res->column = first->start_column;
2231 res->data.param_decl.name = token_buf(name);
2232 res->data.param_decl.doc_comments = doc_comments;
2233 res->data.param_decl.is_noalias = first->id == TokenIdKeywordNoAlias;
2234 res->data.param_decl.is_comptime = first->id == TokenIdKeywordCompTime;
2160 res->main_token = first;
2161 res->data.param_decl.name = token_buf(pc, name);
2162 res->data.param_decl.doc_comments = first_doc_comment;
2163 res->data.param_decl.is_noalias = pc->token_ids[first] == TokenIdKeywordNoAlias;
2164 res->data.param_decl.is_comptime = pc->token_ids[first] == TokenIdKeywordCompTime;
22352165 return res;
22362166}
22372167
......@@ -2240,15 +2170,15 @@ static AstNode *ast_parse_param_decl(ParseContext *pc) {
22402170// / DOT3
22412171// / TypeExpr
22422172static AstNode *ast_parse_param_type(ParseContext *pc) {
2243 Token *anytype_token = eat_token_if(pc, TokenIdKeywordAnyType);
2244 if (anytype_token != nullptr) {
2173 TokenIndex anytype_token = eat_token_if(pc, TokenIdKeywordAnyType);
2174 if (anytype_token != 0) {
22452175 AstNode *res = ast_create_node(pc, NodeTypeParamDecl, anytype_token);
22462176 res->data.param_decl.anytype_token = anytype_token;
22472177 return res;
22482178 }
22492179
2250 Token *dots = eat_token_if(pc, TokenIdEllipsis3);
2251 if (dots != nullptr) {
2180 TokenIndex dots = eat_token_if(pc, TokenIdEllipsis3);
2181 if (dots != 0) {
22522182 AstNode *res = ast_create_node(pc, NodeTypeParamDecl, dots);
22532183 res->data.param_decl.is_var_args = true;
22542184 return res;
......@@ -2266,8 +2196,8 @@ static AstNode *ast_parse_param_type(ParseContext *pc) {
22662196
22672197// IfPrefix <- KEYWORD_if LPAREN Expr RPAREN PtrPayload?
22682198static AstNode *ast_parse_if_prefix(ParseContext *pc) {
2269 Token *first = eat_token_if(pc, TokenIdKeywordIf);
2270 if (first == nullptr)
2199 TokenIndex first = eat_token_if(pc, TokenIdKeywordIf);
2200 if (first == 0)
22712201 return nullptr;
22722202
22732203 expect_token(pc, TokenIdLParen);
......@@ -2279,16 +2209,16 @@ static AstNode *ast_parse_if_prefix(ParseContext *pc) {
22792209 AstNode *res = ast_create_node(pc, NodeTypeIfOptional, first);
22802210 res->data.test_expr.target_node = condition;
22812211 if (opt_payload.unwrap(&payload)) {
2282 res->data.test_expr.var_symbol = token_buf(payload.payload);
2283 res->data.test_expr.var_is_ptr = payload.asterisk != nullptr;
2212 res->data.test_expr.var_symbol = token_buf(pc, payload.payload);
2213 res->data.test_expr.var_is_ptr = payload.asterisk != 0;
22842214 }
22852215 return res;
22862216}
22872217
22882218// WhilePrefix <- KEYWORD_while LPAREN Expr RPAREN PtrPayload? WhileContinueExpr?
22892219static AstNode *ast_parse_while_prefix(ParseContext *pc) {
2290 Token *while_token = eat_token_if(pc, TokenIdKeywordWhile);
2291 if (while_token == nullptr)
2220 TokenIndex while_token = eat_token_if(pc, TokenIdKeywordWhile);
2221 if (while_token == 0)
22922222 return nullptr;
22932223
22942224 expect_token(pc, TokenIdLParen);
......@@ -2302,8 +2232,8 @@ static AstNode *ast_parse_while_prefix(ParseContext *pc) {
23022232 res->data.while_expr.condition = condition;
23032233 res->data.while_expr.continue_expr = continue_expr;
23042234 if (opt_payload.unwrap(&payload)) {
2305 res->data.while_expr.var_symbol = token_buf(payload.payload);
2306 res->data.while_expr.var_is_ptr = payload.asterisk != nullptr;
2235 res->data.while_expr.var_symbol = token_buf(pc, payload.payload);
2236 res->data.while_expr.var_is_ptr = payload.asterisk != 0;
23072237 }
23082238
23092239 return res;
......@@ -2311,8 +2241,8 @@ static AstNode *ast_parse_while_prefix(ParseContext *pc) {
23112241
23122242// ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload
23132243static AstNode *ast_parse_for_prefix(ParseContext *pc) {
2314 Token *for_token = eat_token_if(pc, TokenIdKeywordFor);
2315 if (for_token == nullptr)
2244 TokenIndex for_token = eat_token_if(pc, TokenIdKeywordFor);
2245 if (for_token == 0)
23162246 return nullptr;
23172247
23182248 expect_token(pc, TokenIdLParen);
......@@ -2324,31 +2254,31 @@ static AstNode *ast_parse_for_prefix(ParseContext *pc) {
23242254
23252255 AstNode *res = ast_create_node(pc, NodeTypeForExpr, for_token);
23262256 res->data.for_expr.array_expr = array_expr;
2327 res->data.for_expr.elem_node = token_symbol(pc, payload.payload);
2328 res->data.for_expr.elem_is_ptr = payload.asterisk != nullptr;
2329 if (payload.index != nullptr)
2330 res->data.for_expr.index_node = token_symbol(pc, payload.index);
2257 res->data.for_expr.elem_node = token_identifier(pc, payload.payload);
2258 res->data.for_expr.elem_is_ptr = payload.asterisk != 0;
2259 if (payload.index != 0)
2260 res->data.for_expr.index_node = token_identifier(pc, payload.index);
23312261
23322262 return res;
23332263}
23342264
23352265// Payload <- PIPE IDENTIFIER PIPE
2336static Token *ast_parse_payload(ParseContext *pc) {
2337 if (eat_token_if(pc, TokenIdBinOr) == nullptr)
2338 return nullptr;
2266static TokenIndex ast_parse_payload(ParseContext *pc) {
2267 if (eat_token_if(pc, TokenIdBinOr) == 0)
2268 return 0;
23392269
2340 Token *res = expect_token(pc, TokenIdSymbol);
2270 TokenIndex res = expect_token(pc, TokenIdIdentifier);
23412271 expect_token(pc, TokenIdBinOr);
23422272 return res;
23432273}
23442274
23452275// PtrPayload <- PIPE ASTERISK? IDENTIFIER PIPE
23462276static Optional<PtrPayload> ast_parse_ptr_payload(ParseContext *pc) {
2347 if (eat_token_if(pc, TokenIdBinOr) == nullptr)
2277 if (eat_token_if(pc, TokenIdBinOr) == 0)
23482278 return Optional<PtrPayload>::none();
23492279
2350 Token *asterisk = eat_token_if(pc, TokenIdStar);
2351 Token *payload = expect_token(pc, TokenIdSymbol);
2280 TokenIndex asterisk = eat_token_if(pc, TokenIdStar);
2281 TokenIndex payload = expect_token(pc, TokenIdIdentifier);
23522282 expect_token(pc, TokenIdBinOr);
23532283
23542284 PtrPayload res;
......@@ -2359,14 +2289,14 @@ static Optional<PtrPayload> ast_parse_ptr_payload(ParseContext *pc) {
23592289
23602290// PtrIndexPayload <- PIPE ASTERISK? IDENTIFIER (COMMA IDENTIFIER)? PIPE
23612291static Optional<PtrIndexPayload> ast_parse_ptr_index_payload(ParseContext *pc) {
2362 if (eat_token_if(pc, TokenIdBinOr) == nullptr)
2292 if (eat_token_if(pc, TokenIdBinOr) == 0)
23632293 return Optional<PtrIndexPayload>::none();
23642294
2365 Token *asterisk = eat_token_if(pc, TokenIdStar);
2366 Token *payload = expect_token(pc, TokenIdSymbol);
2367 Token *index = nullptr;
2368 if (eat_token_if(pc, TokenIdComma) != nullptr)
2369 index = expect_token(pc, TokenIdSymbol);
2295 TokenIndex asterisk = eat_token_if(pc, TokenIdStar);
2296 TokenIndex payload = expect_token(pc, TokenIdIdentifier);
2297 TokenIndex index = 0;
2298 if (eat_token_if(pc, TokenIdComma) != 0)
2299 index = expect_token(pc, TokenIdIdentifier);
23702300 expect_token(pc, TokenIdBinOr);
23712301
23722302 PtrIndexPayload res;
......@@ -2390,8 +2320,8 @@ static AstNode *ast_parse_switch_prong(ParseContext *pc) {
23902320 assert(res->type == NodeTypeSwitchProng);
23912321 res->data.switch_prong.expr = expr;
23922322 if (opt_payload.unwrap(&payload)) {
2393 res->data.switch_prong.var_symbol = token_symbol(pc, payload.payload);
2394 res->data.switch_prong.var_is_ptr = payload.asterisk != nullptr;
2323 res->data.switch_prong.var_symbol = token_identifier(pc, payload.payload);
2324 res->data.switch_prong.var_is_ptr = payload.asterisk != 0;
23952325 }
23962326
23972327 return res;
......@@ -2407,7 +2337,7 @@ static AstNode *ast_parse_switch_case(ParseContext *pc) {
24072337 res->data.switch_prong.items.append(first);
24082338 res->data.switch_prong.any_items_are_range = first->type == NodeTypeSwitchRange;
24092339
2410 while (eat_token_if(pc, TokenIdComma) != nullptr) {
2340 while (eat_token_if(pc, TokenIdComma) != 0) {
24112341 AstNode *item = ast_parse_switch_item(pc);
24122342 if (item == nullptr)
24132343 break;
......@@ -2419,8 +2349,8 @@ static AstNode *ast_parse_switch_case(ParseContext *pc) {
24192349 return res;
24202350 }
24212351
2422 Token *else_token = eat_token_if(pc, TokenIdKeywordElse);
2423 if (else_token != nullptr)
2352 TokenIndex else_token = eat_token_if(pc, TokenIdKeywordElse);
2353 if (else_token != 0)
24242354 return ast_create_node(pc, NodeTypeSwitchProng, else_token);
24252355
24262356 return nullptr;
......@@ -2432,8 +2362,8 @@ static AstNode *ast_parse_switch_item(ParseContext *pc) {
24322362 if (expr == nullptr)
24332363 return nullptr;
24342364
2435 Token *dots = eat_token_if(pc, TokenIdEllipsis3);
2436 if (dots != nullptr) {
2365 TokenIndex dots = eat_token_if(pc, TokenIdEllipsis3);
2366 if (dots != 0) {
24372367 AstNode *expr2 = ast_expect(pc, ast_parse_expr);
24382368 AstNode *res = ast_create_node(pc, NodeTypeSwitchRange, dots);
24392369 res->data.switch_range.start = expr;
......@@ -2478,9 +2408,9 @@ static AstNode *ast_parse_assign_op(ParseContext *pc) {
24782408 table[TokenIdTimesEq] = BinOpTypeAssignTimes;
24792409 table[TokenIdTimesPercentEq] = BinOpTypeAssignTimesWrap;
24802410
2481 BinOpType op = table[peek_token(pc)->id];
2411 BinOpType op = table[pc->token_ids[pc->current_token]];
24822412 if (op != BinOpTypeInvalid) {
2483 Token *op_token = eat_token(pc);
2413 TokenIndex op_token = eat_token(pc);
24842414 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
24852415 res->data.bin_op_expr.bin_op = op;
24862416 return res;
......@@ -2506,9 +2436,9 @@ static AstNode *ast_parse_compare_op(ParseContext *pc) {
25062436 table[TokenIdCmpLessOrEq] = BinOpTypeCmpLessOrEq;
25072437 table[TokenIdCmpGreaterOrEq] = BinOpTypeCmpGreaterOrEq;
25082438
2509 BinOpType op = table[peek_token(pc)->id];
2439 BinOpType op = table[pc->token_ids[pc->current_token]];
25102440 if (op != BinOpTypeInvalid) {
2511 Token *op_token = eat_token(pc);
2441 TokenIndex op_token = eat_token(pc);
25122442 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
25132443 res->data.bin_op_expr.bin_op = op;
25142444 return res;
......@@ -2530,20 +2460,20 @@ static AstNode *ast_parse_bitwise_op(ParseContext *pc) {
25302460 table[TokenIdBinOr] = BinOpTypeBinOr;
25312461 table[TokenIdKeywordOrElse] = BinOpTypeUnwrapOptional;
25322462
2533 BinOpType op = table[peek_token(pc)->id];
2463 BinOpType op = table[pc->token_ids[pc->current_token]];
25342464 if (op != BinOpTypeInvalid) {
2535 Token *op_token = eat_token(pc);
2465 TokenIndex op_token = eat_token(pc);
25362466 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
25372467 res->data.bin_op_expr.bin_op = op;
25382468 return res;
25392469 }
25402470
2541 Token *catch_token = eat_token_if(pc, TokenIdKeywordCatch);
2542 if (catch_token != nullptr) {
2543 Token *payload = ast_parse_payload(pc);
2471 TokenIndex catch_token = eat_token_if(pc, TokenIdKeywordCatch);
2472 if (catch_token != 0) {
2473 TokenIndex payload = ast_parse_payload(pc);
25442474 AstNode *res = ast_create_node(pc, NodeTypeCatchExpr, catch_token);
2545 if (payload != nullptr)
2546 res->data.unwrap_err_expr.symbol = token_symbol(pc, payload);
2475 if (payload != 0)
2476 res->data.unwrap_err_expr.symbol = token_identifier(pc, payload);
25472477
25482478 return res;
25492479 }
......@@ -2559,9 +2489,9 @@ static AstNode *ast_parse_bit_shift_op(ParseContext *pc) {
25592489 table[TokenIdBitShiftLeft] = BinOpTypeBitShiftLeft;
25602490 table[TokenIdBitShiftRight] = BinOpTypeBitShiftRight;
25612491
2562 BinOpType op = table[peek_token(pc)->id];
2492 BinOpType op = table[pc->token_ids[pc->current_token]];
25632493 if (op != BinOpTypeInvalid) {
2564 Token *op_token = eat_token(pc);
2494 TokenIndex op_token = eat_token(pc);
25652495 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
25662496 res->data.bin_op_expr.bin_op = op;
25672497 return res;
......@@ -2584,9 +2514,9 @@ static AstNode *ast_parse_addition_op(ParseContext *pc) {
25842514 table[TokenIdPlusPercent] = BinOpTypeAddWrap;
25852515 table[TokenIdMinusPercent] = BinOpTypeSubWrap;
25862516
2587 BinOpType op = table[peek_token(pc)->id];
2517 BinOpType op = table[pc->token_ids[pc->current_token]];
25882518 if (op != BinOpTypeInvalid) {
2589 Token *op_token = eat_token(pc);
2519 TokenIndex op_token = eat_token(pc);
25902520 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
25912521 res->data.bin_op_expr.bin_op = op;
25922522 return res;
......@@ -2611,9 +2541,9 @@ static AstNode *ast_parse_multiply_op(ParseContext *pc) {
26112541 table[TokenIdStarStar] = BinOpTypeArrayMult;
26122542 table[TokenIdTimesPercent] = BinOpTypeMultWrap;
26132543
2614 BinOpType op = table[peek_token(pc)->id];
2544 BinOpType op = table[pc->token_ids[pc->current_token]];
26152545 if (op != BinOpTypeInvalid) {
2616 Token *op_token = eat_token(pc);
2546 TokenIndex op_token = eat_token(pc);
26172547 AstNode *res = ast_create_node(pc, NodeTypeBinOpExpr, op_token);
26182548 res->data.bin_op_expr.bin_op = op;
26192549 return res;
......@@ -2638,23 +2568,23 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {
26382568 table[TokenIdMinusPercent] = PrefixOpNegationWrap;
26392569 table[TokenIdAmpersand] = PrefixOpAddrOf;
26402570
2641 PrefixOp op = table[peek_token(pc)->id];
2571 PrefixOp op = table[pc->token_ids[pc->current_token]];
26422572 if (op != PrefixOpInvalid) {
2643 Token *op_token = eat_token(pc);
2573 TokenIndex op_token = eat_token(pc);
26442574 AstNode *res = ast_create_node(pc, NodeTypePrefixOpExpr, op_token);
26452575 res->data.prefix_op_expr.prefix_op = op;
26462576 return res;
26472577 }
26482578
2649 Token *try_token = eat_token_if(pc, TokenIdKeywordTry);
2650 if (try_token != nullptr) {
2579 TokenIndex try_token = eat_token_if(pc, TokenIdKeywordTry);
2580 if (try_token != 0) {
26512581 AstNode *res = ast_create_node(pc, NodeTypeReturnExpr, try_token);
26522582 res->data.return_expr.kind = ReturnKindError;
26532583 return res;
26542584 }
26552585
2656 Token *await = eat_token_if(pc, TokenIdKeywordAwait);
2657 if (await != nullptr) {
2586 TokenIndex await = eat_token_if(pc, TokenIdKeywordAwait);
2587 if (await != 0) {
26582588 AstNode *res = ast_create_node(pc, NodeTypeAwaitExpr, await);
26592589 return res;
26602590 }
......@@ -2668,16 +2598,16 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {
26682598// / ArrayTypeStart (ByteAlign / KEYWORD_const / KEYWORD_volatile)*
26692599// / PtrTypeStart (KEYWORD_align LPAREN Expr (COLON INTEGER COLON INTEGER)? RPAREN / KEYWORD_const / KEYWORD_volatile)*
26702600static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
2671 Token *questionmark = eat_token_if(pc, TokenIdQuestion);
2672 if (questionmark != nullptr) {
2601 TokenIndex questionmark = eat_token_if(pc, TokenIdQuestion);
2602 if (questionmark != 0) {
26732603 AstNode *res = ast_create_node(pc, NodeTypePrefixOpExpr, questionmark);
26742604 res->data.prefix_op_expr.prefix_op = PrefixOpOptional;
26752605 return res;
26762606 }
26772607
2678 Token *anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame);
2679 if (anyframe != nullptr) {
2680 if (eat_token_if(pc, TokenIdArrow) != nullptr) {
2608 TokenIndex anyframe = eat_token_if(pc, TokenIdKeywordAnyFrame);
2609 if (anyframe != 0) {
2610 if (eat_token_if(pc, TokenIdArrow) != 0) {
26812611 AstNode *res = ast_create_node(pc, NodeTypeAnyFrameType, anyframe);
26822612 return res;
26832613 }
......@@ -2685,18 +2615,18 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
26852615 put_back_token(pc);
26862616 }
26872617
2688 Token *arr_init_lbracket = eat_token_if(pc, TokenIdLBracket);
2689 if (arr_init_lbracket != nullptr) {
2690 Token *underscore = eat_token_if(pc, TokenIdSymbol);
2691 if (underscore == nullptr) {
2618 TokenIndex arr_init_lbracket = eat_token_if(pc, TokenIdLBracket);
2619 if (arr_init_lbracket != 0) {
2620 TokenIndex underscore = eat_token_if(pc, TokenIdIdentifier);
2621 if (underscore == 0) {
26922622 put_back_token(pc);
2693 } else if (!buf_eql_str(token_buf(underscore), "_")) {
2623 } else if (!buf_eql_str(token_buf(pc, underscore), "_")) {
26942624 put_back_token(pc);
26952625 put_back_token(pc);
26962626 } else {
26972627 AstNode *sentinel = nullptr;
2698 Token *colon = eat_token_if(pc, TokenIdColon);
2699 if (colon != nullptr) {
2628 TokenIndex colon = eat_token_if(pc, TokenIdColon);
2629 if (colon != 0) {
27002630 sentinel = ast_expect(pc, ast_parse_expr);
27012631 }
27022632 expect_token(pc, TokenIdRBracket);
......@@ -2715,33 +2645,33 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
27152645 if (child == nullptr)
27162646 child = ptr;
27172647 while (true) {
2718 Token *allowzero_token = eat_token_if(pc, TokenIdKeywordAllowZero);
2719 if (allowzero_token != nullptr) {
2648 TokenIndex allowzero_token = eat_token_if(pc, TokenIdKeywordAllowZero);
2649 if (allowzero_token != 0) {
27202650 child->data.pointer_type.allow_zero_token = allowzero_token;
27212651 continue;
27222652 }
27232653
2724 if (eat_token_if(pc, TokenIdKeywordAlign) != nullptr) {
2654 if (eat_token_if(pc, TokenIdKeywordAlign) != 0) {
27252655 expect_token(pc, TokenIdLParen);
27262656 AstNode *align_expr = ast_expect(pc, ast_parse_expr);
27272657 child->data.pointer_type.align_expr = align_expr;
2728 if (eat_token_if(pc, TokenIdColon) != nullptr) {
2729 Token *bit_offset_start = expect_token(pc, TokenIdIntLiteral);
2658 if (eat_token_if(pc, TokenIdColon) != 0) {
2659 TokenIndex bit_offset_start = expect_token(pc, TokenIdIntLiteral);
27302660 expect_token(pc, TokenIdColon);
2731 Token *host_int_bytes = expect_token(pc, TokenIdIntLiteral);
2732 child->data.pointer_type.bit_offset_start = token_bigint(bit_offset_start);
2733 child->data.pointer_type.host_int_bytes = token_bigint(host_int_bytes);
2661 TokenIndex host_int_bytes = expect_token(pc, TokenIdIntLiteral);
2662 child->data.pointer_type.bit_offset_start = bit_offset_start;
2663 child->data.pointer_type.host_int_bytes = host_int_bytes;
27342664 }
27352665 expect_token(pc, TokenIdRParen);
27362666 continue;
27372667 }
27382668
2739 if (eat_token_if(pc, TokenIdKeywordConst) != nullptr) {
2669 if (eat_token_if(pc, TokenIdKeywordConst) != 0) {
27402670 child->data.pointer_type.is_const = true;
27412671 continue;
27422672 }
27432673
2744 if (eat_token_if(pc, TokenIdKeywordVolatile) != nullptr) {
2674 if (eat_token_if(pc, TokenIdKeywordVolatile) != 0) {
27452675 child->data.pointer_type.is_volatile = true;
27462676 continue;
27472677 }
......@@ -2756,8 +2686,8 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
27562686 if (array != nullptr) {
27572687 assert(array->type == NodeTypeArrayType);
27582688 while (true) {
2759 Token *allowzero_token = eat_token_if(pc, TokenIdKeywordAllowZero);
2760 if (allowzero_token != nullptr) {
2689 TokenIndex allowzero_token = eat_token_if(pc, TokenIdKeywordAllowZero);
2690 if (allowzero_token != 0) {
27612691 array->data.array_type.allow_zero_token = allowzero_token;
27622692 continue;
27632693 }
......@@ -2768,12 +2698,12 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
27682698 continue;
27692699 }
27702700
2771 if (eat_token_if(pc, TokenIdKeywordConst) != nullptr) {
2701 if (eat_token_if(pc, TokenIdKeywordConst) != 0) {
27722702 array->data.array_type.is_const = true;
27732703 continue;
27742704 }
27752705
2776 if (eat_token_if(pc, TokenIdKeywordVolatile) != nullptr) {
2706 if (eat_token_if(pc, TokenIdKeywordVolatile) != 0) {
27772707 array->data.array_type.is_volatile = true;
27782708 continue;
27792709 }
......@@ -2793,14 +2723,14 @@ static AstNode *ast_parse_prefix_type_op(ParseContext *pc) {
27932723// / DOTASTERISK
27942724// / DOTQUESTIONMARK
27952725static AstNode *ast_parse_suffix_op(ParseContext *pc) {
2796 Token *lbracket = eat_token_if(pc, TokenIdLBracket);
2797 if (lbracket != nullptr) {
2726 TokenIndex lbracket = eat_token_if(pc, TokenIdLBracket);
2727 if (lbracket != 0) {
27982728 AstNode *start = ast_expect(pc, ast_parse_expr);
27992729 AstNode *end = nullptr;
2800 if (eat_token_if(pc, TokenIdEllipsis2) != nullptr) {
2730 if (eat_token_if(pc, TokenIdEllipsis2) != 0) {
28012731 AstNode *sentinel = nullptr;
28022732 end = ast_parse_expr(pc);
2803 if (eat_token_if(pc, TokenIdColon) != nullptr) {
2733 if (eat_token_if(pc, TokenIdColon) != 0) {
28042734 sentinel = ast_parse_expr(pc);
28052735 }
28062736 expect_token(pc, TokenIdRBracket);
......@@ -2819,18 +2749,18 @@ static AstNode *ast_parse_suffix_op(ParseContext *pc) {
28192749 return res;
28202750 }
28212751
2822 Token *dot_asterisk = eat_token_if(pc, TokenIdDotStar);
2823 if (dot_asterisk != nullptr)
2752 TokenIndex dot_asterisk = eat_token_if(pc, TokenIdDotStar);
2753 if (dot_asterisk != 0)
28242754 return ast_create_node(pc, NodeTypePtrDeref, dot_asterisk);
28252755
2826 Token *dot = eat_token_if(pc, TokenIdDot);
2827 if (dot != nullptr) {
2828 if (eat_token_if(pc, TokenIdQuestion) != nullptr)
2756 TokenIndex dot = eat_token_if(pc, TokenIdDot);
2757 if (dot != 0) {
2758 if (eat_token_if(pc, TokenIdQuestion) != 0)
28292759 return ast_create_node(pc, NodeTypeUnwrapOptional, dot);
28302760
2831 Token *ident = expect_token(pc, TokenIdSymbol);
2761 TokenIndex ident = expect_token(pc, TokenIdIdentifier);
28322762 AstNode *res = ast_create_node(pc, NodeTypeFieldAccessExpr, dot);
2833 res->data.field_access_expr.field_name = token_buf(ident);
2763 res->data.field_access_expr.field_name = token_buf(pc, ident);
28342764 return res;
28352765 }
28362766
......@@ -2839,8 +2769,8 @@ static AstNode *ast_parse_suffix_op(ParseContext *pc) {
28392769
28402770// FnCallArguments <- LPAREN ExprList RPAREN
28412771static AstNode *ast_parse_fn_call_arguments(ParseContext *pc) {
2842 Token *paren = eat_token_if(pc, TokenIdLParen);
2843 if (paren == nullptr)
2772 TokenIndex paren = eat_token_if(pc, TokenIdLParen);
2773 if (paren == 0)
28442774 return nullptr;
28452775
28462776 ZigList<AstNode *> params = ast_parse_list(pc, TokenIdComma, ast_parse_expr);
......@@ -2854,14 +2784,14 @@ static AstNode *ast_parse_fn_call_arguments(ParseContext *pc) {
28542784
28552785// ArrayTypeStart <- LBRACKET Expr? RBRACKET
28562786static AstNode *ast_parse_array_type_start(ParseContext *pc) {
2857 Token *lbracket = eat_token_if(pc, TokenIdLBracket);
2858 if (lbracket == nullptr)
2787 TokenIndex lbracket = eat_token_if(pc, TokenIdLBracket);
2788 if (lbracket == 0)
28592789 return nullptr;
28602790
28612791 AstNode *size = ast_parse_expr(pc);
28622792 AstNode *sentinel = nullptr;
2863 Token *colon = eat_token_if(pc, TokenIdColon);
2864 if (colon != nullptr) {
2793 TokenIndex colon = eat_token_if(pc, TokenIdColon);
2794 if (colon != 0) {
28652795 sentinel = ast_expect(pc, ast_parse_expr);
28662796 }
28672797 expect_token(pc, TokenIdRBracket);
......@@ -2879,10 +2809,10 @@ static AstNode *ast_parse_array_type_start(ParseContext *pc) {
28792809static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {
28802810 AstNode *sentinel = nullptr;
28812811
2882 Token *asterisk = eat_token_if(pc, TokenIdStar);
2883 if (asterisk != nullptr) {
2884 Token *colon = eat_token_if(pc, TokenIdColon);
2885 if (colon != nullptr) {
2812 TokenIndex asterisk = eat_token_if(pc, TokenIdStar);
2813 if (asterisk != 0) {
2814 TokenIndex colon = eat_token_if(pc, TokenIdColon);
2815 if (colon != 0) {
28862816 sentinel = ast_expect(pc, ast_parse_expr);
28872817 }
28882818 AstNode *res = ast_create_node(pc, NodeTypePointerType, asterisk);
......@@ -2891,10 +2821,10 @@ static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {
28912821 return res;
28922822 }
28932823
2894 Token *asterisk2 = eat_token_if(pc, TokenIdStarStar);
2895 if (asterisk2 != nullptr) {
2896 Token *colon = eat_token_if(pc, TokenIdColon);
2897 if (colon != nullptr) {
2824 TokenIndex asterisk2 = eat_token_if(pc, TokenIdStarStar);
2825 if (asterisk2 != 0) {
2826 TokenIndex colon = eat_token_if(pc, TokenIdColon);
2827 if (colon != 0) {
28982828 sentinel = ast_expect(pc, ast_parse_expr);
28992829 }
29002830 AstNode *res = ast_create_node(pc, NodeTypePointerType, asterisk2);
......@@ -2906,15 +2836,15 @@ static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {
29062836 return res;
29072837 }
29082838
2909 Token *lbracket = eat_token_if(pc, TokenIdLBracket);
2910 if (lbracket != nullptr) {
2911 Token *star = eat_token_if(pc, TokenIdStar);
2912 if (star == nullptr) {
2839 TokenIndex lbracket = eat_token_if(pc, TokenIdLBracket);
2840 if (lbracket != 0) {
2841 TokenIndex star = eat_token_if(pc, TokenIdStar);
2842 if (star == 0) {
29132843 put_back_token(pc);
29142844 } else {
2915 Token *c_tok = eat_token_if(pc, TokenIdSymbol);
2916 if (c_tok != nullptr) {
2917 if (!buf_eql_str(token_buf(c_tok), "c")) {
2845 TokenIndex c_tok = eat_token_if(pc, TokenIdIdentifier);
2846 if (c_tok != 0) {
2847 if (!buf_eql_str(token_buf(pc, c_tok), "c")) {
29182848 put_back_token(pc); // c symbol
29192849 } else {
29202850 expect_token(pc, TokenIdRBracket);
......@@ -2924,8 +2854,8 @@ static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {
29242854 }
29252855 }
29262856
2927 Token *colon = eat_token_if(pc, TokenIdColon);
2928 if (colon != nullptr) {
2857 TokenIndex colon = eat_token_if(pc, TokenIdColon);
2858 if (colon != 0) {
29292859 sentinel = ast_expect(pc, ast_parse_expr);
29302860 }
29312861 expect_token(pc, TokenIdRBracket);
......@@ -2951,9 +2881,7 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {
29512881
29522882 res->data.container_decl.fields = members.fields;
29532883 res->data.container_decl.decls = members.decls;
2954 if (buf_len(&members.doc_comments) != 0) {
2955 res->data.container_decl.doc_comments = members.doc_comments;
2956 }
2884 res->data.container_decl.doc_comments = members.doc_comments;
29572885 return res;
29582886}
29592887
......@@ -2963,8 +2891,8 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {
29632891// / KEYWORD_union (LPAREN (KEYWORD_enum (LPAREN Expr RPAREN)? / Expr) RPAREN)?
29642892// / KEYWORD_opaque
29652893static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
2966 Token *first = eat_token_if(pc, TokenIdKeywordStruct);
2967 if (first != nullptr) {
2894 TokenIndex first = eat_token_if(pc, TokenIdKeywordStruct);
2895 if (first != 0) {
29682896 AstNode *res = ast_create_node(pc, NodeTypeContainerDecl, first);
29692897 res->data.container_decl.init_arg_expr = nullptr;
29702898 res->data.container_decl.kind = ContainerKindStruct;
......@@ -2972,7 +2900,7 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
29722900 }
29732901
29742902 first = eat_token_if(pc, TokenIdKeywordOpaque);
2975 if (first != nullptr) {
2903 if (first != 0) {
29762904 AstNode *res = ast_create_node(pc, NodeTypeContainerDecl, first);
29772905 res->data.container_decl.init_arg_expr = nullptr;
29782906 res->data.container_decl.kind = ContainerKindOpaque;
......@@ -2980,9 +2908,9 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
29802908 }
29812909
29822910 first = eat_token_if(pc, TokenIdKeywordEnum);
2983 if (first != nullptr) {
2911 if (first != 0) {
29842912 AstNode *init_arg_expr = nullptr;
2985 if (eat_token_if(pc, TokenIdLParen) != nullptr) {
2913 if (eat_token_if(pc, TokenIdLParen) != 0) {
29862914 init_arg_expr = ast_expect(pc, ast_parse_expr);
29872915 expect_token(pc, TokenIdRParen);
29882916 }
......@@ -2993,13 +2921,13 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
29932921 }
29942922
29952923 first = eat_token_if(pc, TokenIdKeywordUnion);
2996 if (first != nullptr) {
2924 if (first != 0) {
29972925 AstNode *init_arg_expr = nullptr;
29982926 bool auto_enum = false;
2999 if (eat_token_if(pc, TokenIdLParen) != nullptr) {
3000 if (eat_token_if(pc, TokenIdKeywordEnum) != nullptr) {
2927 if (eat_token_if(pc, TokenIdLParen) != 0) {
2928 if (eat_token_if(pc, TokenIdKeywordEnum) != 0) {
30012929 auto_enum = true;
3002 if (eat_token_if(pc, TokenIdLParen) != nullptr) {
2930 if (eat_token_if(pc, TokenIdLParen) != 0) {
30032931 init_arg_expr = ast_expect(pc, ast_parse_expr);
30042932 expect_token(pc, TokenIdRParen);
30052933 }
......@@ -3022,7 +2950,7 @@ static AstNode *ast_parse_container_decl_type(ParseContext *pc) {
30222950
30232951// ByteAlign <- KEYWORD_align LPAREN Expr RPAREN
30242952static AstNode *ast_parse_byte_align(ParseContext *pc) {
3025 if (eat_token_if(pc, TokenIdKeywordAlign) == nullptr)
2953 if (eat_token_if(pc, TokenIdKeywordAlign) == 0)
30262954 return nullptr;
30272955
30282956 expect_token(pc, TokenIdLParen);
......@@ -3103,7 +3031,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
31033031 case NodeTypeCharLiteral:
31043032 // none
31053033 break;
3106 case NodeTypeSymbol:
3034 case NodeTypeIdentifier:
31073035 // none
31083036 break;
31093037 case NodeTypePrefixOpExpr:
......@@ -3264,3 +3192,403 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
32643192 break;
32653193 }
32663194}
3195
3196Error source_string_literal_buf(const char *source, Buf *out, size_t *bad_index) {
3197 size_t byte_offset = 0;
3198
3199 assert(source[byte_offset] == '"');
3200 byte_offset += 1;
3201
3202 buf_resize(out, 0);
3203
3204 uint32_t codepoint;
3205
3206 enum {
3207 StateStart,
3208 StateBackslash,
3209 StateUnicodeLBrace,
3210 StateUnicodeDigit,
3211 } state = StateStart;
3212 for (;;byte_offset += 1) {
3213 switch (state) {
3214 case StateStart: switch (source[byte_offset]) {
3215 case '\\':
3216 state = StateBackslash;
3217 continue;
3218 case '\n':
3219 *bad_index = byte_offset;
3220 return ErrorInvalidCharacter;
3221 case '"':
3222 return ErrorNone;
3223 default:
3224 buf_append_char(out, source[byte_offset]);
3225 continue;
3226 }
3227 case StateBackslash: switch (source[byte_offset]) {
3228 case 'n':
3229 buf_append_char(out, '\n');
3230 state = StateStart;
3231 continue;
3232 case 'r':
3233 buf_append_char(out, '\r');
3234 state = StateStart;
3235 continue;
3236 case '\\':
3237 buf_append_char(out, '\\');
3238 state = StateStart;
3239 continue;
3240 case 't':
3241 buf_append_char(out, '\t');
3242 state = StateStart;
3243 continue;
3244 case '\'':
3245 buf_append_char(out, '\'');
3246 state = StateStart;
3247 continue;
3248 case '"':
3249 buf_append_char(out, '"');
3250 state = StateStart;
3251 continue;
3252 case 'x': {
3253 byte_offset += 1;
3254 uint8_t digit1;
3255 if (source[byte_offset] >= '0' && source[byte_offset] <= '9') {
3256 digit1 = source[byte_offset] - '0';
3257 } else if (source[byte_offset] >= 'a' && source[byte_offset] <= 'z') {
3258 digit1 = source[byte_offset] - 'a' + 10;
3259 } else if (source[byte_offset] >= 'A' && source[byte_offset] <= 'Z') {
3260 digit1 = source[byte_offset] - 'A' + 10;
3261 } else {
3262 *bad_index = byte_offset;
3263 return ErrorInvalidCharacter;
3264 }
3265
3266 byte_offset += 1;
3267 uint8_t digit0;
3268 if (source[byte_offset] >= '0' && source[byte_offset] <= '9') {
3269 digit0 = source[byte_offset] - '0';
3270 } else if (source[byte_offset] >= 'a' && source[byte_offset] <= 'z') {
3271 digit0 = source[byte_offset] - 'a' + 10;
3272 } else if (source[byte_offset] >= 'A' && source[byte_offset] <= 'Z') {
3273 digit0 = source[byte_offset] - 'A' + 10;
3274 } else {
3275 *bad_index = byte_offset;
3276 return ErrorInvalidCharacter;
3277 }
3278
3279 buf_append_char(out, digit1 * 16 + digit0);
3280 state = StateStart;
3281 continue;
3282 }
3283 case 'u':
3284 state = StateUnicodeLBrace;
3285 continue;
3286 default:
3287 *bad_index = byte_offset;
3288 return ErrorInvalidCharacter;
3289 }
3290 case StateUnicodeLBrace: switch (source[byte_offset]) {
3291 case '{':
3292 state = StateUnicodeDigit;
3293 codepoint = 0;
3294 continue;
3295 default:
3296 *bad_index = byte_offset;
3297 return ErrorInvalidCharacter;
3298 }
3299 case StateUnicodeDigit: {
3300 uint8_t digit;
3301 if (source[byte_offset] >= '0' && source[byte_offset] <= '9') {
3302 digit = source[byte_offset] - '0';
3303 } else if (source[byte_offset] >= 'a' && source[byte_offset] <= 'z') {
3304 digit = source[byte_offset] - 'a' + 10;
3305 } else if (source[byte_offset] >= 'A' && source[byte_offset] <= 'Z') {
3306 digit = source[byte_offset] - 'A' + 10;
3307 } else if (source[byte_offset] == '}') {
3308 if (codepoint < 0x80) {
3309 buf_append_char(out, codepoint);
3310 } else if (codepoint < 0x800) {
3311 buf_append_char(out, 0xc0 | (codepoint >> 6));
3312 buf_append_char(out, 0x80 | (codepoint & 0x3f));
3313 } else if (codepoint < 0x10000) {
3314 buf_append_char(out, 0xe0 | (codepoint >> 12));
3315 buf_append_char(out, 0x80 | ((codepoint >> 6) & 0x3f));
3316 buf_append_char(out, 0x80 | (codepoint & 0x3f));
3317 } else if (codepoint < 0x110000) {
3318 buf_append_char(out, 0xf0 | (codepoint >> 18));
3319 buf_append_char(out, 0x80 | ((codepoint >> 12) & 0x3f));
3320 buf_append_char(out, 0x80 | ((codepoint >> 6) & 0x3f));
3321 buf_append_char(out, 0x80 | (codepoint & 0x3f));
3322 } else {
3323 *bad_index = byte_offset;
3324 return ErrorUnicodePointTooLarge;
3325 }
3326 state = StateStart;
3327 continue;
3328 } else {
3329 *bad_index = byte_offset;
3330 return ErrorInvalidCharacter;
3331 }
3332 codepoint = codepoint * 16 + digit;
3333 continue;
3334 }
3335 }
3336 }
3337 zig_unreachable();
3338}
3339
3340static uint32_t utf8_code_point(const uint8_t *bytes) {
3341 if (bytes[0] <= 0x7f) {
3342 return bytes[0];
3343 } else if (bytes[0] >= 0xc0 && bytes[0] <= 0xdf) {
3344 uint32_t result = bytes[0] & 0x1f;
3345 result <<= 6;
3346 result |= bytes[1] & 0x3f;
3347 return result;
3348 } else if (bytes[0] >= 0xe0 && bytes[0] <= 0xef) {
3349 uint32_t result = bytes[0] & 0xf;
3350
3351 result <<= 6;
3352 result |= bytes[1] & 0x3f;
3353
3354 result <<= 6;
3355 result |= bytes[2] & 0x3f;
3356
3357 return result;
3358 } else if (bytes[0] >= 0xf0 && bytes[0] <= 0xf7) {
3359 uint32_t result = bytes[0] & 0x7;
3360
3361 result <<= 6;
3362 result |= bytes[1] & 0x3f;
3363
3364 result <<= 6;
3365 result |= bytes[2] & 0x3f;
3366
3367 result <<= 6;
3368 result |= bytes[3] & 0x3f;
3369
3370 return result;
3371 } else {
3372 zig_unreachable();
3373 }
3374}
3375
3376Error source_char_literal(const char *source, uint32_t *result, size_t *bad_index) {
3377 if (source[0] != '\\') {
3378 *result = utf8_code_point((const uint8_t *)source);
3379 return ErrorNone;
3380 }
3381
3382 uint32_t byte_offset = 1;
3383 uint32_t codepoint;
3384
3385 enum State {
3386 StateBackslash,
3387 StateUnicodeLBrace,
3388 StateUnicodeDigit,
3389 } state = StateBackslash;
3390
3391 for (;;byte_offset += 1) {
3392 switch (state) {
3393 case StateBackslash: switch (source[byte_offset]) {
3394 case 'n':
3395 *result = '\n';
3396 return ErrorNone;
3397 case 'r':
3398 *result = '\r';
3399 return ErrorNone;
3400 case '\\':
3401 *result = '\\';
3402 return ErrorNone;
3403 case 't':
3404 *result = '\t';
3405 return ErrorNone;
3406 case '\'':
3407 *result = '\'';
3408 return ErrorNone;
3409 case '"':
3410 *result = '"';
3411 return ErrorNone;
3412 case 'x': {
3413 byte_offset += 1;
3414 uint8_t digit1;
3415 if (source[byte_offset] >= '0' && source[byte_offset] <= '9') {
3416 digit1 = source[byte_offset] - '0';
3417 } else if (source[byte_offset] >= 'a' && source[byte_offset] <= 'z') {
3418 digit1 = source[byte_offset] - 'a' + 10;
3419 } else if (source[byte_offset] >= 'A' && source[byte_offset] <= 'Z') {
3420 digit1 = source[byte_offset] - 'A' + 10;
3421 } else {
3422 *bad_index = byte_offset;
3423 return ErrorInvalidCharacter;
3424 }
3425
3426 byte_offset += 1;
3427 uint8_t digit0;
3428 if (source[byte_offset] >= '0' && source[byte_offset] <= '9') {
3429 digit0 = source[byte_offset] - '0';
3430 } else if (source[byte_offset] >= 'a' && source[byte_offset] <= 'z') {
3431 digit0 = source[byte_offset] - 'a' + 10;
3432 } else if (source[byte_offset] >= 'A' && source[byte_offset] <= 'Z') {
3433 digit0 = source[byte_offset] - 'A' + 10;
3434 } else {
3435 *bad_index = byte_offset;
3436 return ErrorInvalidCharacter;
3437 }
3438
3439 *result = digit1 * 16 + digit0;
3440 return ErrorNone;
3441 }
3442 case 'u':
3443 state = StateUnicodeLBrace;
3444 continue;
3445 default:
3446 *bad_index = byte_offset;
3447 return ErrorInvalidCharacter;
3448 }
3449 case StateUnicodeLBrace: switch (source[byte_offset]) {
3450 case '{':
3451 state = StateUnicodeDigit;
3452 codepoint = 0;
3453 continue;
3454 default:
3455 *bad_index = byte_offset;
3456 return ErrorInvalidCharacter;
3457 }
3458 case StateUnicodeDigit: {
3459 uint8_t digit;
3460 if (source[byte_offset] >= '0' && source[byte_offset] <= '9') {
3461 digit = source[byte_offset] - '0';
3462 } else if (source[byte_offset] >= 'a' && source[byte_offset] <= 'z') {
3463 digit = source[byte_offset] - 'a' + 10;
3464 } else if (source[byte_offset] >= 'A' && source[byte_offset] <= 'Z') {
3465 digit = source[byte_offset] - 'A' + 10;
3466 } else if (source[byte_offset] == '}') {
3467 if (codepoint < 0x110000) {
3468 *result = codepoint;
3469 return ErrorNone;
3470 } else {
3471 *bad_index = byte_offset;
3472 return ErrorUnicodePointTooLarge;
3473 }
3474 } else {
3475 *bad_index = byte_offset;
3476 return ErrorInvalidCharacter;
3477 }
3478 codepoint = codepoint * 16 + digit;
3479 continue;
3480 }
3481 }
3482 }
3483}
3484
3485
3486Buf *token_identifier_buf(RootStruct *root_struct, TokenIndex token) {
3487 Error err;
3488 const char *source = buf_ptr(root_struct->source_code);
3489 size_t byte_offset = root_struct->token_locs[token].offset;
3490 if (root_struct->token_ids[token] == TokenIdBuiltin) {
3491 byte_offset += 1;
3492 } else {
3493 assert(root_struct->token_ids[token] == TokenIdIdentifier);
3494 }
3495 assert(source[byte_offset] != '.'); // wrong token index
3496
3497 if (source[byte_offset] == '@') {
3498 size_t bad_index;
3499 Buf *str = buf_alloc();
3500 if ((err = source_string_literal_buf(source + byte_offset + 1, str, &bad_index))) {
3501 ast_error_offset(root_struct, ErrColorAuto, token, bad_index + 1,
3502 buf_create_from_str("invalid string literal character"));
3503 }
3504 return str;
3505 } else {
3506 size_t start = byte_offset;
3507 for (;; byte_offset += 1) {
3508 if (source[byte_offset] == 0) break;
3509 if ((source[byte_offset] >= 'a' && source[byte_offset] <= 'z') ||
3510 (source[byte_offset] >= 'A' && source[byte_offset] <= 'Z') ||
3511 (source[byte_offset] >= '0' && source[byte_offset] <= '9') ||
3512 source[byte_offset] == '_')
3513 {
3514 continue;
3515 }
3516 break;
3517 }
3518 return buf_create_from_mem(source + start, byte_offset - start);
3519 }
3520}
3521
3522Buf *node_identifier_buf(AstNode *node) {
3523 assert(node->type == NodeTypeIdentifier);
3524 // Currently, stage1 runs astgen for every comptime function call,
3525 // resulting the allocation here wasting memory. As a workaround until
3526 // the code is adjusted to make astgen run only once per source node,
3527 // we memoize the result into the AST here.
3528 if (node->data.identifier.name == nullptr) {
3529 RootStruct *root_struct = node->owner->data.structure.root_struct;
3530 node->data.identifier.name = token_identifier_buf(root_struct, node->main_token);
3531 }
3532 return node->data.identifier.name;
3533}
3534
3535void token_number_literal_bigint(RootStruct *root_struct, BigInt *result, TokenIndex token) {
3536 const char *source = buf_ptr(root_struct->source_code);
3537 uint32_t byte_offset = root_struct->token_locs[token].offset;
3538
3539 bigint_init_unsigned(result, 0);
3540 BigInt radix_bi;
3541
3542 if (source[byte_offset] == '0') {
3543 byte_offset += 1;
3544 switch (source[byte_offset]) {
3545 case 'b':
3546 byte_offset += 1;
3547 bigint_init_unsigned(&radix_bi, 2);
3548 break;
3549 case 'o':
3550 byte_offset += 1;
3551 bigint_init_unsigned(&radix_bi, 8);
3552 break;
3553 case 'x':
3554 byte_offset += 1;
3555 bigint_init_unsigned(&radix_bi, 16);
3556 break;
3557 default:
3558 bigint_init_unsigned(&radix_bi, 10);
3559 break;
3560 }
3561 } else {
3562 bigint_init_unsigned(&radix_bi, 10);
3563 }
3564
3565 BigInt digit_value_bi = {};
3566 BigInt multiplied = {};
3567
3568 for (;source[byte_offset] != 0; byte_offset += 1) {
3569 uint8_t digit;
3570 if (source[byte_offset] >= '0' && source[byte_offset] <= '9') {
3571 digit = source[byte_offset] - '0';
3572 } else if (source[byte_offset] >= 'a' && source[byte_offset] <= 'z') {
3573 digit = source[byte_offset] - 'a' + 10;
3574 } else if (source[byte_offset] >= 'A' && source[byte_offset] <= 'Z') {
3575 digit = source[byte_offset] - 'A' + 10;
3576 } else if (source[byte_offset] == '_') {
3577 continue;
3578 } else {
3579 break;
3580 }
3581 bigint_deinit(&digit_value_bi);
3582 bigint_init_unsigned(&digit_value_bi, digit);
3583
3584 bigint_deinit(&multiplied);
3585 bigint_mul(&multiplied, result, &radix_bi);
3586
3587 bigint_add(result, &multiplied, &digit_value_bi);
3588 }
3589
3590 bigint_deinit(&digit_value_bi);
3591 bigint_deinit(&multiplied);
3592 bigint_deinit(&radix_bi);
3593}
3594
src/stage1/parser.hpp+10-5
......@@ -12,14 +12,19 @@
1212#include "tokenizer.hpp"
1313#include "errmsg.hpp"
1414
15ATTRIBUTE_PRINTF(2, 3)
16void ast_token_error(Token *token, const char *format, ...);
17
18
19AstNode * ast_parse(Buf *buf, ZigList<Token> *tokens, ZigType *owner, ErrColor err_color);
15AstNode * ast_parse(Buf *buf, ZigType *owner, ErrColor err_color);
2016
2117void ast_print(AstNode *node, int indent);
2218
2319void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *context), void *context);
2420
21Buf *node_identifier_buf(AstNode *node);
22
23Buf *token_identifier_buf(RootStruct *root_struct, TokenIndex token);
24
25void token_number_literal_bigint(RootStruct *root_struct, BigInt *result, TokenIndex token);
26
27Error source_string_literal_buf(const char *source, Buf *out, size_t *bad_index);
28Error source_char_literal(const char *source, uint32_t *out, size_t *bad_index);
29
2530#endif
src/stage1/stage2.h+2
......@@ -112,6 +112,8 @@ enum Error {
112112 ErrorZigIsTheCCompiler,
113113 ErrorFileBusy,
114114 ErrorLocked,
115 ErrorInvalidCharacter,
116 ErrorUnicodePointTooLarge,
115117};
116118
117119// ABI warning
src/stage1/tokenizer.cpp+867-979
......@@ -30,18 +30,28 @@
3030 case '7': \
3131 case '8': \
3232 case '9'
33
3334#define DIGIT \
3435 '0': \
3536 case DIGIT_NON_ZERO
3637
37#define ALPHA \
38#define HEXDIGIT \
3839 'a': \
3940 case 'b': \
4041 case 'c': \
4142 case 'd': \
4243 case 'e': \
4344 case 'f': \
44 case 'g': \
45 case 'A': \
46 case 'B': \
47 case 'C': \
48 case 'D': \
49 case 'E': \
50 case 'F': \
51 case DIGIT
52
53#define ALPHA_EXCEPT_HEX_P_O_X \
54 'g': \
4555 case 'h': \
4656 case 'i': \
4757 case 'j': \
......@@ -49,8 +59,6 @@
4959 case 'l': \
5060 case 'm': \
5161 case 'n': \
52 case 'o': \
53 case 'p': \
5462 case 'q': \
5563 case 'r': \
5664 case 's': \
......@@ -58,15 +66,8 @@
5866 case 'u': \
5967 case 'v': \
6068 case 'w': \
61 case 'x': \
6269 case 'y': \
6370 case 'z': \
64 case 'A': \
65 case 'B': \
66 case 'C': \
67 case 'D': \
68 case 'E': \
69 case 'F': \
7071 case 'G': \
7172 case 'H': \
7273 case 'I': \
......@@ -76,7 +77,6 @@
7677 case 'M': \
7778 case 'N': \
7879 case 'O': \
79 case 'P': \
8080 case 'Q': \
8181 case 'R': \
8282 case 'S': \
......@@ -88,7 +88,46 @@
8888 case 'Y': \
8989 case 'Z'
9090
91#define SYMBOL_CHAR \
91#define ALPHA_EXCEPT_E_B_O_X \
92 ALPHA_EXCEPT_HEX_P_O_X: \
93 case 'a': \
94 case 'c': \
95 case 'd': \
96 case 'f': \
97 case 'A': \
98 case 'B': \
99 case 'C': \
100 case 'D': \
101 case 'F': \
102 case 'p': \
103 case 'P'
104
105#define ALPHA_EXCEPT_HEX_AND_P \
106 ALPHA_EXCEPT_HEX_P_O_X: \
107 case 'o': \
108 case 'x'
109
110#define ALPHA_EXCEPT_E \
111 ALPHA_EXCEPT_HEX_AND_P: \
112 case 'a': \
113 case 'b': \
114 case 'c': \
115 case 'd': \
116 case 'f': \
117 case 'A': \
118 case 'B': \
119 case 'C': \
120 case 'D': \
121 case 'F': \
122 case 'p': \
123 case 'P'
124
125#define ALPHA \
126 ALPHA_EXCEPT_E: \
127 case 'e': \
128 case 'E'
129
130#define IDENTIFIER_CHAR \
92131 ALPHA: \
93132 case DIGIT: \
94133 case '_'
......@@ -157,101 +196,92 @@ static const struct ZigKeyword zig_keywords[] = {
157196 {"while", TokenIdKeywordWhile},
158197};
159198
160bool is_zig_keyword(Buf *buf) {
199// Returns TokenIdIdentifier if it is not a keyword.
200static TokenId zig_keyword_token(const char *name_ptr, size_t name_len) {
161201 for (size_t i = 0; i < array_length(zig_keywords); i += 1) {
162 if (buf_eql_str(buf, zig_keywords[i].text)) {
163 return true;
202 if (mem_eql_str(name_ptr, name_len, zig_keywords[i].text)) {
203 return zig_keywords[i].token_id;
164204 }
165205 }
166 return false;
167}
168
169static bool is_symbol_char(uint8_t c) {
170 switch (c) {
171 case SYMBOL_CHAR:
172 return true;
173 default:
174 return false;
175 }
206 return TokenIdIdentifier;
176207}
177208
178209enum TokenizeState {
179 TokenizeStateStart,
180 TokenizeStateSymbol,
181 TokenizeStateZero, // "0", which might lead to "0x"
182 TokenizeStateNumber, // "123", "0x123"
183 TokenizeStateNumberNoUnderscore, // "12_", "0x12_" next char must be digit
184 TokenizeStateNumberDot,
185 TokenizeStateFloatFraction, // "123.456", "0x123.456"
186 TokenizeStateFloatFractionNoUnderscore, // "123.45_", "0x123.45_"
187 TokenizeStateFloatExponentUnsigned, // "123.456e", "123e", "0x123p"
188 TokenizeStateFloatExponentNumber, // "123.456e7", "123.456e+7", "123.456e-7"
189 TokenizeStateFloatExponentNumberNoUnderscore, // "123.456e7_", "123.456e+7_", "123.456e-7_"
190 TokenizeStateString,
191 TokenizeStateStringEscape,
192 TokenizeStateStringEscapeUnicodeStart,
193 TokenizeStateCharLiteral,
194 TokenizeStateCharLiteralEnd,
195 TokenizeStateCharLiteralUnicode,
196 TokenizeStateSawStar,
197 TokenizeStateSawStarPercent,
198 TokenizeStateSawSlash,
199 TokenizeStateSawSlash2,
200 TokenizeStateSawSlash3,
201 TokenizeStateSawSlashBang,
202 TokenizeStateSawBackslash,
203 TokenizeStateSawPercent,
204 TokenizeStateSawPlus,
205 TokenizeStateSawPlusPercent,
206 TokenizeStateSawDash,
207 TokenizeStateSawMinusPercent,
208 TokenizeStateSawAmpersand,
209 TokenizeStateSawCaret,
210 TokenizeStateSawBar,
211 TokenizeStateDocComment,
212 TokenizeStateContainerDocComment,
213 TokenizeStateLineComment,
214 TokenizeStateLineString,
215 TokenizeStateLineStringEnd,
216 TokenizeStateLineStringContinue,
217 TokenizeStateSawEq,
218 TokenizeStateSawBang,
219 TokenizeStateSawLessThan,
220 TokenizeStateSawLessThanLessThan,
221 TokenizeStateSawGreaterThan,
222 TokenizeStateSawGreaterThanGreaterThan,
223 TokenizeStateSawDot,
224 TokenizeStateSawDotDot,
225 TokenizeStateSawDotStar,
226 TokenizeStateSawAtSign,
227 TokenizeStateCharCode,
228 TokenizeStateError,
210 TokenizeState_start,
211 TokenizeState_identifier,
212 TokenizeState_builtin,
213 TokenizeState_string_literal,
214 TokenizeState_string_literal_backslash,
215 TokenizeState_multiline_string_literal_line,
216 TokenizeState_char_literal,
217 TokenizeState_char_literal_backslash,
218 TokenizeState_char_literal_hex_escape,
219 TokenizeState_char_literal_unicode_escape_saw_u,
220 TokenizeState_char_literal_unicode_escape,
221 TokenizeState_char_literal_unicode,
222 TokenizeState_char_literal_end,
223 TokenizeState_backslash,
224 TokenizeState_equal,
225 TokenizeState_bang,
226 TokenizeState_pipe,
227 TokenizeState_minus,
228 TokenizeState_minus_percent,
229 TokenizeState_asterisk,
230 TokenizeState_asterisk_percent,
231 TokenizeState_slash,
232 TokenizeState_line_comment_start,
233 TokenizeState_line_comment,
234 TokenizeState_doc_comment_start,
235 TokenizeState_doc_comment,
236 TokenizeState_container_doc_comment,
237 TokenizeState_zero,
238 TokenizeState_int_literal_dec,
239 TokenizeState_int_literal_dec_no_underscore,
240 TokenizeState_int_literal_bin,
241 TokenizeState_int_literal_bin_no_underscore,
242 TokenizeState_int_literal_oct,
243 TokenizeState_int_literal_oct_no_underscore,
244 TokenizeState_int_literal_hex,
245 TokenizeState_int_literal_hex_no_underscore,
246 TokenizeState_num_dot_dec,
247 TokenizeState_num_dot_hex,
248 TokenizeState_float_fraction_dec,
249 TokenizeState_float_fraction_dec_no_underscore,
250 TokenizeState_float_fraction_hex,
251 TokenizeState_float_fraction_hex_no_underscore,
252 TokenizeState_float_exponent_unsigned,
253 TokenizeState_float_exponent_num,
254 TokenizeState_float_exponent_num_no_underscore,
255 TokenizeState_ampersand,
256 TokenizeState_caret,
257 TokenizeState_percent,
258 TokenizeState_plus,
259 TokenizeState_plus_percent,
260 TokenizeState_angle_bracket_left,
261 TokenizeState_angle_bracket_angle_bracket_left,
262 TokenizeState_angle_bracket_right,
263 TokenizeState_angle_bracket_angle_bracket_right,
264 TokenizeState_period,
265 TokenizeState_period_2,
266 TokenizeState_period_asterisk,
267 TokenizeState_saw_at_sign,
268 TokenizeState_error,
229269};
230270
231271
232272struct Tokenize {
233 Buf *buf;
273 Tokenization *out;
234274 size_t pos;
235275 TokenizeState state;
236 ZigList<Token> *tokens;
237 int line;
238 int column;
239 Token *cur_tok;
240 Tokenization *out;
241 uint32_t radix;
242 bool is_trailing_underscore;
243 size_t char_code_index;
244 bool unicode;
245 uint32_t char_code;
246 size_t remaining_code_units;
276 uint32_t line;
277 uint32_t column;
247278};
248279
249280ATTRIBUTE_PRINTF(2, 3)
250281static void tokenize_error(Tokenize *t, const char *format, ...) {
251 t->state = TokenizeStateError;
282 t->state = TokenizeState_error;
252283
253 t->out->err_line = t->line;
254 t->out->err_column = t->column;
284 t->out->err_byte_offset = t->pos;
255285
256286 va_list ap;
257287 va_start(ap, format);
......@@ -259,98 +289,18 @@ static void tokenize_error(Tokenize *t, const char *format, ...) {
259289 va_end(ap);
260290}
261291
262static void set_token_id(Tokenize *t, Token *token, TokenId id) {
263 token->id = id;
264
265 if (id == TokenIdIntLiteral) {
266 bigint_init_unsigned(&token->data.int_lit.bigint, 0);
267 } else if (id == TokenIdFloatLiteral) {
268 bigfloat_init_32(&token->data.float_lit.bigfloat, 0.0f);
269 token->data.float_lit.overflow = false;
270 } else if (id == TokenIdStringLiteral || id == TokenIdMultilineStringLiteral || id == TokenIdSymbol) {
271 memset(&token->data.str_lit.str, 0, sizeof(Buf));
272 buf_resize(&token->data.str_lit.str, 0);
273 }
274}
275
276292static void begin_token(Tokenize *t, TokenId id) {
277 assert(!t->cur_tok);
278 t->tokens->add_one();
279 Token *token = &t->tokens->last();
280 token->start_line = t->line;
281 token->start_column = t->column;
282 token->start_pos = t->pos;
283
284 set_token_id(t, token, id);
285
286 t->cur_tok = token;
293 t->out->ids.append(id);
294 TokenLoc tok_loc;
295 tok_loc.offset = (uint32_t) t->pos;
296 tok_loc.line = t->line;
297 tok_loc.column = t->column;
298 t->out->locs.append(tok_loc);
287299}
288300
289301static void cancel_token(Tokenize *t) {
290 t->tokens->pop();
291 t->cur_tok = nullptr;
292}
293
294static void end_float_token(Tokenize *t) {
295 uint8_t *ptr_buf = (uint8_t*)buf_ptr(t->buf) + t->cur_tok->start_pos;
296 size_t buf_len = t->cur_tok->end_pos - t->cur_tok->start_pos;
297 if (bigfloat_init_buf(&t->cur_tok->data.float_lit.bigfloat, ptr_buf, buf_len)) {
298 t->cur_tok->data.float_lit.overflow = true;
299 }
300}
301
302static void end_token(Tokenize *t) {
303 assert(t->cur_tok);
304 t->cur_tok->end_pos = t->pos + 1;
305
306 if (t->cur_tok->id == TokenIdFloatLiteral) {
307 end_float_token(t);
308 } else if (t->cur_tok->id == TokenIdSymbol) {
309 char *token_mem = buf_ptr(t->buf) + t->cur_tok->start_pos;
310 int token_len = (int)(t->cur_tok->end_pos - t->cur_tok->start_pos);
311
312 for (size_t i = 0; i < array_length(zig_keywords); i += 1) {
313 if (mem_eql_str(token_mem, token_len, zig_keywords[i].text)) {
314 t->cur_tok->id = zig_keywords[i].token_id;
315 break;
316 }
317 }
318 }
319
320 t->cur_tok = nullptr;
321}
322
323static bool is_exponent_signifier(uint8_t c, int radix) {
324 if (radix == 16) {
325 return c == 'p' || c == 'P';
326 } else {
327 return c == 'e' || c == 'E';
328 }
329}
330
331static uint32_t get_digit_value(uint8_t c) {
332 if ('0' <= c && c <= '9') {
333 return c - '0';
334 }
335 if ('A' <= c && c <= 'Z') {
336 return c - 'A' + 10;
337 }
338 if ('a' <= c && c <= 'z') {
339 return c - 'a' + 10;
340 }
341 return UINT32_MAX;
342}
343
344static void handle_string_escape(Tokenize *t, uint8_t c) {
345 if (t->cur_tok->id == TokenIdCharLiteral) {
346 t->cur_tok->data.char_lit.c = c;
347 t->state = TokenizeStateCharLiteralEnd;
348 } else if (t->cur_tok->id == TokenIdStringLiteral || t->cur_tok->id == TokenIdSymbol) {
349 buf_append_char(&t->cur_tok->data.str_lit.str, c);
350 t->state = TokenizeStateString;
351 } else {
352 zig_unreachable();
353 }
302 t->out->ids.pop();
303 t->out->locs.pop();
354304}
355305
356306static const char* get_escape_shorthand(uint8_t c) {
......@@ -376,7 +326,15 @@ static const char* get_escape_shorthand(uint8_t c) {
376326 }
377327}
378328
329static void invalid_eof(Tokenize *t) {
330 return tokenize_error(t, "unexpected End-Of-File");
331}
332
379333static void invalid_char_error(Tokenize *t, uint8_t c) {
334 if (c == 0) {
335 return invalid_eof(t);
336 }
337
380338 if (c == '\r') {
381339 tokenize_error(t, "invalid carriage return, only '\\n' line endings are supported");
382340 return;
......@@ -396,1139 +354,1089 @@ static void invalid_char_error(Tokenize *t, uint8_t c) {
396354 tokenize_error(t, "invalid character: '\\x%02x'", c);
397355}
398356
399void tokenize(Buf *buf, Tokenization *out) {
357void tokenize(const char *source, Tokenization *out) {
400358 Tokenize t = {0};
401359 t.out = out;
402 t.tokens = out->tokens = heap::c_allocator.create<ZigList<Token>>();
403 t.buf = buf;
404360
405 out->line_offsets = heap::c_allocator.create<ZigList<size_t>>();
406 out->line_offsets->append(0);
361 size_t remaining_code_units;
362 size_t seen_escape_digits;
407363
408 // Skip the UTF-8 BOM if present
409 if (buf_starts_with_mem(buf, "\xEF\xBB\xBF", 3)) {
364 // Skip the UTF-8 BOM if present.
365 if (source[0] == (char)0xef &&
366 source[1] == (char)0xbb &&
367 source[2] == (char)0xbf)
368 {
410369 t.pos += 3;
411370 }
412371
413 for (; t.pos < buf_len(t.buf); t.pos += 1) {
414 uint8_t c = buf_ptr(t.buf)[t.pos];
372 // Invalid token takes up index 0 so that index 0 can mean "none".
373 begin_token(&t, TokenIdCount);
374
375 for (;;) {
376 uint8_t c = source[t.pos];
415377 switch (t.state) {
416 case TokenizeStateError:
417 break;
418 case TokenizeStateStart:
378 case TokenizeState_error:
379 goto eof;
380 case TokenizeState_start:
419381 switch (c) {
382 case 0:
383 goto eof;
420384 case WHITESPACE:
421385 break;
386 case '"':
387 begin_token(&t, TokenIdStringLiteral);
388 t.state = TokenizeState_string_literal;
389 break;
390 case '\'':
391 begin_token(&t, TokenIdCharLiteral);
392 t.state = TokenizeState_char_literal;
393 break;
422394 case ALPHA:
423395 case '_':
424 t.state = TokenizeStateSymbol;
425 begin_token(&t, TokenIdSymbol);
426 buf_append_char(&t.cur_tok->data.str_lit.str, c);
396 t.state = TokenizeState_identifier;
397 begin_token(&t, TokenIdIdentifier);
427398 break;
428 case '0':
429 t.state = TokenizeStateZero;
430 begin_token(&t, TokenIdIntLiteral);
431 t.is_trailing_underscore = false;
432 t.radix = 10;
433 bigint_init_unsigned(&t.cur_tok->data.int_lit.bigint, 0);
399 case '@':
400 begin_token(&t, TokenIdBuiltin);
401 t.state = TokenizeState_saw_at_sign;
434402 break;
435 case DIGIT_NON_ZERO:
436 t.state = TokenizeStateNumber;
437 begin_token(&t, TokenIdIntLiteral);
438 t.is_trailing_underscore = false;
439 t.radix = 10;
440 bigint_init_unsigned(&t.cur_tok->data.int_lit.bigint, get_digit_value(c));
403 case '=':
404 begin_token(&t, TokenIdEq);
405 t.state = TokenizeState_equal;
441406 break;
442 case '"':
443 begin_token(&t, TokenIdStringLiteral);
444 t.state = TokenizeStateString;
407 case '!':
408 begin_token(&t, TokenIdBang);
409 t.state = TokenizeState_bang;
445410 break;
446 case '\'':
447 begin_token(&t, TokenIdCharLiteral);
448 t.state = TokenizeStateCharLiteral;
411 case '|':
412 begin_token(&t, TokenIdBinOr);
413 t.state = TokenizeState_pipe;
449414 break;
450415 case '(':
451416 begin_token(&t, TokenIdLParen);
452 end_token(&t);
453417 break;
454418 case ')':
455419 begin_token(&t, TokenIdRParen);
456 end_token(&t);
457 break;
458 case ',':
459 begin_token(&t, TokenIdComma);
460 end_token(&t);
461 break;
462 case '?':
463 begin_token(&t, TokenIdQuestion);
464 end_token(&t);
465 break;
466 case '{':
467 begin_token(&t, TokenIdLBrace);
468 end_token(&t);
469 break;
470 case '}':
471 begin_token(&t, TokenIdRBrace);
472 end_token(&t);
473420 break;
474421 case '[':
475422 begin_token(&t, TokenIdLBracket);
476 end_token(&t);
477423 break;
478424 case ']':
479425 begin_token(&t, TokenIdRBracket);
480 end_token(&t);
481426 break;
482427 case ';':
483428 begin_token(&t, TokenIdSemicolon);
484 end_token(&t);
429 break;
430 case ',':
431 begin_token(&t, TokenIdComma);
432 break;
433 case '?':
434 begin_token(&t, TokenIdQuestion);
485435 break;
486436 case ':':
487437 begin_token(&t, TokenIdColon);
488 end_token(&t);
489438 break;
490 case '#':
491 begin_token(&t, TokenIdNumberSign);
492 end_token(&t);
439 case '%':
440 begin_token(&t, TokenIdPercent);
441 t.state = TokenizeState_percent;
493442 break;
494443 case '*':
495444 begin_token(&t, TokenIdStar);
496 t.state = TokenizeStateSawStar;
445 t.state = TokenizeState_asterisk;
497446 break;
498 case '/':
499 begin_token(&t, TokenIdSlash);
500 t.state = TokenizeStateSawSlash;
447 case '+':
448 begin_token(&t, TokenIdPlus);
449 t.state = TokenizeState_plus;
450 break;
451 case '<':
452 begin_token(&t, TokenIdCmpLessThan);
453 t.state = TokenizeState_angle_bracket_left;
454 break;
455 case '>':
456 begin_token(&t, TokenIdCmpGreaterThan);
457 t.state = TokenizeState_angle_bracket_right;
458 break;
459 case '^':
460 begin_token(&t, TokenIdBinXor);
461 t.state = TokenizeState_caret;
501462 break;
502463 case '\\':
503 begin_token(&t, TokenIdMultilineStringLiteral);
504 t.state = TokenizeStateSawBackslash;
464 begin_token(&t, TokenIdMultilineStringLiteralLine);
465 t.state = TokenizeState_backslash;
505466 break;
506 case '%':
507 begin_token(&t, TokenIdPercent);
508 t.state = TokenizeStateSawPercent;
467 case '{':
468 begin_token(&t, TokenIdLBrace);
509469 break;
510 case '+':
511 begin_token(&t, TokenIdPlus);
512 t.state = TokenizeStateSawPlus;
470 case '}':
471 begin_token(&t, TokenIdRBrace);
513472 break;
514473 case '~':
515474 begin_token(&t, TokenIdTilde);
516 end_token(&t);
517475 break;
518 case '@':
519 begin_token(&t, TokenIdAtSign);
520 t.state = TokenizeStateSawAtSign;
476 case '.':
477 begin_token(&t, TokenIdDot);
478 t.state = TokenizeState_period;
521479 break;
522480 case '-':
523481 begin_token(&t, TokenIdDash);
524 t.state = TokenizeStateSawDash;
482 t.state = TokenizeState_minus;
483 break;
484 case '/':
485 begin_token(&t, TokenIdSlash);
486 t.state = TokenizeState_slash;
525487 break;
526488 case '&':
527489 begin_token(&t, TokenIdAmpersand);
528 t.state = TokenizeStateSawAmpersand;
490 t.state = TokenizeState_ampersand;
529491 break;
530 case '^':
531 begin_token(&t, TokenIdBinXor);
532 t.state = TokenizeStateSawCaret;
533 break;
534 case '|':
535 begin_token(&t, TokenIdBinOr);
536 t.state = TokenizeStateSawBar;
492 case '0':
493 t.state = TokenizeState_zero;
494 begin_token(&t, TokenIdIntLiteral);
537495 break;
538 case '=':
539 begin_token(&t, TokenIdEq);
540 t.state = TokenizeStateSawEq;
496 case DIGIT_NON_ZERO:
497 t.state = TokenizeState_int_literal_dec;
498 begin_token(&t, TokenIdIntLiteral);
541499 break;
542 case '!':
543 begin_token(&t, TokenIdBang);
544 t.state = TokenizeStateSawBang;
500 default:
501 invalid_char_error(&t, c);
502 }
503 break;
504 case TokenizeState_saw_at_sign:
505 switch (c) {
506 case 0:
507 invalid_eof(&t);
508 goto eof;
509 case '"':
510 t.out->ids.last() = TokenIdIdentifier;
511 t.state = TokenizeState_string_literal;
545512 break;
546 case '<':
547 begin_token(&t, TokenIdCmpLessThan);
548 t.state = TokenizeStateSawLessThan;
513 case IDENTIFIER_CHAR:
514 t.state = TokenizeState_builtin;
549515 break;
550 case '>':
551 begin_token(&t, TokenIdCmpGreaterThan);
552 t.state = TokenizeStateSawGreaterThan;
516 default:
517 invalid_char_error(&t, c);
518 }
519 break;
520 case TokenizeState_ampersand:
521 switch (c) {
522 case 0:
523 goto eof;
524 case '&':
525 tokenize_error(&t, "`&&` is invalid. Note that `and` is boolean AND");
553526 break;
554 case '.':
555 begin_token(&t, TokenIdDot);
556 t.state = TokenizeStateSawDot;
527 case '=':
528 t.out->ids.last() = TokenIdBitAndEq;
529 t.state = TokenizeState_start;
557530 break;
558531 default:
559 invalid_char_error(&t, c);
532 t.state = TokenizeState_start;
533 continue;
560534 }
561535 break;
562 case TokenizeStateSawDot:
536 case TokenizeState_asterisk:
563537 switch (c) {
564 case '.':
565 t.state = TokenizeStateSawDotDot;
566 set_token_id(&t, t.cur_tok, TokenIdEllipsis2);
538 case 0:
539 goto eof;
540 case '=':
541 t.out->ids.last() = TokenIdTimesEq;
542 t.state = TokenizeState_start;
567543 break;
568544 case '*':
569 t.state = TokenizeStateSawDotStar;
570 set_token_id(&t, t.cur_tok, TokenIdDotStar);
545 t.out->ids.last() = TokenIdStarStar;
546 t.state = TokenizeState_start;
547 break;
548 case '%':
549 t.state = TokenizeState_asterisk_percent;
571550 break;
572551 default:
573 t.pos -= 1;
574 end_token(&t);
575 t.state = TokenizeStateStart;
552 t.state = TokenizeState_start;
576553 continue;
577554 }
578555 break;
579 case TokenizeStateSawDotDot:
556 case TokenizeState_asterisk_percent:
580557 switch (c) {
581 case '.':
582 t.state = TokenizeStateStart;
583 set_token_id(&t, t.cur_tok, TokenIdEllipsis3);
584 end_token(&t);
558 case 0:
559 t.out->ids.last() = TokenIdTimesPercent;
560 goto eof;
561 case '=':
562 t.out->ids.last() = TokenIdTimesPercentEq;
563 t.state = TokenizeState_start;
585564 break;
586565 default:
587 t.pos -= 1;
588 end_token(&t);
589 t.state = TokenizeStateStart;
566 t.out->ids.last() = TokenIdTimesPercent;
567 t.state = TokenizeState_start;
590568 continue;
591569 }
592570 break;
593 case TokenizeStateSawDotStar:
571 case TokenizeState_percent:
594572 switch (c) {
595 case '*':
596 tokenize_error(&t, "`.*` can't be followed by `*`. Are you missing a space?");
573 case 0:
574 goto eof;
575 case '=':
576 t.out->ids.last() = TokenIdModEq;
577 t.state = TokenizeState_start;
597578 break;
598579 default:
599 t.pos -= 1;
600 end_token(&t);
601 t.state = TokenizeStateStart;
580 t.state = TokenizeState_start;
602581 continue;
603582 }
604583 break;
605 case TokenizeStateSawGreaterThan:
584 case TokenizeState_plus:
606585 switch (c) {
586 case 0:
587 goto eof;
607588 case '=':
608 set_token_id(&t, t.cur_tok, TokenIdCmpGreaterOrEq);
609 end_token(&t);
610 t.state = TokenizeStateStart;
589 t.out->ids.last() = TokenIdPlusEq;
590 t.state = TokenizeState_start;
611591 break;
612 case '>':
613 set_token_id(&t, t.cur_tok, TokenIdBitShiftRight);
614 t.state = TokenizeStateSawGreaterThanGreaterThan;
592 case '+':
593 t.out->ids.last() = TokenIdPlusPlus;
594 t.state = TokenizeState_start;
595 break;
596 case '%':
597 t.state = TokenizeState_plus_percent;
615598 break;
616599 default:
617 t.pos -= 1;
618 end_token(&t);
619 t.state = TokenizeStateStart;
600 t.state = TokenizeState_start;
620601 continue;
621602 }
622603 break;
623 case TokenizeStateSawGreaterThanGreaterThan:
604 case TokenizeState_plus_percent:
624605 switch (c) {
606 case 0:
607 t.out->ids.last() = TokenIdPlusPercent;
608 goto eof;
625609 case '=':
626 set_token_id(&t, t.cur_tok, TokenIdBitShiftRightEq);
627 end_token(&t);
628 t.state = TokenizeStateStart;
610 t.out->ids.last() = TokenIdPlusPercentEq;
611 t.state = TokenizeState_start;
629612 break;
630613 default:
631 t.pos -= 1;
632 end_token(&t);
633 t.state = TokenizeStateStart;
614 t.out->ids.last() = TokenIdPlusPercent;
615 t.state = TokenizeState_start;
634616 continue;
635617 }
636618 break;
637 case TokenizeStateSawLessThan:
619 case TokenizeState_caret:
638620 switch (c) {
621 case 0:
622 goto eof;
639623 case '=':
640 set_token_id(&t, t.cur_tok, TokenIdCmpLessOrEq);
641 end_token(&t);
642 t.state = TokenizeStateStart;
624 t.out->ids.last() = TokenIdBitXorEq;
625 t.state = TokenizeState_start;
643626 break;
644 case '<':
645 set_token_id(&t, t.cur_tok, TokenIdBitShiftLeft);
646 t.state = TokenizeStateSawLessThanLessThan;
627 default:
628 t.state = TokenizeState_start;
629 continue;
630 }
631 break;
632 case TokenizeState_identifier:
633 switch (c) {
634 case 0: {
635 uint32_t start_pos = t.out->locs.last().offset;
636 t.out->ids.last() = zig_keyword_token(
637 source + start_pos, t.pos - start_pos);
638 goto eof;
639 }
640 case IDENTIFIER_CHAR:
641 break;
642 default: {
643 uint32_t start_pos = t.out->locs.last().offset;
644 t.out->ids.last() = zig_keyword_token(
645 source + start_pos, t.pos - start_pos);
646
647 t.state = TokenizeState_start;
648 continue;
649 }
650 }
651 break;
652 case TokenizeState_builtin:
653 switch (c) {
654 case 0:
655 goto eof;
656 case IDENTIFIER_CHAR:
647657 break;
648658 default:
649 t.pos -= 1;
650 end_token(&t);
651 t.state = TokenizeStateStart;
659 t.state = TokenizeState_start;
652660 continue;
653661 }
654662 break;
655 case TokenizeStateSawLessThanLessThan:
663 case TokenizeState_backslash:
664 switch (c) {
665 case '\\':
666 t.state = TokenizeState_multiline_string_literal_line;
667 break;
668 default:
669 invalid_char_error(&t, c);
670 break;
671 }
672 break;
673 case TokenizeState_string_literal:
674 switch (c) {
675 case 0:
676 invalid_eof(&t);
677 goto eof;
678 case '\\':
679 t.state = TokenizeState_string_literal_backslash;
680 break;
681 case '"':
682 t.state = TokenizeState_start;
683 break;
684 case '\n':
685 case '\r':
686 tokenize_error(&t, "newline not allowed in string literal");
687 break;
688 default:
689 break;
690 }
691 break;
692 case TokenizeState_string_literal_backslash:
693 switch (c) {
694 case 0:
695 invalid_eof(&t);
696 goto eof;
697 case '\n':
698 case '\r':
699 tokenize_error(&t, "newline not allowed in string literal");
700 break;
701 default:
702 t.state = TokenizeState_string_literal;
703 break;
704 }
705 break;
706 case TokenizeState_char_literal:
707 if (c == 0) {
708 invalid_eof(&t);
709 goto eof;
710 } else if (c == '\\') {
711 t.state = TokenizeState_char_literal_backslash;
712 } else if (c == '\'') {
713 tokenize_error(&t, "expected character");
714 } else if ((c >= 0x80 && c <= 0xbf) || c >= 0xf8) {
715 // 10xxxxxx
716 // 11111xxx
717 invalid_char_error(&t, c);
718 } else if (c >= 0xc0 && c <= 0xdf) {
719 // 110xxxxx
720 remaining_code_units = 1;
721 t.state = TokenizeState_char_literal_unicode;
722 } else if (c >= 0xe0 && c <= 0xef) {
723 // 1110xxxx
724 remaining_code_units = 2;
725 t.state = TokenizeState_char_literal_unicode;
726 } else if (c >= 0xf0 && c <= 0xf7) {
727 // 11110xxx
728 remaining_code_units = 3;
729 t.state = TokenizeState_char_literal_unicode;
730 } else {
731 t.state = TokenizeState_char_literal_end;
732 }
733 break;
734 case TokenizeState_char_literal_backslash:
735 switch (c) {
736 case 0:
737 invalid_eof(&t);
738 goto eof;
739 case '\n':
740 case '\r':
741 tokenize_error(&t, "newline not allowed in character literal");
742 break;
743 case 'x':
744 t.state = TokenizeState_char_literal_hex_escape;
745 seen_escape_digits = 0;
746 break;
747 case 'u':
748 t.state = TokenizeState_char_literal_unicode_escape_saw_u;
749 break;
750 case 'U':
751 invalid_char_error(&t, c);
752 break;
753 default:
754 t.state = TokenizeState_char_literal_end;
755 break;
756 }
757 break;
758 case TokenizeState_char_literal_hex_escape:
759 switch (c) {
760 case ALPHA:
761 case DIGIT:
762 seen_escape_digits += 1;
763 if (seen_escape_digits == 2) {
764 t.state = TokenizeState_char_literal_end;
765 }
766 break;
767 default:
768 tokenize_error(&t, "expected hex digit");
769 break;
770 }
771 break;
772 case TokenizeState_char_literal_unicode_escape_saw_u:
773 switch (c) {
774 case '{':
775 t.state = TokenizeState_char_literal_unicode_escape;
776 seen_escape_digits = 0;
777 break;
778 default:
779 tokenize_error(&t, "expected '{' to begin unicode escape sequence");
780 break;
781 }
782 break;
783 case TokenizeState_char_literal_unicode_escape:
656784 switch (c) {
785 case ALPHA:
786 case DIGIT:
787 seen_escape_digits += 1;
788 break;
789 case '}':
790 if (seen_escape_digits == 0) {
791 tokenize_error(&t, "empty unicode escape sequence");
792 break;
793 }
794 t.state = TokenizeState_char_literal_end;
795 break;
796 default:
797 tokenize_error(&t, "expected hex digit");
798 break;
799 }
800 break;
801 case TokenizeState_char_literal_end:
802 switch (c) {
803 case '\'':
804 t.state = TokenizeState_start;
805 break;
806 default:
807 invalid_char_error(&t, c);
808 break;
809 }
810 break;
811 case TokenizeState_char_literal_unicode:
812 if (c >= 0x80 && c <= 0xbf) {
813 remaining_code_units -= 1;
814 if (remaining_code_units == 0) {
815 t.state = TokenizeState_char_literal_end;
816 }
817 } else {
818 invalid_char_error(&t, c);
819 }
820 break;
821 case TokenizeState_multiline_string_literal_line:
822 switch (c) {
823 case 0:
824 goto eof;
825 case '\n':
826 t.state = TokenizeState_start;
827 break;
828 default:
829 break;
830 }
831 break;
832 case TokenizeState_bang:
833 switch (c) {
834 case 0:
835 goto eof;
657836 case '=':
658 set_token_id(&t, t.cur_tok, TokenIdBitShiftLeftEq);
659 end_token(&t);
660 t.state = TokenizeStateStart;
837 t.out->ids.last() = TokenIdCmpNotEq;
838 t.state = TokenizeState_start;
661839 break;
662840 default:
663 t.pos -= 1;
664 end_token(&t);
665 t.state = TokenizeStateStart;
841 t.state = TokenizeState_start;
666842 continue;
667843 }
668844 break;
669 case TokenizeStateSawBang:
845 case TokenizeState_pipe:
670846 switch (c) {
847 case 0:
848 goto eof;
671849 case '=':
672 set_token_id(&t, t.cur_tok, TokenIdCmpNotEq);
673 end_token(&t);
674 t.state = TokenizeStateStart;
850 t.out->ids.last() = TokenIdBitOrEq;
851 t.state = TokenizeState_start;
852 break;
853 case '|':
854 t.out->ids.last() = TokenIdBarBar;
855 t.state = TokenizeState_start;
675856 break;
676857 default:
677 t.pos -= 1;
678 end_token(&t);
679 t.state = TokenizeStateStart;
858 t.state = TokenizeState_start;
680859 continue;
681860 }
682861 break;
683 case TokenizeStateSawEq:
862 case TokenizeState_equal:
684863 switch (c) {
864 case 0:
865 goto eof;
685866 case '=':
686 set_token_id(&t, t.cur_tok, TokenIdCmpEq);
687 end_token(&t);
688 t.state = TokenizeStateStart;
867 t.out->ids.last() = TokenIdCmpEq;
868 t.state = TokenizeState_start;
689869 break;
690870 case '>':
691 set_token_id(&t, t.cur_tok, TokenIdFatArrow);
692 end_token(&t);
693 t.state = TokenizeStateStart;
871 t.out->ids.last() = TokenIdFatArrow;
872 t.state = TokenizeState_start;
694873 break;
695874 default:
696 t.pos -= 1;
697 end_token(&t);
698 t.state = TokenizeStateStart;
875 t.state = TokenizeState_start;
699876 continue;
700877 }
701878 break;
702 case TokenizeStateSawStar:
879 case TokenizeState_minus:
703880 switch (c) {
704 case '=':
705 set_token_id(&t, t.cur_tok, TokenIdTimesEq);
706 end_token(&t);
707 t.state = TokenizeStateStart;
881 case 0:
882 goto eof;
883 case '>':
884 t.out->ids.last() = TokenIdArrow;
885 t.state = TokenizeState_start;
708886 break;
709 case '*':
710 set_token_id(&t, t.cur_tok, TokenIdStarStar);
711 end_token(&t);
712 t.state = TokenizeStateStart;
887 case '=':
888 t.out->ids.last() = TokenIdMinusEq;
889 t.state = TokenizeState_start;
713890 break;
714891 case '%':
715 set_token_id(&t, t.cur_tok, TokenIdTimesPercent);
716 t.state = TokenizeStateSawStarPercent;
892 t.state = TokenizeState_minus_percent;
717893 break;
718894 default:
719 t.pos -= 1;
720 end_token(&t);
721 t.state = TokenizeStateStart;
895 t.state = TokenizeState_start;
722896 continue;
723897 }
724898 break;
725 case TokenizeStateSawStarPercent:
899 case TokenizeState_minus_percent:
726900 switch (c) {
901 case 0:
902 t.out->ids.last() = TokenIdMinusPercent;
903 goto eof;
727904 case '=':
728 set_token_id(&t, t.cur_tok, TokenIdTimesPercentEq);
729 end_token(&t);
730 t.state = TokenizeStateStart;
905 t.out->ids.last() = TokenIdMinusPercentEq;
906 t.state = TokenizeState_start;
731907 break;
732908 default:
733 t.pos -= 1;
734 end_token(&t);
735 t.state = TokenizeStateStart;
909 t.out->ids.last() = TokenIdMinusPercent;
910 t.state = TokenizeState_start;
736911 continue;
737912 }
738913 break;
739 case TokenizeStateSawPercent:
914 case TokenizeState_angle_bracket_left:
740915 switch (c) {
916 case 0:
917 goto eof;
741918 case '=':
742 set_token_id(&t, t.cur_tok, TokenIdModEq);
743 end_token(&t);
744 t.state = TokenizeStateStart;
919 t.out->ids.last() = TokenIdCmpLessOrEq;
920 t.state = TokenizeState_start;
745921 break;
746 case '.':
747 set_token_id(&t, t.cur_tok, TokenIdPercentDot);
748 end_token(&t);
749 t.state = TokenizeStateStart;
922 case '<':
923 t.state = TokenizeState_angle_bracket_angle_bracket_left;
750924 break;
751925 default:
752 t.pos -= 1;
753 end_token(&t);
754 t.state = TokenizeStateStart;
926 t.state = TokenizeState_start;
755927 continue;
756928 }
757929 break;
758 case TokenizeStateSawPlus:
930 case TokenizeState_angle_bracket_angle_bracket_left:
759931 switch (c) {
932 case 0:
933 t.out->ids.last() = TokenIdBitShiftLeft;
934 goto eof;
760935 case '=':
761 set_token_id(&t, t.cur_tok, TokenIdPlusEq);
762 end_token(&t);
763 t.state = TokenizeStateStart;
936 t.out->ids.last() = TokenIdBitShiftLeftEq;
937 t.state = TokenizeState_start;
764938 break;
765 case '+':
766 set_token_id(&t, t.cur_tok, TokenIdPlusPlus);
767 end_token(&t);
768 t.state = TokenizeStateStart;
939 default:
940 t.out->ids.last() = TokenIdBitShiftLeft;
941 t.state = TokenizeState_start;
942 continue;
943 }
944 break;
945 case TokenizeState_angle_bracket_right:
946 switch (c) {
947 case 0:
948 goto eof;
949 case '=':
950 t.out->ids.last() = TokenIdCmpGreaterOrEq;
951 t.state = TokenizeState_start;
769952 break;
770 case '%':
771 set_token_id(&t, t.cur_tok, TokenIdPlusPercent);
772 t.state = TokenizeStateSawPlusPercent;
953 case '>':
954 t.state = TokenizeState_angle_bracket_angle_bracket_right;
773955 break;
774956 default:
775 t.pos -= 1;
776 end_token(&t);
777 t.state = TokenizeStateStart;
957 t.state = TokenizeState_start;
778958 continue;
779959 }
780960 break;
781 case TokenizeStateSawPlusPercent:
961 case TokenizeState_angle_bracket_angle_bracket_right:
782962 switch (c) {
963 case 0:
964 t.out->ids.last() = TokenIdBitShiftRight;
965 goto eof;
783966 case '=':
784 set_token_id(&t, t.cur_tok, TokenIdPlusPercentEq);
785 end_token(&t);
786 t.state = TokenizeStateStart;
967 t.out->ids.last() = TokenIdBitShiftRightEq;
968 t.state = TokenizeState_start;
787969 break;
788970 default:
789 t.pos -= 1;
790 end_token(&t);
791 t.state = TokenizeStateStart;
971 t.out->ids.last() = TokenIdBitShiftRight;
972 t.state = TokenizeState_start;
792973 continue;
793974 }
794975 break;
795 case TokenizeStateSawAmpersand:
976 case TokenizeState_period:
796977 switch (c) {
797 case '&':
798 tokenize_error(&t, "`&&` is invalid. Note that `and` is boolean AND");
978 case 0:
979 goto eof;
980 case '.':
981 t.state = TokenizeState_period_2;
799982 break;
800 case '=':
801 set_token_id(&t, t.cur_tok, TokenIdBitAndEq);
802 end_token(&t);
803 t.state = TokenizeStateStart;
983 case '*':
984 t.state = TokenizeState_period_asterisk;
804985 break;
805986 default:
806 t.pos -= 1;
807 end_token(&t);
808 t.state = TokenizeStateStart;
987 t.state = TokenizeState_start;
809988 continue;
810989 }
811990 break;
812 case TokenizeStateSawCaret:
991 case TokenizeState_period_2:
813992 switch (c) {
814 case '=':
815 set_token_id(&t, t.cur_tok, TokenIdBitXorEq);
816 end_token(&t);
817 t.state = TokenizeStateStart;
993 case 0:
994 t.out->ids.last() = TokenIdEllipsis2;
995 goto eof;
996 case '.':
997 t.out->ids.last() = TokenIdEllipsis3;
998 t.state = TokenizeState_start;
818999 break;
8191000 default:
820 t.pos -= 1;
821 end_token(&t);
822 t.state = TokenizeStateStart;
1001 t.out->ids.last() = TokenIdEllipsis2;
1002 t.state = TokenizeState_start;
8231003 continue;
8241004 }
8251005 break;
826 case TokenizeStateSawBar:
1006 case TokenizeState_period_asterisk:
8271007 switch (c) {
828 case '=':
829 set_token_id(&t, t.cur_tok, TokenIdBitOrEq);
830 end_token(&t);
831 t.state = TokenizeStateStart;
832 break;
833 case '|':
834 set_token_id(&t, t.cur_tok, TokenIdBarBar);
835 end_token(&t);
836 t.state = TokenizeStateStart;
1008 case 0:
1009 t.out->ids.last() = TokenIdDotStar;
1010 goto eof;
1011 case '*':
1012 tokenize_error(&t, "`.*` cannot be followed by `*`. Are you missing a space?");
8371013 break;
8381014 default:
839 t.pos -= 1;
840 end_token(&t);
841 t.state = TokenizeStateStart;
1015 t.out->ids.last() = TokenIdDotStar;
1016 t.state = TokenizeState_start;
8421017 continue;
8431018 }
8441019 break;
845 case TokenizeStateSawSlash:
1020 case TokenizeState_slash:
8461021 switch (c) {
1022 case 0:
1023 goto eof;
8471024 case '/':
848 t.state = TokenizeStateSawSlash2;
1025 t.state = TokenizeState_line_comment_start;
8491026 break;
8501027 case '=':
851 set_token_id(&t, t.cur_tok, TokenIdDivEq);
852 end_token(&t);
853 t.state = TokenizeStateStart;
1028 t.out->ids.last() = TokenIdDivEq;
1029 t.state = TokenizeState_start;
8541030 break;
8551031 default:
856 t.pos -= 1;
857 end_token(&t);
858 t.state = TokenizeStateStart;
1032 t.state = TokenizeState_start;
8591033 continue;
8601034 }
8611035 break;
862 case TokenizeStateSawSlash2:
1036 case TokenizeState_line_comment_start:
8631037 switch (c) {
1038 case 0:
1039 goto eof;
8641040 case '/':
865 t.state = TokenizeStateSawSlash3;
1041 t.state = TokenizeState_doc_comment_start;
8661042 break;
8671043 case '!':
868 t.state = TokenizeStateSawSlashBang;
1044 t.out->ids.last() = TokenIdContainerDocComment;
1045 t.state = TokenizeState_container_doc_comment;
8691046 break;
8701047 case '\n':
8711048 cancel_token(&t);
872 t.state = TokenizeStateStart;
1049 t.state = TokenizeState_start;
8731050 break;
8741051 default:
8751052 cancel_token(&t);
876 t.state = TokenizeStateLineComment;
1053 t.state = TokenizeState_line_comment;
8771054 break;
8781055 }
8791056 break;
880 case TokenizeStateSawSlash3:
1057 case TokenizeState_doc_comment_start:
8811058 switch (c) {
1059 case 0:
1060 t.out->ids.last() = TokenIdDocComment;
1061 goto eof;
8821062 case '/':
8831063 cancel_token(&t);
884 t.state = TokenizeStateLineComment;
1064 t.state = TokenizeState_line_comment;
8851065 break;
8861066 case '\n':
887 set_token_id(&t, t.cur_tok, TokenIdDocComment);
888 end_token(&t);
889 t.state = TokenizeStateStart;
1067 t.out->ids.last() = TokenIdDocComment;
1068 t.state = TokenizeState_start;
8901069 break;
8911070 default:
892 set_token_id(&t, t.cur_tok, TokenIdDocComment);
893 t.state = TokenizeStateDocComment;
1071 t.out->ids.last() = TokenIdDocComment;
1072 t.state = TokenizeState_doc_comment;
8941073 break;
8951074 }
8961075 break;
897 case TokenizeStateSawSlashBang:
1076 case TokenizeState_line_comment:
8981077 switch (c) {
1078 case 0:
1079 goto eof;
8991080 case '\n':
900 set_token_id(&t, t.cur_tok, TokenIdContainerDocComment);
901 end_token(&t);
902 t.state = TokenizeStateStart;
1081 t.state = TokenizeState_start;
9031082 break;
9041083 default:
905 set_token_id(&t, t.cur_tok, TokenIdContainerDocComment);
906 t.state = TokenizeStateContainerDocComment;
9071084 break;
9081085 }
9091086 break;
910 case TokenizeStateSawBackslash:
1087 case TokenizeState_doc_comment:
1088 case TokenizeState_container_doc_comment:
9111089 switch (c) {
912 case '\\':
913 t.state = TokenizeStateLineString;
1090 case 0:
1091 goto eof;
1092 case '\n':
1093 t.state = TokenizeState_start;
9141094 break;
9151095 default:
916 invalid_char_error(&t, c);
1096 // do nothing
9171097 break;
9181098 }
9191099 break;
920 case TokenizeStateLineString:
1100 case TokenizeState_zero:
9211101 switch (c) {
922 case '\n':
923 t.state = TokenizeStateLineStringEnd;
1102 case 0:
1103 goto eof;
1104 case 'b':
1105 t.state = TokenizeState_int_literal_bin_no_underscore;
9241106 break;
925 default:
926 buf_append_char(&t.cur_tok->data.str_lit.str, c);
1107 case 'o':
1108 t.state = TokenizeState_int_literal_oct_no_underscore;
9271109 break;
928 }
929 break;
930 case TokenizeStateLineStringEnd:
931 switch (c) {
932 case WHITESPACE:
1110 case 'x':
1111 t.state = TokenizeState_int_literal_hex_no_underscore;
9331112 break;
934 case '\\':
935 t.state = TokenizeStateLineStringContinue;
1113 case DIGIT:
1114 case '_':
1115 case '.':
1116 case 'e':
1117 case 'E':
1118 // Reinterpret as a decimal number.
1119 t.state = TokenizeState_int_literal_dec;
1120 continue;
1121 case ALPHA_EXCEPT_E_B_O_X:
1122 invalid_char_error(&t, c);
9361123 break;
9371124 default:
938 t.pos -= 1;
939 end_token(&t);
940 t.state = TokenizeStateStart;
1125 t.state = TokenizeState_start;
9411126 continue;
9421127 }
9431128 break;
944 case TokenizeStateLineStringContinue:
1129 case TokenizeState_int_literal_bin_no_underscore:
9451130 switch (c) {
946 case '\\':
947 t.state = TokenizeStateLineString;
948 buf_append_char(&t.cur_tok->data.str_lit.str, '\n');
1131 case '0':
1132 case '1':
1133 t.state = TokenizeState_int_literal_bin;
9491134 break;
9501135 default:
9511136 invalid_char_error(&t, c);
952 break;
9531137 }
9541138 break;
955 case TokenizeStateLineComment:
1139 case TokenizeState_int_literal_bin:
9561140 switch (c) {
957 case '\n':
958 t.state = TokenizeStateStart;
1141 case 0:
1142 goto eof;
1143 case '_':
1144 t.state = TokenizeState_int_literal_bin_no_underscore;
9591145 break;
960 default:
961 // do nothing
1146 case '0':
1147 case '1':
1148 break;
1149 case '2':
1150 case '3':
1151 case '4':
1152 case '5':
1153 case '6':
1154 case '7':
1155 case '8':
1156 case '9':
1157 case ALPHA:
1158 invalid_char_error(&t, c);
9621159 break;
1160 default:
1161 t.state = TokenizeState_start;
1162 continue;
9631163 }
9641164 break;
965 case TokenizeStateDocComment:
1165 case TokenizeState_int_literal_oct_no_underscore:
9661166 switch (c) {
967 case '\n':
968 end_token(&t);
969 t.state = TokenizeStateStart;
1167 case '0':
1168 case '1':
1169 case '2':
1170 case '3':
1171 case '4':
1172 case '5':
1173 case '6':
1174 case '7':
1175 t.state = TokenizeState_int_literal_oct;
9701176 break;
9711177 default:
972 // do nothing
1178 invalid_char_error(&t, c);
9731179 break;
9741180 }
9751181 break;
976 case TokenizeStateContainerDocComment:
1182 case TokenizeState_int_literal_oct:
9771183 switch (c) {
978 case '\n':
979 end_token(&t);
980 t.state = TokenizeStateStart;
1184 case 0:
1185 goto eof;
1186 case '_':
1187 t.state = TokenizeState_int_literal_oct_no_underscore;
9811188 break;
982 default:
983 // do nothing
1189 case '0':
1190 case '1':
1191 case '2':
1192 case '3':
1193 case '4':
1194 case '5':
1195 case '6':
1196 case '7':
9841197 break;
985 }
986 break;
987 case TokenizeStateSawAtSign:
988 switch (c) {
989 case '"':
990 set_token_id(&t, t.cur_tok, TokenIdSymbol);
991 t.state = TokenizeStateString;
1198 case ALPHA:
1199 case '8':
1200 case '9':
1201 invalid_char_error(&t, c);
9921202 break;
9931203 default:
994 t.pos -= 1;
995 end_token(&t);
996 t.state = TokenizeStateStart;
1204 t.state = TokenizeState_start;
9971205 continue;
9981206 }
9991207 break;
1000 case TokenizeStateSymbol:
1208 case TokenizeState_int_literal_dec_no_underscore:
10011209 switch (c) {
1002 case SYMBOL_CHAR:
1003 buf_append_char(&t.cur_tok->data.str_lit.str, c);
1210 case DIGIT:
1211 t.state = TokenizeState_int_literal_dec;
10041212 break;
10051213 default:
1006 t.pos -= 1;
1007 end_token(&t);
1008 t.state = TokenizeStateStart;
1009 continue;
1214 invalid_char_error(&t, c);
1215 break;
10101216 }
10111217 break;
1012 case TokenizeStateString:
1218 case TokenizeState_int_literal_dec:
10131219 switch (c) {
1014 case '"':
1015 end_token(&t);
1016 t.state = TokenizeStateStart;
1220 case 0:
1221 goto eof;
1222 case '_':
1223 t.state = TokenizeState_int_literal_dec_no_underscore;
10171224 break;
1018 case '\n':
1019 tokenize_error(&t, "newline not allowed in string literal");
1225 case '.':
1226 t.state = TokenizeState_num_dot_dec;
1227 t.out->ids.last() = TokenIdFloatLiteral;
10201228 break;
1021 case '\\':
1022 t.state = TokenizeStateStringEscape;
1229 case 'e':
1230 case 'E':
1231 t.state = TokenizeState_float_exponent_unsigned;
1232 t.out->ids.last() = TokenIdFloatLiteral;
10231233 break;
1024 default:
1025 buf_append_char(&t.cur_tok->data.str_lit.str, c);
1234 case DIGIT:
1235 break;
1236 case ALPHA_EXCEPT_E:
1237 invalid_char_error(&t, c);
10261238 break;
1239 default:
1240 t.state = TokenizeState_start;
1241 continue;
10271242 }
10281243 break;
1029 case TokenizeStateStringEscape:
1244 case TokenizeState_int_literal_hex_no_underscore:
10301245 switch (c) {
1031 case 'x':
1032 t.state = TokenizeStateCharCode;
1033 t.radix = 16;
1034 t.char_code = 0;
1035 t.char_code_index = 0;
1036 t.unicode = false;
1037 break;
1038 case 'u':
1039 t.state = TokenizeStateStringEscapeUnicodeStart;
1040 break;
1041 case 'n':
1042 handle_string_escape(&t, '\n');
1246 case HEXDIGIT:
1247 t.state = TokenizeState_int_literal_hex;
10431248 break;
1044 case 'r':
1045 handle_string_escape(&t, '\r');
1249 default:
1250 invalid_char_error(&t, c);
1251 }
1252 break;
1253 case TokenizeState_int_literal_hex:
1254 switch (c) {
1255 case 0:
1256 goto eof;
1257 case '_':
1258 t.state = TokenizeState_int_literal_hex_no_underscore;
10461259 break;
1047 case '\\':
1048 handle_string_escape(&t, '\\');
1260 case '.':
1261 t.state = TokenizeState_num_dot_hex;
1262 t.out->ids.last() = TokenIdFloatLiteral;
10491263 break;
1050 case 't':
1051 handle_string_escape(&t, '\t');
1264 case 'p':
1265 case 'P':
1266 t.state = TokenizeState_float_exponent_unsigned;
1267 t.out->ids.last() = TokenIdFloatLiteral;
10521268 break;
1053 case '\'':
1054 handle_string_escape(&t, '\'');
1269 case HEXDIGIT:
10551270 break;
1056 case '"':
1057 handle_string_escape(&t, '\"');
1271 case ALPHA_EXCEPT_HEX_AND_P:
1272 invalid_char_error(&t, c);
10581273 break;
10591274 default:
1060 invalid_char_error(&t, c);
1275 t.state = TokenizeState_start;
1276 continue;
10611277 }
10621278 break;
1063 case TokenizeStateStringEscapeUnicodeStart:
1279 case TokenizeState_num_dot_dec:
10641280 switch (c) {
1065 case '{':
1066 t.state = TokenizeStateCharCode;
1067 t.radix = 16;
1068 t.char_code = 0;
1069 t.char_code_index = 0;
1070 t.unicode = true;
1281 case 0:
1282 goto eof;
1283 case '.':
1284 t.out->ids.last() = TokenIdIntLiteral;
1285 t.pos -= 1;
1286 t.column -= 1;
1287 t.state = TokenizeState_start;
1288 continue;
1289 case 'e':
1290 case 'E':
1291 t.state = TokenizeState_float_exponent_unsigned;
1292 break;
1293 case DIGIT:
1294 t.state = TokenizeState_float_fraction_dec;
10711295 break;
10721296 default:
10731297 invalid_char_error(&t, c);
1298 break;
10741299 }
10751300 break;
1076 case TokenizeStateCharCode:
1077 {
1078 if (t.unicode && c == '}') {
1079 if (t.char_code_index == 0) {
1080 tokenize_error(&t, "empty unicode escape sequence");
1081 break;
1082 }
1083 if (t.char_code > 0x10ffff) {
1084 tokenize_error(&t, "unicode value out of range: %x", t.char_code);
1085 break;
1086 }
1087 if (t.cur_tok->id == TokenIdCharLiteral) {
1088 t.cur_tok->data.char_lit.c = t.char_code;
1089 t.state = TokenizeStateCharLiteralEnd;
1090 } else if (t.char_code <= 0x7f) {
1091 // 00000000 00000000 00000000 0xxxxxxx
1092 handle_string_escape(&t, (uint8_t)t.char_code);
1093 } else if (t.char_code <= 0x7ff) {
1094 // 00000000 00000000 00000xxx xx000000
1095 handle_string_escape(&t, (uint8_t)(0xc0 | (t.char_code >> 6)));
1096 // 00000000 00000000 00000000 00xxxxxx
1097 handle_string_escape(&t, (uint8_t)(0x80 | (t.char_code & 0x3f)));
1098 } else if (t.char_code <= 0xffff) {
1099 // 00000000 00000000 xxxx0000 00000000
1100 handle_string_escape(&t, (uint8_t)(0xe0 | (t.char_code >> 12)));
1101 // 00000000 00000000 0000xxxx xx000000
1102 handle_string_escape(&t, (uint8_t)(0x80 | ((t.char_code >> 6) & 0x3f)));
1103 // 00000000 00000000 00000000 00xxxxxx
1104 handle_string_escape(&t, (uint8_t)(0x80 | (t.char_code & 0x3f)));
1105 } else if (t.char_code <= 0x10ffff) {
1106 // 00000000 000xxx00 00000000 00000000
1107 handle_string_escape(&t, (uint8_t)(0xf0 | (t.char_code >> 18)));
1108 // 00000000 000000xx xxxx0000 00000000
1109 handle_string_escape(&t, (uint8_t)(0x80 | ((t.char_code >> 12) & 0x3f)));
1110 // 00000000 00000000 0000xxxx xx000000
1111 handle_string_escape(&t, (uint8_t)(0x80 | ((t.char_code >> 6) & 0x3f)));
1112 // 00000000 00000000 00000000 00xxxxxx
1113 handle_string_escape(&t, (uint8_t)(0x80 | (t.char_code & 0x3f)));
1114 } else {
1115 zig_unreachable();
1116 }
1301 case TokenizeState_num_dot_hex:
1302 switch (c) {
1303 case 0:
1304 goto eof;
1305 case '.':
1306 t.out->ids.last() = TokenIdIntLiteral;
1307 t.pos -= 1;
1308 t.column -= 1;
1309 t.state = TokenizeState_start;
1310 continue;
1311 case 'p':
1312 case 'P':
1313 t.state = TokenizeState_float_exponent_unsigned;
11171314 break;
1118 }
1119
1120 uint32_t digit_value = get_digit_value(c);
1121 if (digit_value >= t.radix) {
1122 tokenize_error(&t, "invalid digit: '%c'", c);
1315 case HEXDIGIT:
1316 t.out->ids.last() = TokenIdFloatLiteral;
1317 t.state = TokenizeState_float_fraction_hex;
1318 break;
1319 default:
1320 invalid_char_error(&t, c);
11231321 break;
1124 }
1125 t.char_code *= t.radix;
1126 t.char_code += digit_value;
1127 t.char_code_index += 1;
1128
1129 if (!t.unicode && t.char_code_index >= 2) {
1130 assert(t.char_code <= 255);
1131 handle_string_escape(&t, (uint8_t)t.char_code);
1132 }
1133 }
1134 break;
1135 case TokenizeStateCharLiteral:
1136 if (c == '\'') {
1137 tokenize_error(&t, "expected character");
1138 } else if (c == '\\') {
1139 t.state = TokenizeStateStringEscape;
1140 } else if ((c >= 0x80 && c <= 0xbf) || c >= 0xf8) {
1141 // 10xxxxxx
1142 // 11111xxx
1143 invalid_char_error(&t, c);
1144 } else if (c >= 0xc0 && c <= 0xdf) {
1145 // 110xxxxx
1146 t.cur_tok->data.char_lit.c = c & 0x1f;
1147 t.remaining_code_units = 1;
1148 t.state = TokenizeStateCharLiteralUnicode;
1149 } else if (c >= 0xe0 && c <= 0xef) {
1150 // 1110xxxx
1151 t.cur_tok->data.char_lit.c = c & 0x0f;
1152 t.remaining_code_units = 2;
1153 t.state = TokenizeStateCharLiteralUnicode;
1154 } else if (c >= 0xf0 && c <= 0xf7) {
1155 // 11110xxx
1156 t.cur_tok->data.char_lit.c = c & 0x07;
1157 t.remaining_code_units = 3;
1158 t.state = TokenizeStateCharLiteralUnicode;
1159 } else {
1160 t.cur_tok->data.char_lit.c = c;
1161 t.state = TokenizeStateCharLiteralEnd;
11621322 }
11631323 break;
1164 case TokenizeStateCharLiteralEnd:
1324 case TokenizeState_float_fraction_dec_no_underscore:
11651325 switch (c) {
1166 case '\'':
1167 end_token(&t);
1168 t.state = TokenizeStateStart;
1326 case DIGIT:
1327 t.state = TokenizeState_float_fraction_dec;
11691328 break;
11701329 default:
11711330 invalid_char_error(&t, c);
11721331 }
11731332 break;
1174 case TokenizeStateCharLiteralUnicode:
1175 if (c <= 0x7f || c >= 0xc0) {
1176 invalid_char_error(&t, c);
1177 }
1178 t.cur_tok->data.char_lit.c <<= 6;
1179 t.cur_tok->data.char_lit.c += c & 0x3f;
1180 t.remaining_code_units--;
1181 if (t.remaining_code_units == 0) {
1182 t.state = TokenizeStateCharLiteralEnd;
1183 }
1184 break;
1185 case TokenizeStateZero:
1333 case TokenizeState_float_fraction_dec:
11861334 switch (c) {
1187 case 'b':
1188 t.radix = 2;
1189 t.state = TokenizeStateNumberNoUnderscore;
1335 case 0:
1336 goto eof;
1337 case '_':
1338 t.state = TokenizeState_float_fraction_dec_no_underscore;
11901339 break;
1191 case 'o':
1192 t.radix = 8;
1193 t.state = TokenizeStateNumberNoUnderscore;
1340 case 'e':
1341 case 'E':
1342 t.state = TokenizeState_float_exponent_unsigned;
11941343 break;
1195 case 'x':
1196 t.radix = 16;
1197 t.state = TokenizeStateNumberNoUnderscore;
1344 case DIGIT:
1345 break;
1346 case ALPHA_EXCEPT_E:
1347 invalid_char_error(&t, c);
11981348 break;
11991349 default:
1200 // reinterpret as normal number
1201 t.pos -= 1;
1202 t.state = TokenizeStateNumber;
1350 t.state = TokenizeState_start;
12031351 continue;
12041352 }
12051353 break;
1206 case TokenizeStateNumberNoUnderscore:
1207 if (c == '_') {
1208 invalid_char_error(&t, c);
1209 break;
1210 } else if (get_digit_value(c) < t.radix) {
1211 t.is_trailing_underscore = false;
1212 t.state = TokenizeStateNumber;
1354 case TokenizeState_float_fraction_hex_no_underscore:
1355 switch (c) {
1356 case HEXDIGIT:
1357 t.state = TokenizeState_float_fraction_hex;
1358 break;
1359 default:
1360 invalid_char_error(&t, c);
12131361 }
1214 ZIG_FALLTHROUGH;
1215 case TokenizeStateNumber:
1216 {
1217 if (c == '_') {
1218 t.is_trailing_underscore = true;
1219 t.state = TokenizeStateNumberNoUnderscore;
1362 break;
1363 case TokenizeState_float_fraction_hex:
1364 switch (c) {
1365 case 0:
1366 goto eof;
1367 case '_':
1368 t.state = TokenizeState_float_fraction_hex_no_underscore;
12201369 break;
1221 }
1222 if (c == '.') {
1223 if (t.is_trailing_underscore) {
1224 invalid_char_error(&t, c);
1225 break;
1226 }
1227 t.state = TokenizeStateNumberDot;
1370 case 'p':
1371 case 'P':
1372 t.state = TokenizeState_float_exponent_unsigned;
12281373 break;
1229 }
1230 if (is_exponent_signifier(c, t.radix)) {
1231 if (t.is_trailing_underscore) {
1232 invalid_char_error(&t, c);
1233 break;
1234 }
1235 if (t.radix != 16 && t.radix != 10) {
1236 invalid_char_error(&t, c);
1237 }
1238 t.state = TokenizeStateFloatExponentUnsigned;
1239 t.radix = 10; // exponent is always base 10
1240 assert(t.cur_tok->id == TokenIdIntLiteral);
1241 set_token_id(&t, t.cur_tok, TokenIdFloatLiteral);
1374 case HEXDIGIT:
12421375 break;
1243 }
1244 uint32_t digit_value = get_digit_value(c);
1245 if (digit_value >= t.radix) {
1246 if (t.is_trailing_underscore) {
1247 invalid_char_error(&t, c);
1248 break;
1249 }
1250
1251 if (is_symbol_char(c)) {
1252 invalid_char_error(&t, c);
1253 }
1254 // not my char
1255 t.pos -= 1;
1256 end_token(&t);
1257 t.state = TokenizeStateStart;
1258 continue;
1259 }
1260 BigInt digit_value_bi;
1261 bigint_init_unsigned(&digit_value_bi, digit_value);
1262
1263 BigInt radix_bi;
1264 bigint_init_unsigned(&radix_bi, t.radix);
1265
1266 BigInt multiplied;
1267 bigint_mul(&multiplied, &t.cur_tok->data.int_lit.bigint, &radix_bi);
1268
1269 bigint_add(&t.cur_tok->data.int_lit.bigint, &multiplied, &digit_value_bi);
1270 break;
1271 }
1272 case TokenizeStateNumberDot:
1273 {
1274 if (c == '.') {
1275 t.pos -= 2;
1276 end_token(&t);
1277 t.state = TokenizeStateStart;
1278 continue;
1279 }
1280 if (t.radix != 16 && t.radix != 10) {
1376 case ALPHA_EXCEPT_HEX_AND_P:
12811377 invalid_char_error(&t, c);
1282 }
1283 t.pos -= 1;
1284 t.state = TokenizeStateFloatFractionNoUnderscore;
1285 assert(t.cur_tok->id == TokenIdIntLiteral);
1286 set_token_id(&t, t.cur_tok, TokenIdFloatLiteral);
1287 continue;
1288 }
1289 case TokenizeStateFloatFractionNoUnderscore:
1290 if (c == '_') {
1291 invalid_char_error(&t, c);
1292 } else if (get_digit_value(c) < t.radix) {
1293 t.is_trailing_underscore = false;
1294 t.state = TokenizeStateFloatFraction;
1295 }
1296 ZIG_FALLTHROUGH;
1297 case TokenizeStateFloatFraction:
1298 {
1299 if (c == '_') {
1300 t.is_trailing_underscore = true;
1301 t.state = TokenizeStateFloatFractionNoUnderscore;
1302 break;
1303 }
1304 if (is_exponent_signifier(c, t.radix)) {
1305 if (t.is_trailing_underscore) {
1306 invalid_char_error(&t, c);
1307 break;
1308 }
1309 t.state = TokenizeStateFloatExponentUnsigned;
1310 t.radix = 10; // exponent is always base 10
13111378 break;
1312 }
1313 uint32_t digit_value = get_digit_value(c);
1314 if (digit_value >= t.radix) {
1315 if (t.is_trailing_underscore) {
1316 invalid_char_error(&t, c);
1317 break;
1318 }
1319 if (is_symbol_char(c)) {
1320 invalid_char_error(&t, c);
1321 }
1322 // not my char
1323 t.pos -= 1;
1324 end_token(&t);
1325 t.state = TokenizeStateStart;
1379 default:
1380 t.state = TokenizeState_start;
13261381 continue;
1327 }
1328
1329 // we use parse_f128 to generate the float literal, so just
1330 // need to get to the end of the token
13311382 }
13321383 break;
1333 case TokenizeStateFloatExponentUnsigned:
1384 case TokenizeState_float_exponent_unsigned:
13341385 switch (c) {
13351386 case '+':
1336 t.state = TokenizeStateFloatExponentNumberNoUnderscore;
1337 break;
13381387 case '-':
1339 t.state = TokenizeStateFloatExponentNumberNoUnderscore;
1388 t.state = TokenizeState_float_exponent_num_no_underscore;
13401389 break;
13411390 default:
1342 // reinterpret as normal exponent number
1343 t.pos -= 1;
1344 t.state = TokenizeStateFloatExponentNumberNoUnderscore;
1345 continue;
1346 }
1347 break;
1348 case TokenizeStateFloatExponentNumberNoUnderscore:
1349 if (c == '_') {
1350 invalid_char_error(&t, c);
1351 } else if (get_digit_value(c) < t.radix) {
1352 t.is_trailing_underscore = false;
1353 t.state = TokenizeStateFloatExponentNumber;
1354 }
1355 ZIG_FALLTHROUGH;
1356 case TokenizeStateFloatExponentNumber:
1357 {
1358 if (c == '_') {
1359 t.is_trailing_underscore = true;
1360 t.state = TokenizeStateFloatExponentNumberNoUnderscore;
1361 break;
1362 }
1363 uint32_t digit_value = get_digit_value(c);
1364 if (digit_value >= t.radix) {
1365 if (t.is_trailing_underscore) {
1366 invalid_char_error(&t, c);
1367 break;
1368 }
1369 if (is_symbol_char(c)) {
1370 invalid_char_error(&t, c);
1371 }
1372 // not my char
1373 t.pos -= 1;
1374 end_token(&t);
1375 t.state = TokenizeStateStart;
1391 // Reinterpret as a normal exponent number.
1392 t.state = TokenizeState_float_exponent_num_no_underscore;
13761393 continue;
1377 }
1378
1379 // we use parse_f128 to generate the float literal, so just
1380 // need to get to the end of the token
13811394 }
13821395 break;
1383 case TokenizeStateSawDash:
1396 case TokenizeState_float_exponent_num_no_underscore:
13841397 switch (c) {
1385 case '>':
1386 set_token_id(&t, t.cur_tok, TokenIdArrow);
1387 end_token(&t);
1388 t.state = TokenizeStateStart;
1389 break;
1390 case '=':
1391 set_token_id(&t, t.cur_tok, TokenIdMinusEq);
1392 end_token(&t);
1393 t.state = TokenizeStateStart;
1394 break;
1395 case '%':
1396 set_token_id(&t, t.cur_tok, TokenIdMinusPercent);
1397 t.state = TokenizeStateSawMinusPercent;
1398 case DIGIT:
1399 t.state = TokenizeState_float_exponent_num;
13981400 break;
13991401 default:
1400 t.pos -= 1;
1401 end_token(&t);
1402 t.state = TokenizeStateStart;
1403 continue;
1402 invalid_char_error(&t, c);
14041403 }
14051404 break;
1406 case TokenizeStateSawMinusPercent:
1405 case TokenizeState_float_exponent_num:
14071406 switch (c) {
1408 case '=':
1409 set_token_id(&t, t.cur_tok, TokenIdMinusPercentEq);
1410 end_token(&t);
1411 t.state = TokenizeStateStart;
1407 case 0:
1408 goto eof;
1409 case '_':
1410 t.state = TokenizeState_float_exponent_num_no_underscore;
1411 break;
1412 case DIGIT:
1413 break;
1414 case ALPHA:
1415 invalid_char_error(&t, c);
14121416 break;
14131417 default:
1414 t.pos -= 1;
1415 end_token(&t);
1416 t.state = TokenizeStateStart;
1418 t.state = TokenizeState_start;
14171419 continue;
14181420 }
14191421 break;
14201422 }
1423 t.pos += 1;
14211424 if (c == '\n') {
1422 out->line_offsets->append(t.pos + 1);
14231425 t.line += 1;
14241426 t.column = 0;
14251427 } else {
14261428 t.column += 1;
14271429 }
14281430 }
1429 // EOF
1430 switch (t.state) {
1431 case TokenizeStateStart:
1432 case TokenizeStateError:
1433 break;
1434 case TokenizeStateNumberNoUnderscore:
1435 case TokenizeStateFloatFractionNoUnderscore:
1436 case TokenizeStateFloatExponentNumberNoUnderscore:
1437 case TokenizeStateNumberDot:
1438 tokenize_error(&t, "unterminated number literal");
1439 break;
1440 case TokenizeStateString:
1441 tokenize_error(&t, "unterminated string");
1442 break;
1443 case TokenizeStateStringEscape:
1444 case TokenizeStateStringEscapeUnicodeStart:
1445 case TokenizeStateCharCode:
1446 if (t.cur_tok->id == TokenIdStringLiteral) {
1447 tokenize_error(&t, "unterminated string");
1448 break;
1449 } else if (t.cur_tok->id == TokenIdCharLiteral) {
1450 tokenize_error(&t, "unterminated Unicode code point literal");
1451 break;
1452 } else {
1453 zig_unreachable();
1454 }
1455 break;
1456 case TokenizeStateCharLiteral:
1457 case TokenizeStateCharLiteralEnd:
1458 case TokenizeStateCharLiteralUnicode:
1459 tokenize_error(&t, "unterminated Unicode code point literal");
1460 break;
1461 case TokenizeStateSymbol:
1462 case TokenizeStateZero:
1463 case TokenizeStateNumber:
1464 case TokenizeStateFloatFraction:
1465 case TokenizeStateFloatExponentUnsigned:
1466 case TokenizeStateFloatExponentNumber:
1467 case TokenizeStateSawStar:
1468 case TokenizeStateSawSlash:
1469 case TokenizeStateSawPercent:
1470 case TokenizeStateSawPlus:
1471 case TokenizeStateSawDash:
1472 case TokenizeStateSawAmpersand:
1473 case TokenizeStateSawCaret:
1474 case TokenizeStateSawBar:
1475 case TokenizeStateSawEq:
1476 case TokenizeStateSawBang:
1477 case TokenizeStateSawLessThan:
1478 case TokenizeStateSawLessThanLessThan:
1479 case TokenizeStateSawGreaterThan:
1480 case TokenizeStateSawGreaterThanGreaterThan:
1481 case TokenizeStateSawDot:
1482 case TokenizeStateSawDotStar:
1483 case TokenizeStateSawAtSign:
1484 case TokenizeStateSawStarPercent:
1485 case TokenizeStateSawPlusPercent:
1486 case TokenizeStateSawMinusPercent:
1487 case TokenizeStateLineString:
1488 case TokenizeStateLineStringEnd:
1489 case TokenizeStateDocComment:
1490 case TokenizeStateContainerDocComment:
1491 end_token(&t);
1492 break;
1493 case TokenizeStateSawDotDot:
1494 case TokenizeStateSawBackslash:
1495 case TokenizeStateLineStringContinue:
1496 tokenize_error(&t, "unexpected EOF");
1497 break;
1498 case TokenizeStateLineComment:
1499 break;
1500 case TokenizeStateSawSlash2:
1501 cancel_token(&t);
1502 break;
1503 case TokenizeStateSawSlash3:
1504 set_token_id(&t, t.cur_tok, TokenIdDocComment);
1505 end_token(&t);
1506 break;
1507 case TokenizeStateSawSlashBang:
1508 set_token_id(&t, t.cur_tok, TokenIdContainerDocComment);
1509 end_token(&t);
1510 break;
1511 }
1512 if (t.state != TokenizeStateError) {
1513 if (t.tokens->length > 0) {
1514 Token *last_token = &t.tokens->last();
1515 t.line = (int)last_token->start_line;
1516 t.column = (int)last_token->start_column;
1517 t.pos = last_token->start_pos;
1518 } else {
1519 t.pos = 0;
1520 }
1521 begin_token(&t, TokenIdEof);
1522 end_token(&t);
1523 assert(!t.cur_tok);
1524 }
1431eof:;
1432
1433 begin_token(&t, TokenIdEof);
15251434}
15261435
15271436const char * token_name(TokenId id) {
15281437 switch (id) {
15291438 case TokenIdAmpersand: return "&";
15301439 case TokenIdArrow: return "->";
1531 case TokenIdAtSign: return "@";
15321440 case TokenIdBang: return "!";
15331441 case TokenIdBarBar: return "||";
15341442 case TokenIdBinOr: return "|";
......@@ -1622,9 +1530,7 @@ const char * token_name(TokenId id) {
16221530 case TokenIdMinusPercent: return "-%";
16231531 case TokenIdMinusPercentEq: return "-%=";
16241532 case TokenIdModEq: return "%=";
1625 case TokenIdNumberSign: return "#";
16261533 case TokenIdPercent: return "%";
1627 case TokenIdPercentDot: return "%.";
16281534 case TokenIdPlus: return "+";
16291535 case TokenIdPlusEq: return "+=";
16301536 case TokenIdPlusPercent: return "+%";
......@@ -1638,33 +1544,15 @@ const char * token_name(TokenId id) {
16381544 case TokenIdStar: return "*";
16391545 case TokenIdStarStar: return "**";
16401546 case TokenIdStringLiteral: return "StringLiteral";
1641 case TokenIdMultilineStringLiteral: return "MultilineStringLiteral";
1642 case TokenIdSymbol: return "Symbol";
1547 case TokenIdMultilineStringLiteralLine: return "MultilineStringLiteralLine";
1548 case TokenIdIdentifier: return "Identifier";
16431549 case TokenIdTilde: return "~";
16441550 case TokenIdTimesEq: return "*=";
16451551 case TokenIdTimesPercent: return "*%";
16461552 case TokenIdTimesPercentEq: return "*%=";
1553 case TokenIdBuiltin: return "Builtin";
16471554 case TokenIdCount:
16481555 zig_unreachable();
16491556 }
16501557 return "(invalid token)";
16511558}
1652
1653void print_tokens(Buf *buf, ZigList<Token> *tokens) {
1654 for (size_t i = 0; i < tokens->length; i += 1) {
1655 Token *token = &tokens->at(i);
1656 fprintf(stderr, "%s ", token_name(token->id));
1657 if (token->start_pos != SIZE_MAX) {
1658 fwrite(buf_ptr(buf) + token->start_pos, 1, token->end_pos - token->start_pos, stderr);
1659 }
1660 fprintf(stderr, "\n");
1661 }
1662}
1663
1664bool valid_symbol_starter(uint8_t c) {
1665 switch (c) {
1666 case SYMBOL_START:
1667 return true;
1668 }
1669 return false;
1670}
src/stage1/tokenizer.hpp+14-56
......@@ -12,10 +12,9 @@
1212#include "bigint.hpp"
1313#include "bigfloat.hpp"
1414
15enum TokenId {
15enum TokenId : uint8_t {
1616 TokenIdAmpersand,
1717 TokenIdArrow,
18 TokenIdAtSign,
1918 TokenIdBang,
2019 TokenIdBarBar,
2120 TokenIdBinOr,
......@@ -27,6 +26,7 @@ enum TokenId {
2726 TokenIdBitShiftRight,
2827 TokenIdBitShiftRightEq,
2928 TokenIdBitXorEq,
29 TokenIdBuiltin,
3030 TokenIdCharLiteral,
3131 TokenIdCmpEq,
3232 TokenIdCmpGreaterOrEq,
......@@ -109,9 +109,7 @@ enum TokenId {
109109 TokenIdMinusPercent,
110110 TokenIdMinusPercentEq,
111111 TokenIdModEq,
112 TokenIdNumberSign,
113112 TokenIdPercent,
114 TokenIdPercentDot,
115113 TokenIdPlus,
116114 TokenIdPlusEq,
117115 TokenIdPlusPercent,
......@@ -125,75 +123,35 @@ enum TokenId {
125123 TokenIdStar,
126124 TokenIdStarStar,
127125 TokenIdStringLiteral,
128 TokenIdMultilineStringLiteral,
129 TokenIdSymbol,
126 TokenIdMultilineStringLiteralLine,
127 TokenIdIdentifier,
130128 TokenIdTilde,
131129 TokenIdTimesEq,
132130 TokenIdTimesPercent,
133131 TokenIdTimesPercentEq,
134 TokenIdCount,
135};
136
137struct TokenFloatLit {
138 BigFloat bigfloat;
139 // overflow is true if when parsing the number, we discovered it would not fit
140 // without losing data
141 bool overflow;
142};
143
144struct TokenIntLit {
145 BigInt bigint;
146};
147
148struct TokenStrLit {
149 Buf str;
150};
151132
152struct TokenCharLit {
153 uint32_t c;
133 TokenIdCount,
154134};
155135
156struct Token {
157 TokenId id;
158 size_t start_pos;
159 size_t end_pos;
160 size_t start_line;
161 size_t start_column;
162
163 union {
164 // TokenIdIntLiteral
165 TokenIntLit int_lit;
166
167 // TokenIdFloatLiteral
168 TokenFloatLit float_lit;
136typedef uint32_t TokenIndex;
169137
170 // TokenIdStringLiteral, TokenIdMultilineStringLiteral or TokenIdSymbol
171 TokenStrLit str_lit;
172
173 // TokenIdCharLiteral
174 TokenCharLit char_lit;
175 } data;
138struct TokenLoc {
139 uint32_t offset;
140 uint32_t line;
141 uint32_t column;
176142};
177// work around conflicting name Token which is also found in libclang
178typedef Token ZigToken;
179143
180144struct Tokenization {
181 ZigList<Token> *tokens;
182 ZigList<size_t> *line_offsets;
145 ZigList<TokenId> ids;
146 ZigList<TokenLoc> locs;
183147
184148 // if an error occurred
185149 Buf *err;
186 size_t err_line;
187 size_t err_column;
150 uint32_t err_byte_offset;
188151};
189152
190void tokenize(Buf *buf, Tokenization *out_tokenization);
191
192void print_tokens(Buf *buf, ZigList<Token> *tokens);
153void tokenize(const char *source, Tokenization *out_tokenization);
193154
194155const char * token_name(TokenId id);
195156
196bool valid_symbol_starter(uint8_t c);
197bool is_zig_keyword(Buf *buf);
198
199157#endif
test/behavior/misc.zig+8-7
......@@ -1,6 +1,7 @@
11const std = @import("std");
22const expect = std.testing.expect;
33const expectEqualSlices = std.testing.expectEqualSlices;
4const expectEqualStrings = std.testing.expectEqualStrings;
45const mem = std.mem;
56const builtin = @import("builtin");
67
......@@ -147,13 +148,13 @@ test "array mult operator" {
147148}
148149
149150test "string escapes" {
150 try expect(mem.eql(u8, "\"", "\x22"));
151 try expect(mem.eql(u8, "\'", "\x27"));
152 try expect(mem.eql(u8, "\n", "\x0a"));
153 try expect(mem.eql(u8, "\r", "\x0d"));
154 try expect(mem.eql(u8, "\t", "\x09"));
155 try expect(mem.eql(u8, "\\", "\x5c"));
156 try expect(mem.eql(u8, "\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01"));
151 try expectEqualStrings("\"", "\x22");
152 try expectEqualStrings("\'", "\x27");
153 try expectEqualStrings("\n", "\x0a");
154 try expectEqualStrings("\r", "\x0d");
155 try expectEqualStrings("\t", "\x09");
156 try expectEqualStrings("\\", "\x5c");
157 try expectEqualStrings("\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01");
157158}
158159
159160test "multiline string" {
test/compile_errors.zig+4-4
......@@ -34,9 +34,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3434 \\ const c: *S = &.{};
3535 \\}
3636 , &[_][]const u8{
37 "mp.zig:2:31: error: expected type '[][]const u8', found '*const struct:2:31'",
38 "mp.zig:5:33: error: expected type '*[2][]const u8', found '*const struct:5:33'",
39 "mp.zig:9:21: error: expected type '*S', found '*const struct:9:21'",
37 "tmp.zig:2:31: error: expected type '[][]const u8', found '*const struct:2:31'",
38 "tmp.zig:5:33: error: expected type '*[2][]const u8', found '*const struct:5:33'",
39 "tmp.zig:9:21: error: expected type '*S', found '*const struct:9:21'",
4040 });
4141
4242 cases.add("@Type() union payload is undefined",
......@@ -8416,6 +8416,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
84168416 \\ var sequence = "repeat".*** 10;
84178417 \\}
84188418 , &[_][]const u8{
8419 "tmp.zig:2:30: error: `.*` can't be followed by `*`. Are you missing a space?",
8419 "tmp.zig:2:30: error: `.*` cannot be followed by `*`. Are you missing a space?",
84208420 });
84218421}